gbranden pushed a commit to branch master
in repository groff.
commit b4f9d7010d10703df99770db0e4d91fa57422d38
Author: G. Branden Robinson <[email protected]>
AuthorDate: Mon Jul 15 18:02:24 2024 -0500
[troff]: Fix Savannah #64301 (13/15).
* src/roff/troff/number.cpp (is_valid_term): When parsing integer
literals, remove manual detection of overflow, relying on `ckd_mul()`
and `ckd_add()` to indicate it. When an overflowing literal is
encountered, skip excess digits. This is a behavior change, albeit an
esoteric one; evaluation of a numeric term no longer aborts in this
scenario.
---
ChangeLog | 6 ++++++
src/roff/troff/number.cpp | 27 ++++++++++++---------------
2 files changed, 18 insertions(+), 15 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index c9c928986..9df66c2f6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -12,6 +12,12 @@
(get_vunits, get_hunits): Use `ckd_add()` (with temporary
variable, annotating why) instead of primitive operation, and
throw error diagnostic if arithmetic wraps.
+ (is_valid_term): When parsing integer literals, remove manual
+ detection of overflow, relying on `ckd_mul()` and `ckd_add()` to
+ indicate it. When an overflowing literal is encountered, skip
+ excess digits. This is a behavior change, albeit an esoteric
+ one; evaluation of a numeric term no longer aborts in this
+ scenario.
* src/roff/troff/hvunits.h: Include `config.h` and `stdckdint.h`
headers.
diff --git a/src/roff/troff/number.cpp b/src/roff/troff/number.cpp
index 6e512e643..b00ad1df6 100644
--- a/src/roff/troff/number.cpp
+++ b/src/roff/troff/number.cpp
@@ -392,6 +392,7 @@ static bool is_valid_term(units *u, int scaling_unit,
bool is_parenthesized, bool is_mandatory)
{
bool is_negative = false;
+ bool is_overflowing = false;
for (;;)
if (is_parenthesized && tok.is_space())
tok.next();
@@ -498,19 +499,18 @@ static bool is_valid_term(units *u, int scaling_unit,
case '9':
*u = 0;
do {
- if (*u > INT_MAX / 10) {
- error("numeric overflow");
- return false;
- }
- *u *= 10;
- if (*u > INT_MAX - (int(c) - '0')) {
- error("numeric overflow");
- return false;
- }
- *u += c - '0';
+ // If wrapping, don't `break`; eat and discard further digits.
+ if (!is_overflowing) {
+ if (ckd_mul(u, *u, 10))
+ is_overflowing = true;
+ if (ckd_add(u, *u, c - '0'))
+ is_overflowing = true;
+ }
tok.next();
c = tok.ch();
} while (csdigit(c));
+ if (is_overflowing)
+ error("integer value wrapped");
break;
case '/':
case '*':
@@ -637,11 +637,8 @@ static bool is_valid_term(units *u, int scaling_unit,
if (do_next)
tok.next();
if (is_negative) {
- if (*u == INT_MIN) {
- error("numeric overflow");
- return false;
- }
- *u = -*u;
+ if (ckd_mul(u, *u, -1))
+ error("integer multiplication wrapped");
}
return true;
}
_______________________________________________
Groff-commit mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/groff-commit