Commit 230b6132 for tesseract

commit 230b6132926e5b774de1d2ba5f66013076f14a79
Author: Stefan Weil <sw@weilnetz.de>
Date:   Sun Jul 12 21:09:52 2026 +0200

    Fix zero-size entry UB and add hard limit on DAWG edge count

    - tessdatamanager.cpp: skip DeSerialize when entry_size is 0 after
      resize(0), avoiding undefined behavior from &entries_[i][0] on an
      empty vector.
    - dawg.cpp: add hard upper bound (50M) on num_edges_ to prevent
      resource-exhaustion DoS from a crafted .traineddata with a huge
      dictionary component, even when the remaining-bytes check passes.

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

diff --git a/src/ccutil/tessdatamanager.cpp b/src/ccutil/tessdatamanager.cpp
index 67e86dc0..debdf035 100644
--- a/src/ccutil/tessdatamanager.cpp
+++ b/src/ccutil/tessdatamanager.cpp
@@ -150,7 +150,7 @@ bool TessdataManager::LoadMemBuffer(const char *name, const char *data, int size
         return false;
       }
       entries_[i].resize(entry_size);
-      if (!fp.DeSerialize(&entries_[i][0], entry_size)) {
+      if (entry_size > 0 && !fp.DeSerialize(&entries_[i][0], entry_size)) {
         return false;
       }
     }
diff --git a/src/dict/dawg.cpp b/src/dict/dawg.cpp
index 55699d47..f386dd9d 100644
--- a/src/dict/dawg.cpp
+++ b/src/dict/dawg.cpp
@@ -369,6 +369,11 @@ bool SquishedDawg::read_squished_dawg(TFile *file) {
     tprintf("Empty dawg: num_edges is 0\n");
     return false;
   }
+  // Hard upper bound to prevent resource-exhaustion DoS.
+  if (num_edges_ > 50000000) {
+    tprintf("Dawg num_edges %u exceeds hard limit\n", num_edges_);
+    return false;
+  }
   // Reject if the declared edge count exceeds the remaining component bytes.
   if (num_edges_ > file->RemainingBytes() / sizeof(EDGE_RECORD)) {
     tprintf("Dawg num_edges %u exceeds remaining data\n", num_edges_);