Commit 1d37ffa9 for tesseract

commit 1d37ffa9651fc517b17bc2373f7d07e638b01c3f
Author: Stefan Weil <sw@weilnetz.de>
Date:   Fri Nov 13 17:30:07 2026 +0100

    textord: clamp textord_spline_medianwin in split_stepped_spline

    split_stepped_spline() derives leftindex and rightindex from multiples
    of textord_spline_medianwin and reads xcoords[leftindex - 1] and
    xcoords[rightindex - 1]. The indices only stay inside
    startindex..endindex if the window is at least 4. A smaller value
    caused a read out of bounds, and a huge value overflowed the
    multiplication by 3.

    Use a local copy of the parameter which is clipped to [4, INT16_MAX].
    The default value (6) is not affected.

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

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

diff --git a/src/textord/oldbasel.cpp b/src/textord/oldbasel.cpp
index f9612a60..d21bc28f 100644
--- a/src/textord/oldbasel.cpp
+++ b/src/textord/oldbasel.cpp
@@ -26,6 +26,7 @@
 #include "ccstruct.h"
 #include "detlinefit.h"
 #include "drawtord.h"
+#include "helpers.h" // for ClipToRange
 #include "makerow.h"
 #include "quadlsq.h"
 #include "statistc.h"
@@ -1146,6 +1147,10 @@ bool split_stepped_spline( // make xstarts
   float leftcoord, rightcoord;
   int leftindex, rightindex;
   float step; // spline step
+  // The index arithmetic below keeps leftindex - 1 and rightindex - 1 inside
+  // startindex..endindex only if the window is at least 4, and the window
+  // has to be small enough to be multiplied by 3.
+  const int medianwin = ClipToRange<int>(textord_spline_medianwin, 4, INT16_MAX);

   doneany = false;
   startindex = 0;
@@ -1171,11 +1176,11 @@ bool split_stepped_spline( // make xstarts
         if (textord_debug_baselines) {
           tprintf("Too many segments to resegment spline!!\n");
         }
-      } else if (endindex - startindex >= textord_spline_medianwin * 3) {
-        while (centreindex - startindex < textord_spline_medianwin * 3 / 2) {
+      } else if (endindex - startindex >= medianwin * 3) {
+        while (centreindex - startindex < medianwin * 3 / 2) {
           centreindex++;
         }
-        while (endindex - centreindex < textord_spline_medianwin * 3 / 2) {
+        while (endindex - centreindex < medianwin * 3 / 2) {
           centreindex--;
         }
         leftindex = (startindex + startindex + centreindex) / 3;
@@ -1183,22 +1188,22 @@ bool split_stepped_spline( // make xstarts
         leftcoord = (xcoords[startindex] * 2 + xcoords[centreindex]) / 3.0;
         rightcoord = (xcoords[centreindex] + xcoords[endindex] * 2) / 3.0;
         while (xcoords[leftindex] > leftcoord &&
-               leftindex - startindex > textord_spline_medianwin) {
+               leftindex - startindex > medianwin) {
           leftindex--;
         }
         while (xcoords[leftindex] < leftcoord &&
-               centreindex - leftindex > textord_spline_medianwin / 2) {
+               centreindex - leftindex > medianwin / 2) {
           leftindex++;
         }
         if (xcoords[leftindex] - leftcoord > leftcoord - xcoords[leftindex - 1]) {
           leftindex--;
         }
         while (xcoords[rightindex] > rightcoord &&
-               rightindex - centreindex > textord_spline_medianwin / 2) {
+               rightindex - centreindex > medianwin / 2) {
           rightindex--;
         }
         while (xcoords[rightindex] < rightcoord &&
-               endindex - rightindex > textord_spline_medianwin) {
+               endindex - rightindex > medianwin) {
           rightindex++;
         }
         if (xcoords[rightindex] - rightcoord > rightcoord - xcoords[rightindex - 1]) {
@@ -1216,7 +1221,7 @@ bool split_stepped_spline( // make xstarts
         doneany = true;
       } else if (textord_debug_baselines) {
         tprintf("Resegmenting spline failed - insufficient pts (%d,%d,%d,%d)\n", startindex,
-                centreindex, endindex, static_cast<int32_t>(textord_spline_medianwin));
+                centreindex, endindex, medianwin);
       }
     }
     //              else tprintf("Spline step at %d is %g\n",