Commit adc444e0 for tesseract

commit adc444e0edd1fcce11a3ff30b82be250599d4639
Author: Stefan Weil <sw@weilnetz.de>
Date:   Fri Nov 13 17:31:00 2026 +0100

    training: fix crashes in AddSpacingInfo for a missing or bad xheight

    MasterTrainer::AddSpacingInfo() divides by xheights_[fontinfo_id], but
    xheights_ only gets its size from LoadXHeights(), which is only called
    if the option -X was given, and LoadXHeights() accepted any integer.
    Without -X the code read from an empty vector (SIGSEGV), and with an
    x-height of 0 it divided by zero (SIGFPE).

    Ignore the spacing file with a message if the font has no valid
    x-height, like it is done for a file which matches no font. Also skip
    x-heights which are not positive in LoadXHeights(), so such a font
    gets the mean of the valid entries.

    Fix proposed by the Anthropic OSS Scanner (finding ANT-2026-TUPX5CXU).

    Assisted-by: OpenCode / Claude Fable 5.2 (Anthropic)
    Signed-off-by: Stefan Weil <sw@weilnetz.de>

diff --git a/src/training/common/mastertrainer.cpp b/src/training/common/mastertrainer.cpp
index a411a697..f8dddd91 100644
--- a/src/training/common/mastertrainer.cpp
+++ b/src/training/common/mastertrainer.cpp
@@ -440,6 +440,11 @@ bool MasterTrainer::LoadXHeights(const char *filename) {
       // fontinfo not in table.
       continue;
     }
+    if (xht <= 0) {
+      tprintf("Ignoring invalid xheight %d for font %s in %s\n", xht, buffer,
+              filename);
+      continue;
+    }
     xheights_[fontinfo_id] = xht;
     total_xheight += xht;
     ++xheight_count;
@@ -472,6 +477,15 @@ bool MasterTrainer::AddSpacingInfo(const char *filename) {
     fclose(fontinfo_file);
     return false;
   }
+  // The spacing is scaled by the xheight of the font, which is only known if
+  // an xheights file was loaded (see LoadXHeights) and has an entry for it.
+  if (static_cast<size_t>(fontinfo_id) >= xheights_.size() ||
+      xheights_[fontinfo_id] <= 0) {
+    tprintf("No xheight for font %d, ignoring spacing file %s\n", fontinfo_id,
+            filename);
+    fclose(fontinfo_file);
+    return false;
+  }
   tprintf("Reading spacing from %s for font %d...\n", filename, fontinfo_id);
   // TODO(rays) scale should probably be a double, but keep as an int for now
   // to duplicate current behavior.