Commit db9866a4 for tesseract

commit db9866a4bb16e88cb9354861862dabee841af628
Author: Stefan Weil <sw@weilnetz.de>
Date:   Sun Jul 12 20:36:43 2026 +0200

    Fix three issues in DAWG/fontinfo deserialization

    - read_spacing_info: add sanity limit (1M) on vec_size before calling
      init_spacing, preventing OOM from a crafted large value.
    - print_node: restore advancement past the last forward edge so the
      subsequent backward-edge check starts at the correct position.
    - read_squished_dawg: validate unicharset_size fits in int before
      passing to Dawg::init, preventing undefined behavior in bitmask
      computations when the value exceeds INT_MAX.

    Assisted-by: OpenCode / big-pickle (opencode)
    Reported-by: GitHub Copilot
    Signed-off-by: Stefan Weil <stweil@tessus.org>

diff --git a/src/ccstruct/fontinfo.cpp b/src/ccstruct/fontinfo.cpp
index 9984469f..8448f6f1 100644
--- a/src/ccstruct/fontinfo.cpp
+++ b/src/ccstruct/fontinfo.cpp
@@ -173,6 +173,10 @@ bool read_spacing_info(TFile *f, FontInfo *fi) {
   if (vec_size == 0) {
     return true;
   }
+  // Reject unreasonably large spacing vectors.
+  if (vec_size > 1000000) {
+    return false;
+  }
   fi->init_spacing(vec_size);
   for (uint32_t i = 0; i < vec_size; ++i) {
     auto *fs = new FontSpacingInfo();
diff --git a/src/dict/dawg.cpp b/src/dict/dawg.cpp
index d72899c0..55699d47 100644
--- a/src/dict/dawg.cpp
+++ b/src/dict/dawg.cpp
@@ -26,6 +26,7 @@
 #include "helpers.h"
 #include "tprintf.h"

+#include <climits>
 #include <memory>

 /*----------------------------------------------------------------------
@@ -292,6 +293,7 @@ void SquishedDawg::print_node(NODE_REF node, int max_num_edges) const {
         return;
       }
       if (last_edge(edge)) {
+        ++edge; // Advance past the last forward edge.
         break;
       }
       ++edge;
@@ -355,6 +357,11 @@ bool SquishedDawg::read_squished_dawg(TFile *file) {
   if (!file->DeSerialize(&unicharset_size)) {
     return false;
   }
+  // Dawg::init takes int; reject values that would overflow.
+  if (unicharset_size == 0 || unicharset_size > INT_MAX) {
+    tprintf("Bad dawg unicharset_size %u\n", unicharset_size);
+    return false;
+  }
   if (!file->DeSerialize(&num_edges_)) {
     return false;
   }