gbranden pushed a commit to branch master
in repository groff.

commit 95b6901bb47ae10d41592b125e90816fe3412ad1
Author: G. Branden Robinson <[email protected]>
AuthorDate: Wed Jun 24 19:12:58 2026 -0500

    [troff]: Add overflow check to `dictionary` type.
    
    * src/roff/troff/dictionary.cpp: Preprocessor-include "errarg.h" and
      "error.h" to make visible `fatal()` function.
    
      (dictionary::lookup): Add overflow check of dictionary capacity.
      GCC's static analyzer was suspicious that it could overflow.
      `capacity` is a `ssize_t`, but C++'s allocator (behind `new`) uses
      `size_t`.  If `capacity` wraps (overflows), emit fatal error.
---
 ChangeLog                     | 10 ++++++++++
 src/roff/troff/dictionary.cpp |  7 +++++++
 2 files changed, 17 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index 229ab8564..e3d80c9c5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2026-06-24  G. Branden Robinson <[email protected]>
+
+       * src/roff/troff/dictionary.cpp: Preprocessor-include "errarg.h"
+       and "error.h" to make visible `fatal()` function.
+       (dictionary::lookup): Add overflow check of dictionary capacity.
+       GCC's static analyzer was suspicious that it could overflow.
+       `capacity` is a `ssize_t`, but C++'s allocator (behind `new`)
+       uses `size_t`.  If `capacity` wraps (overflows), emit fatal
+       error.
+
 2026-06-24  G. Branden Robinson <[email protected]>
 
        [libgroff,troff]: Reallocate fatal error exit responsibilities,
diff --git a/src/roff/troff/dictionary.cpp b/src/roff/troff/dictionary.cpp
index 8cdcc62b2..9418583a2 100644
--- a/src/roff/troff/dictionary.cpp
+++ b/src/roff/troff/dictionary.cpp
@@ -30,6 +30,8 @@ along with this program.  If not, see 
<http://www.gnu.org/licenses/>. */
 // libgroff
 #include "symbol.h" // prerequisite of dictionary.h
 #include "dictionary.h"
+#include "errarg.h" // prerequisite of error.h
+#include "error.h" // prerequisite of error.h
 
 // is 'p' a good size for a hash table
 
@@ -81,6 +83,11 @@ void *dictionary::lookup(symbol s, void *v)
     capacity = ssize_t(capacity * factor);
     while (!is_good_size(capacity))
       ++capacity;
+    if (capacity < 0)
+      // If `capacity` wrapped, the old size must have fit in a signed
+      // integer.
+      fatal("cannot grow dictionary beyond %1 entries",
+           static_cast<int>(old_capacity));
     association *old_table = table;
     table = new association[capacity];
     occupancy = 0;

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

Reply via email to