Validate raw binary length in non-blocking Smile parser, accumulate long content [CVE-2026-104895] (#825) - #826
Merged
cowtowncoder merged 15 commits intoOct 2, 2026
Conversation
… long content (FasterXML#825) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This was referenced Oct 2, 2026
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.
Fixes #825.
Started as a fix for raw binary length handling in the non-blocking Smile parser. After review, it also covers related length validation for other length-prefixed values, and
StreamReadConstraintshandling in both Smile parsers.Non-blocking parser (
NonBlockingByteArrayParser)Raw binary (#825)
ByteArrayBuilderas it is fed._binaryValue == nullmode flag.Length validation
BigIntegerlength,BigDecimalscale and length) are decoded by a single resumable helper. It rejects values that do not fit in 31 bits, asSmileParser._readUnsignedVInt()does. TheBigDecimalscale keeps the same 31-bit limit as the blocking parser.Big numbers
BigInteger/BigDecimaldecodes as zero, as in the blocking parser (Uncaught validation problem wrt Smile "BigDecimal" type (found by OSS-Fuzzer) #257). Before, it threwNumberFormatException.Feeding input
feedInput()counts the chunk being fed againstmaxDocumentLength, and validates before changing any state, so a rejected feed leaves the parser unchanged.feedInput()afterclose()is rejected, andneedMoreInput()returnsfalseafterclose().Both parsers:
maxNumberLengthforBigInteger/BigDecimalStreamConstraintsExceptionand continues, the content of the failed value is skipped and parsing resumes with the next token. The blocking parser does not read the content unless the caller continues. Repeated access to the failed value throws the failure again (as a new exception).maxTokenCountin both parsers. If the token count fails for it, the length failure is attached as suppressed.Integer.MAX_VALUE) are reported the same way by both parsers.Other
SmileParserBase._encoded7BitLength(int)helper, used by both parsers. It also fixes the encoded length reported in the "Unexpected end-of-input for Binary value (7-bit)" message._reportInvalidUnsignedVInt()formats bytes as0x%02X, matching the non-blocking parser.NonBlockingParserBase: new minor stateMINOR_VALUE_SKIP_7BIT_BODY.Tests
AsyncRawBinaryLengthTest:BigDecimalscales;AsyncZeroLengthBigNumberTest: zero-lengthBigInteger/BigDecimal.SimpleBinaryParseTest: long raw values (> 250,000 bytes) fed in small chunks, reusing one parser.constraints/LongBigNumberSmileReadTest:maxNumberLengthfailure;constraints/LongDocumentSmileReadTest: non-blockingmaxDocumentLengthwith a single feed, and with a rejected feed.smiletests pass (274).Related issues found during review (not fixed here)
#830, #831, #832, #833, #834, #835
🤖 Generated with Claude Code