gbranden pushed a commit to branch master
in repository groff.

commit f3a331e907f7824a7edff025bed21fb2110a2860
Author: G. Branden Robinson <[email protected]>
AuthorDate: Mon Jul 15 12:10:47 2024 -0500

    [troff]: Fix Savannah #64301 (12/15).
    
    * src/roff/troff/number.cpp (get_hunits): Use `ckd_add()` (with
      temporary variable, annotating why) instead of primitive operation,
      and throw error diagnostic if arithmetic wraps.
---
 ChangeLog                 |  6 +++---
 src/roff/troff/number.cpp | 11 +++++++++--
 2 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index f8df5c55a..c9c928986 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -9,9 +9,9 @@
        `ckd_sub()`, and `ckd_mul()` instead of primitive operations,
        and throw error diagnostic if arithmetic wraps.
        (is_valid_expression): Remove manual detection of overflow.
-       (get_vunits): Use `ckd_add()` (with temporary variable,
-       annotating why) instead of primitive operation, and throw error
-       diagnostic if arithmetic wraps.
+       (get_vunits, get_hunits): Use `ckd_add()` (with temporary
+       variable, annotating why) instead of primitive operation, and
+       throw error diagnostic if arithmetic wraps.
 
        * 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 c1de807a8..6e512e643 100644
--- a/src/roff/troff/number.cpp
+++ b/src/roff/troff/number.cpp
@@ -146,6 +146,9 @@ bool get_vunits(vunits *res, unsigned char si, vunits 
prev_value)
 bool get_hunits(hunits *res, unsigned char si, hunits prev_value)
 {
   units h;
+  // Use a primitive temporary because having the ckd macros store to
+  // &(res->n) requires `friend` access and produces wrong results.
+  int i;
   switch (get_incr_number(&h, si)) {
   case INVALID:
     return false;
@@ -153,10 +156,14 @@ bool get_hunits(hunits *res, unsigned char si, hunits 
prev_value)
     *res = h;
     break;
   case INCREMENT:
-    *res = prev_value + h;
+    if (ckd_add(&i, prev_value.to_units(), h))
+      error("integer addition wrapped");
+    *res = i;
     break;
   case DECREMENT:
-    *res = prev_value - h;
+    if (ckd_sub(&i, prev_value.to_units(), h))
+      error("integer subtraction wrapped");
+    *res = i;
     break;
   default:
     assert(0 == "unhandled case returned by get_incr_number()");

_______________________________________________
Groff-commit mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/groff-commit

Reply via email to