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

Reply via email to