Skip to content

Fix #1640: validate numeric value separator in non-root context for non-blocking parser - #1648

Open
seonwooj0810 wants to merge 1 commit into
FasterXML:3.xfrom
seonwooj0810:fix/issue-1640-async-number-separator
Open

Fix #1640: validate numeric value separator in non-root context for non-blocking parser#1648
seonwooj0810 wants to merge 1 commit into
FasterXML:3.xfrom
seonwooj0810:fix/issue-1640-async-number-separator

Conversation

@seonwooj0810

Copy link
Copy Markdown
Contributor

Summary

Follow-up to #1615 (which fixed the three blocking parsers) and per @cowtowncoder's comment in that PR confirming a separate fix for the non-blocking path is warranted.

The non-blocking (async) parser did not verify that numeric values are followed by a valid separator (whitespace, comma, ], }) when parsed inside an Array or Object context, silently accepting malformed inputs that blocking parsers rejected:

// Blocking parsers (fixed in #1615): correctly throw
// Async parser (this PR): previously returned VALUE_NUMBER_INT
JsonParser p = factory.createNonBlockingByteArrayParser(...);
feeder.feedInput(new byte[]{'[','1','2','3','t','r','u','e',']'}, 0, 9);
feeder.endOfInput();
p.nextToken(); // START_ARRAY
p.nextToken(); // was VALUE_NUMBER_INT, should throw StreamReadException

Root cause

Five integer-completion sites and three float-completion sites in NonBlockingUtf8JsonParserBase called _valueComplete(JsonToken.VALUE_NUMBER_*) without a separator check:

  • _startPositiveNumber(int ch) — inline digit loop
  • _startNegativeNumber() — inline digit loop
  • _startPositiveNumber() — inline digit loop (+ sign variant)
  • _finishNumberIntegralPart(...) — resumption path (chunk boundary)
  • Hex number completion (via resetIntHex)
  • _startFloat(...) — inline fraction/exponent loop
  • _finishFloatFraction() — resumption path (fraction digits)
  • _finishFloatExponent(...) — resumption path (exponent digits)

Fix

Adds _verifyNumberSeparator(int ch) to NonBlockingUtf8JsonParserBase, mirroring the same method added to the three blocking parsers in #1615. For root context it delegates to the existing _verifyRootSpace(ch); for non-root context it validates the separator is one of \t\r\n,]} (or a comment-start character if the respective feature is enabled), consistent with the blocking-parser behavior.

All 8 completion sites now call _verifyNumberSeparator(ch) before _valueComplete(...).

Testing

  • New test class AsyncNumberSeparator1640Test covering int, float-fraction, and float-exponent mangled cases across bytesPerRead values of 90, 3, and 1 (to exercise both inline and resumption paths).
  • AsyncTokenBranchNumberErrorTest.mangledNonRootInts in tofix/ now passes; removed its @JacksonTestFailureExpected annotation. The mangledNonRootFloats test remains in tofix/ (the 'f'/'d' suffix case still uses a dedicated code path with a different error message).
  • Full test suite: 1813 tests, 0 failures, 0 errors.

Fixes #1640

…ext for non-blocking parser

Non-blocking (async) parser did not verify that numeric values are followed
by a valid separator (whitespace, comma, `]`, `}`) when parsed inside an
Array or Object context, silently accepting inputs like `[123true]` or
`[1.5x]` that blocking parsers correctly rejected.

Root cause: five inline integer-completion sites in `NonBlockingUtf8JsonParserBase`
(`_startPositiveNumber(int)`, `_startNegativeNumber`, `_startPositiveNumber`,
`_finishNumberIntegralPart`, hex-number completion) and the float-completion
sites in `_startFloat`, `_finishFloatFraction`, `_finishFloatExponent` called
`_valueComplete` without a separator check. The blocking-parser fix in FasterXML#1615
added `_verifyNumberSeparator` to the three blocking parsers; this PR applies
the equivalent check to the non-blocking path.
@github-actions

github-actions Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

📈 Overall Code Coverage

Metric Coverage Change
Instructions coverage 83.64% 📉 -0.030%
Branches branches 76.49% 📉 -0.040%

Overall project coverage from JaCoCo test results. Change values compare against the latest base branch build.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Non-root number separator validation not applied to non-blocking (async) parser (follow-up to #1557)

1 participant