Commit 9e719c15 for tesseract
commit 9e719c155f8b89372fc5443602acba6d9e67555e
Author: Stefan Weil <sw@weilnetz.de>
Date: Fri Nov 13 17:31:00 2026 +0100
ccmain: fix read out of bounds in PrerecAllWordsPar for an empty word
PrerecAllWordsPar() (tessedit_parallelize) assumes that each ratings
matrix has a cell (0, 0). In LSTM-only mode a word without blobs is
not replaced by a fake word, so its ratings matrix has dimension 0,
and get(0, 0) read behind the empty array.
Skip such a word. It has no blobs which could be classified.
Fix proposed by the Anthropic OSS Scanner (finding ANT-2026-XHAFVBQP).
Assisted-by: OpenCode / Claude Fable 5.2 (Anthropic)
Signed-off-by: Stefan Weil <sw@weilnetz.de>
diff --git a/src/ccmain/par_control.cpp b/src/ccmain/par_control.cpp
index 731bd19a..17203949 100644
--- a/src/ccmain/par_control.cpp
+++ b/src/ccmain/par_control.cpp
@@ -54,7 +54,10 @@ void Tesseract::PrerecAllWordsPar(const std::vector<WordData> &words) {
// Prepare all the blobs.
std::vector<BlobData> blobs;
for (const auto &w : words) {
- if (w.word->ratings != nullptr && w.word->ratings->get(0, 0) == nullptr) {
+ // In LSTM mode a word with no blobs is not faked, so its ratings matrix
+ // can be empty; there is nothing to pre-classify in that case.
+ if (w.word->ratings != nullptr && w.word->ratings->dimension() > 0 &&
+ w.word->ratings->get(0, 0) == nullptr) {
for (size_t s = 0; s < w.lang_words.size(); ++s) {
Tesseract *sub = s < sub_langs_.size() ? sub_langs_[s] : this;
const WERD_RES &word = *w.lang_words[s];