Commit 5fd28e33 for tesseract
commit 5fd28e33a131a5572b4ec3ef0bfaf8fb34810c4b
Author: Stefan Weil <sw@weilnetz.de>
Date: Fri Nov 13 17:31:00 2026 +0100
fontinfo: check the font ids before they are used as an index
FontInfoTable::SetContainsFontProperties() and
SetContainsMultipleFontProperties() used the font ids of the classifier
results as indices into the table without a check. In classifier_tester
the table is made from the font_properties file of the user, while the
ids come from the shape table of the model, so they need not match,
and the code read out of bounds.
Ignore ids which are not in the table, like
Tesseract::set_word_fonts() does.
Fix proposed by the Anthropic OSS Scanner (finding ANT-2026-7OLQOJK3).
Assisted-by: OpenCode / Claude Fable 5.2 (Anthropic)
Signed-off-by: Stefan Weil <sw@weilnetz.de>
diff --git a/src/ccstruct/fontinfo.cpp b/src/ccstruct/fontinfo.cpp
index 444578ba..c5688643 100644
--- a/src/ccstruct/fontinfo.cpp
+++ b/src/ccstruct/fontinfo.cpp
@@ -62,13 +62,23 @@ bool FontInfoTable::DeSerialize(TFile *fp) {
return this->DeSerializeClasses(fp);
}
+// Returns true if font_id is a valid index into table. The ids in a set of
+// ScoredFont come from the classifier's traineddata, which need not have been
+// trained with the same fonts as table, so they cannot be trusted blindly.
+static bool IsValidFontId(const FontInfoTable &table, int font_id) {
+ return 0 <= font_id && font_id < static_cast<int>(table.size());
+}
+
// Returns true if the given set of fonts includes one with the same
-// properties as font_id.
+// properties as font_id. Fonts that are not in this table are ignored.
bool FontInfoTable::SetContainsFontProperties(int font_id,
const std::vector<ScoredFont> &font_set) const {
+ if (!IsValidFontId(*this, font_id)) {
+ return false;
+ }
uint32_t properties = at(font_id).properties;
for (auto &&f : font_set) {
- if (at(f.fontinfo_id).properties == properties) {
+ if (IsValidFontId(*this, f.fontinfo_id) && at(f.fontinfo_id).properties == properties) {
return true;
}
}
@@ -76,15 +86,19 @@ bool FontInfoTable::SetContainsFontProperties(int font_id,
}
// Returns true if the given set of fonts includes multiple properties.
+// Fonts that are not in this table are ignored.
bool FontInfoTable::SetContainsMultipleFontProperties(
const std::vector<ScoredFont> &font_set) const {
- if (font_set.empty()) {
- return false;
- }
- int first_font = font_set[0].fontinfo_id;
- uint32_t properties = at(first_font).properties;
- for (unsigned f = 1; f < font_set.size(); ++f) {
- if (at(font_set[f].fontinfo_id).properties != properties) {
+ bool have_properties = false;
+ uint32_t properties = 0;
+ for (auto &&f : font_set) {
+ if (!IsValidFontId(*this, f.fontinfo_id)) {
+ continue;
+ }
+ if (!have_properties) {
+ properties = at(f.fontinfo_id).properties;
+ have_properties = true;
+ } else if (at(f.fontinfo_id).properties != properties) {
return true;
}
}