Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,12 @@ public abstract class NonBlockingJsonParserBase
protected final static int MINOR_NUMBER_EXPONENT_MARKER = 31;
protected final static int MINOR_NUMBER_EXPONENT_DIGITS = 32;

// Resumption state for an explicit '+' followed by '0' (and possibly more
// zeros). Companion to {@link #MINOR_NUMBER_ZERO} and
// {@link #MINOR_NUMBER_MINUSZERO}; needed so that the buffered text on
// resume correctly retains the leading '+' character.
protected final static int MINOR_NUMBER_PLUSZERO = 33;

protected final static int MINOR_VALUE_STRING = 40;
protected final static int MINOR_VALUE_STRING_ESCAPE = 41;
protected final static int MINOR_VALUE_STRING_UTF8_2 = 42;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,8 @@ protected final JsonToken _finishToken() throws JacksonException
return _finishNumberLeadingZeroes();
case MINOR_NUMBER_MINUSZERO:
return _finishNumberLeadingNegZeroes();
case MINOR_NUMBER_PLUSZERO:
return _finishNumberLeadingPosZeroes();
case MINOR_NUMBER_INTEGER_DIGITS:
return _finishNumberIntegralPart(_textBuffer.getBufferWithoutReset(),
_textBuffer.getCurrentSegmentSize());
Expand Down Expand Up @@ -349,15 +351,21 @@ protected final JsonToken _finishTokenWithEOF() throws JacksonException
return _finishKeywordTokenWithEOF("false", _pending32, JsonToken.VALUE_FALSE);
case MINOR_VALUE_TOKEN_NON_STD:
return _finishNonStdTokenWithEOF(_nonStdTokenType, _pending32);
case MINOR_VALUE_TOKEN_ERROR: // case of "almost token", just need tokenize for error
case MINOR_VALUE_TOKEN_ERROR: // case of "almost token", just need to tokenize for error
return _finishErrorTokenWithEOF();

// Number-parsing states; valid stopping points, more explicit errors
case MINOR_NUMBER_ZERO:
case MINOR_NUMBER_MINUSZERO:
// NOTE: does NOT retain possible leading minus-sign (can change if
// absolutely needs be)
return _valueCompleteInt(0, "0");
case MINOR_NUMBER_MINUSZERO:
_numberNegative = true;
_valueCompleteInt(0, "-0");
_intLength = 1;
return _currToken;
case MINOR_NUMBER_PLUSZERO:
_valueCompleteInt(0, "+0");
_intLength = 1;
return _currToken;
case MINOR_NUMBER_INTEGER_DIGITS:
// Fine: just need to ensure we have value fully defined
{
Expand Down Expand Up @@ -1643,7 +1651,10 @@ protected JsonToken _finishNumberLeadingPosNegZeroes(final boolean negative) thr
// numeric characters; likely legal separators, or, known illegal (letters).
while (true) {
if (_inputPtr >= _inputEnd) {
_minorState = negative ? MINOR_NUMBER_MINUSZERO : MINOR_NUMBER_ZERO;
// Use MINOR_NUMBER_PLUSZERO for explicit-plus paths so the sign is
// preserved on resumption (callers reach here via
// _finishNumberLeadingPosZeroes / _finishNumberLeadingNegZeroes only).
_minorState = negative ? MINOR_NUMBER_MINUSZERO : MINOR_NUMBER_PLUSZERO;
return _updateTokenToNA();
}
int ch = getNextUnsignedByteFromBuffer();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,11 @@ void leadingPlusSignInDecimalEnabled2() throws Exception {
assertEquals(JsonToken.VALUE_NUMBER_FLOAT, p.nextToken());
assertEquals(0.123, p.getDoubleValue());
assertEquals("0.123", p.getDecimalValue().toString());
assertEquals("0.123", p.currentText());
// The async parser now retains the leading '+' here too, matching the
// blocking parsers and the sibling leadingPlusSignInDecimalEnabled test
// for "+123". Previously the explicit '+' followed by leading zero was
// lost on the byte-by-byte resumption path.
assertEquals("+0.123", p.currentText());
} finally {
p.close();
}
Expand All @@ -256,6 +260,48 @@ void leadingPlusSignInDecimalEnabled3() throws Exception {
}
}

// Root-level "+0" / "-0" / "0" terminated by end-of-input: exercises the
// MINOR_NUMBER_PLUSZERO / MINOR_NUMBER_MINUSZERO / MINOR_NUMBER_ZERO branches
// of `_finishTokenWithEOF`. Previously the sign was discarded here even when
// the byte-by-byte resumption path preserved it.
@Test
void rootPlusZeroAtEOF() throws Exception {
JsonFactory jsonFactory = JsonFactory.builder()
.enable(JsonReadFeature.ALLOW_LEADING_PLUS_SIGN_FOR_NUMBERS).build();
AsyncReaderWrapper p = createParser(jsonFactory, "+0", 1);
try {
assertEquals(JsonToken.VALUE_NUMBER_INT, p.nextToken());
assertEquals(0, p.getIntValue());
assertEquals("+0", p.currentText());
} finally {
p.close();
}
}

@Test
void rootMinusZeroAtEOF() throws Exception {
AsyncReaderWrapper p = createParser(DEFAULT_F, "-0", 1);
try {
assertEquals(JsonToken.VALUE_NUMBER_INT, p.nextToken());
assertEquals(0, p.getIntValue());
assertEquals("-0", p.currentText());
} finally {
p.close();
}
}

@Test
void rootPlainZeroAtEOF() throws Exception {
AsyncReaderWrapper p = createParser(DEFAULT_F, "0", 1);
try {
assertEquals(JsonToken.VALUE_NUMBER_INT, p.nextToken());
assertEquals(0, p.getIntValue());
assertEquals("0", p.currentText());
} finally {
p.close();
}
}

@Test
void leadingPlusSignNoLeadingZeroDisabled() throws Exception {
final String JSON = "[ +.123 ]";
Expand Down
Loading