gbranden pushed a commit to branch master
in repository groff.
commit 41ce02672a795aa52d408e1e64c0c093934fdf3e
Author: G. Branden Robinson <[email protected]>
AuthorDate: Wed Aug 14 11:01:54 2024 -0500
[troff]: Fix Savannah #64229.
Throw diagnostic in event of a diversion's contents overflowing its
vertical position. We can't do anything sensible in this case, so make
it a fatal error. (It's also more likely that your host environment
will exhaust memory available to the `troff` process before encountering
this problem.)
* src/roff/troff/div.cpp: New constant symbol `DIVERSION_LENGTH_MAX`
defines the maximum permissible vertical size of a diversion in basic
units. Presently, it is `INT_MAX`.
(macro_diversion::distance_to_next_trap): When there is no diversion
trap, or it has already been passed, report the distance to
`DIVERSION_LENGTH_MAX` (rather than `INT_MAX`) divided by the vertical
resolution.
(macro_diversion::output): Check for overflow when incrementing
vertical position upon writing out a line, and emit fatal error
diagnostic if it occurs.
Fixes <https://savannah.gnu.org/bugs/?64229>. Thanks to Dave Kemper for
the discussion.
---
ChangeLog | 23 +++++++++++++++++++++++
src/roff/troff/div.cpp | 15 ++++++++++++++-
2 files changed, 37 insertions(+), 1 deletion(-)
diff --git a/ChangeLog b/ChangeLog
index 4dba2196c..aae3db6d0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,26 @@
+2024-08-14 G. Branden Robinson <[email protected]>
+
+ [troff]: Throw diagnostic in event of a diversion's contents
+ overflowing its vertical position. We can't do anything
+ sensible in this case, so make it a fatal error. (It's also
+ more likely that your host environment will exhaust memory
+ available to the `troff` process before encountering this
+ problem.)
+
+ * src/roff/troff/div.cpp: New constant symbol
+ `DIVERSION_LENGTH_MAX` defines the maximum permissible vertical
+ size of a diversion in basic units. Presently, it is `INT_MAX`.
+ (macro_diversion::distance_to_next_trap): When there is no
+ diversion trap, or it has already been passed, report the
+ distance to `DIVERSION_LENGTH_MAX` (rather than `INT_MAX`)
+ divided by the vertical resolution.
+ (macro_diversion::output): Check for overflow when incrementing
+ vertical position upon writing out a line, and emit fatal error
+ diagnostic if it occurs.
+
+ Fixes <https://savannah.gnu.org/bugs/?64229>. Thanks to Dave
+ Kemper for the discussion.
+
2024-08-13 G. Branden Robinson <[email protected]>
* tmac/e.tmac (n1, n2): Invoke the renamed `po` request
diff --git a/src/roff/troff/div.cpp b/src/roff/troff/div.cpp
index 772540c09..f79aabb6e 100644
--- a/src/roff/troff/div.cpp
+++ b/src/roff/troff/div.cpp
@@ -241,6 +241,8 @@ macro_diversion::~macro_diversion()
dn_reg_contents = vertical_position.to_units();
}
+static int DIVERSION_LENGTH_MAX = INT_MAX;
+
vunits macro_diversion::distance_to_next_trap()
{
vunits distance = 0;
@@ -250,7 +252,7 @@ vunits macro_diversion::distance_to_next_trap()
else
// Do the (saturating) arithmetic ourselves to avoid an error
// diagnostic from constructor in number.cpp.
- distance = units(INT_MAX / vresolution);
+ distance = units(DIVERSION_LENGTH_MAX / vresolution);
assert(distance >= 0);
return distance;
}
@@ -300,6 +302,17 @@ void macro_diversion::output(node *nd, int retain_size,
if (width > max_width)
max_width = width;
vunits x = v.pre + v.pre_extra + v.post + v.post_extra;
+ int new_vpos = 0;
+ int vpos = vertical_position.to_units();
+ int lineht = x.to_units();
+ bool overflow = false;
+ if (ckd_add(&new_vpos, vpos, lineht))
+ overflow = true;
+ else if (new_vpos > DIVERSION_LENGTH_MAX)
+ overflow = true;
+ if (overflow)
+ fatal("diversion overflow (vertical position: %1u,"
+ " next line height: %2u)", vpos, lineht);
if (vertical_position_traps_flag
&& !diversion_trap.is_null() && diversion_trap_pos > vertical_position
&& diversion_trap_pos <= vertical_position + x) {
_______________________________________________
Groff-commit mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/groff-commit