Repository navigation
Conversation
LSTMRecognizer::DeSerialize read the null character index null_char_ from the TESSDATA_LSTM component with only a read-success check. The value is later used as an index into top_n_flags_ and outputs in RecodeBeamSearch, both sized to the network softmax width (NumOutputs), so a negative or oversized null_char caused an out-of-bounds write and read on the first recognition step. Validate null_char_ against network_->NumOutputs() at load time and fail the load on an out-of-range value. Add lstm_nullchar_test, which patches the null_char field of a copy of eng.traineddata (locating it via Network::CreateFromFile) and checks that Init rejects an oversized and a negative value. Both tests pass with the fix and fail without it. Fixes GHSA-m232-6r7p-cwq7 Reported-by: Zhixi "Jace" Sun <g.mygenie@gmail.com> Assisted-by: OpenCode / qwen3.8-27b-thinking (Alibaba Cloud) Signed-off-by: Stefan Weil <sw@weilnetz.de>
Up to standards ✅🟢 Issues
|
| Metric | Results |
|---|---|
| Complexity | 21 |
| Duplication | 2 |
NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.
Member
Author
|
@manus-use, please review. |
The CMake unit tests are discovered by globbing unittest/*.cc, so lstm_nullchar_test is picked up automatically there, but the autotools build lists every check program and source explicitly. Add the test to check_PROGRAMS and give it a _SOURCES block. It exercises only libtesseract plus Leptonica (it drives TessBaseAPI/Network loading) and needs neither the legacy engine nor the training tools, so it is not guarded. Assisted-by: OpenCode / qwen3.8-27b-thinking (Alibaba Cloud) Signed-off-by: Stefan Weil <sw@weilnetz.de>
stweil
force-pushed
the
ghsa-m232-nullchar
branch
from
October 8, 2026 08:33
363f153 to
7625d20
Compare
The new null_char range check in LSTMRecognizer::DeSerialize rejects a model when null_char_ >= network_->NumOutputs(). plumbing_test's ToleratesUnicharsetWithoutSpecialCodes built a fixture whose NT_INPUT network declared no outputs, so the (in-range) null_char_ of 0 was now rejected and the model failed to load. The check is correct: a network with zero outputs has no valid output index, so null_char_ can never be in range and the model is unusable. Relaxing the check would leave top_n_flags_[null_char_] indexing past an empty vector, which is exactly the OOB the advisory describes. Instead, declare one output on the fixture so the check passes and the test continues to verify that a unicharset without the special codes loads cleanly. The Rejects* fixtures are unaffected: they are dropped on the empty-stack check before null_char_ is read. Assisted-by: OpenCode / qwen3.8-27b-thinking (Alibaba Cloud) Signed-off-by: Stefan Weil <sw@weilnetz.de>
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
Fixture-construction failures can silently skip both security regression tests.
1 open finding
What changed in this PR
Validates LSTM null_char_ during model loading to prevent out-of-bounds softmax access.
Changes:
- Rejects negative or oversized null-character indices.
- Adds malformed-model regression tests.
- Updates existing fixtures and Autotools registration.
| File | Description |
|---|---|
src/lstm/lstmrecognizer.cpp |
Adds range validation. |
unittest/lstm_nullchar_test.cc |
Adds regression tests. |
unittest/plumbing_test.cc |
Updates fixture output width. |
Makefile.am |
Registers the new test. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+55
to
+56
| bool MakePatchedTraineddata(const std::string &dir, int32_t patched_null_char, | ||
| int *num_outputs) { |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
LSTMRecognizer::DeSerialize read the null character index null_char_ from the TESSDATA_LSTM component with only a read-success check. The value is later used as an index into top_n_flags_ and outputs in RecodeBeamSearch, both sized to the network softmax width (NumOutputs), so a negative or oversized null_char caused an out-of-bounds write and read on the first recognition step.
Validate null_char_ against network_->NumOutputs() at load time and fail the load on an out-of-range value.
Add lstm_nullchar_test, which patches the null_char field of a copy of eng.traineddata (locating it via Network::CreateFromFile) and checks that Init rejects an oversized and a negative value. Both tests pass with the fix and fail without it.
Fixes GHSA-m232-6r7p-cwq7
Reported-by: Zhixi "Jace" Sun g.mygenie@gmail.com
Assisted-by: OpenCode / qwen3.8-27b-thinking (Alibaba Cloud)