From 00c853ec23ffcfaac0ff7228cf7e9c6d853f2ef3 Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Fri, 24 Jun 2022 12:06:55 +0100 Subject: [PATCH 1/2] issue with parsing '-.125' when leading decimal points allowed --- .../jackson/core/json/ReaderBasedJsonParser.java | 10 ++++++++-- .../jackson/core/json/UTF8DataInputJsonParser.java | 9 +++++++-- .../jackson/core/json/UTF8StreamJsonParser.java | 9 +++++++-- .../core/read/NonStandardNumberParsingTest.java | 6 ++++++ 4 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/fasterxml/jackson/core/json/ReaderBasedJsonParser.java b/src/main/java/com/fasterxml/jackson/core/json/ReaderBasedJsonParser.java index 193a08f1e1..281a0b4739 100644 --- a/src/main/java/com/fasterxml/jackson/core/json/ReaderBasedJsonParser.java +++ b/src/main/java/com/fasterxml/jackson/core/json/ReaderBasedJsonParser.java @@ -1327,12 +1327,18 @@ public final Boolean nextBooleanValue() throws IOException // @since 2.11, [core#611] protected final JsonToken _parseFloatThatStartsWithPeriod() throws IOException + { + return _parseFloatThatStartsWithPeriod(false); + } + + protected final JsonToken _parseFloatThatStartsWithPeriod(final boolean neg) throws IOException { // [core#611]: allow optionally leading decimal point if (!isEnabled(JsonReadFeature.ALLOW_LEADING_DECIMAL_POINT_FOR_NUMBERS.mappedFeature())) { return _handleOddValue('.'); } - return _parseFloat(INT_PERIOD, _inputPtr-1, _inputPtr, false, 0); + final int startPtr = neg ? _inputPtr-2 : _inputPtr; + return _parseFloat(INT_PERIOD, startPtr, _inputPtr, neg, 0); } /** @@ -1491,7 +1497,7 @@ private final JsonToken _parseSignedNumber(final boolean negative) throws IOExce if (ch > INT_9 || ch < INT_0) { _inputPtr = ptr; if (ch == INT_PERIOD) { - return _parseFloatThatStartsWithPeriod(); + return _parseFloatThatStartsWithPeriod(negative); } return _handleInvalidNumberStart(ch, negative, true); } diff --git a/src/main/java/com/fasterxml/jackson/core/json/UTF8DataInputJsonParser.java b/src/main/java/com/fasterxml/jackson/core/json/UTF8DataInputJsonParser.java index 377b5e8ed8..9175a3bfcd 100644 --- a/src/main/java/com/fasterxml/jackson/core/json/UTF8DataInputJsonParser.java +++ b/src/main/java/com/fasterxml/jackson/core/json/UTF8DataInputJsonParser.java @@ -1002,13 +1002,18 @@ public Boolean nextBooleanValue() throws IOException // @since 2.11, [core#611] protected final JsonToken _parseFloatThatStartsWithPeriod() throws IOException + { + return _parseFloatThatStartsWithPeriod(false); + } + + protected final JsonToken _parseFloatThatStartsWithPeriod(final boolean neg) throws IOException { // [core#611]: allow optionally leading decimal point if (!isEnabled(JsonReadFeature.ALLOW_LEADING_DECIMAL_POINT_FOR_NUMBERS.mappedFeature())) { return _handleUnexpectedValue(INT_PERIOD); } char[] outBuf = _textBuffer.emptyAndGetCurrentSegment(); - return _parseFloat(outBuf, 0, INT_PERIOD, false, 0); + return _parseFloat(outBuf, 0, INT_PERIOD, neg, 0); } /** @@ -1107,7 +1112,7 @@ private final JsonToken _parseSignedNumber(boolean negative) throws IOException if (c == INT_0) { c = _handleLeadingZeroes(); } else if (c == INT_PERIOD) { - return _parseFloatThatStartsWithPeriod(); + return _parseFloatThatStartsWithPeriod(negative); } else { return _handleInvalidNumberStart(c, negative, true); } diff --git a/src/main/java/com/fasterxml/jackson/core/json/UTF8StreamJsonParser.java b/src/main/java/com/fasterxml/jackson/core/json/UTF8StreamJsonParser.java index b749693898..b4282ad4be 100644 --- a/src/main/java/com/fasterxml/jackson/core/json/UTF8StreamJsonParser.java +++ b/src/main/java/com/fasterxml/jackson/core/json/UTF8StreamJsonParser.java @@ -1432,13 +1432,18 @@ public Boolean nextBooleanValue() throws IOException // @since 2.11, [core#611] protected final JsonToken _parseFloatThatStartsWithPeriod() throws IOException + { + return _parseFloatThatStartsWithPeriod(false); + } + + protected final JsonToken _parseFloatThatStartsWithPeriod(final boolean neg) throws IOException { // [core#611]: allow optionally leading decimal point if (!isEnabled(JsonReadFeature.ALLOW_LEADING_DECIMAL_POINT_FOR_NUMBERS.mappedFeature())) { return _handleUnexpectedValue(INT_PERIOD); } return _parseFloat(_textBuffer.emptyAndGetCurrentSegment(), - 0, INT_PERIOD, false, 0); + 0, INT_PERIOD, neg, 0); } /** @@ -1522,7 +1527,7 @@ private final JsonToken _parseSignedNumber(boolean negative) throws IOException // One special case: if first char is 0, must not be followed by a digit if (c != INT_0) { if (c == INT_PERIOD) { - return _parseFloatThatStartsWithPeriod(); + return _parseFloatThatStartsWithPeriod(negative); } return _handleInvalidNumberStart(c, negative, true); } diff --git a/src/test/java/com/fasterxml/jackson/core/read/NonStandardNumberParsingTest.java b/src/test/java/com/fasterxml/jackson/core/read/NonStandardNumberParsingTest.java index 1bd6aea0f8..2f32e9a72a 100644 --- a/src/test/java/com/fasterxml/jackson/core/read/NonStandardNumberParsingTest.java +++ b/src/test/java/com/fasterxml/jackson/core/read/NonStandardNumberParsingTest.java @@ -115,6 +115,12 @@ private void _testLeadingDotInDecimalAllowed(JsonFactory f, int mode) throws Exc assertEquals("0.125", p.getDecimalValue().toString()); assertEquals(".125", p.getText()); } + try (JsonParser p = createParser(f, mode, " -.125 ")) { + assertEquals(JsonToken.VALUE_NUMBER_FLOAT, p.nextToken()); + assertEquals(-0.125, p.getValueAsDouble()); + assertEquals("-0.125", p.getDecimalValue().toString()); + assertEquals("-.125", p.getText()); + } } private void _testLeadingPlusSignInDecimalAllowed(JsonFactory f, int mode) throws Exception From ea24e28c429fc74bb51a296a125282995e2fb4fd Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Fri, 24 Jun 2022 23:38:41 +0100 Subject: [PATCH 2/2] move failing test to failing tests dir --- .../core/json/ReaderBasedJsonParser.java | 3 +- .../read/NonStandardNumberParsingTest.java | 6 --- .../FailingNonStandardNumberParsingTest.java | 44 +++++++++++++++++++ 3 files changed, 45 insertions(+), 8 deletions(-) create mode 100644 src/test/java/com/fasterxml/jackson/failing/FailingNonStandardNumberParsingTest.java diff --git a/src/main/java/com/fasterxml/jackson/core/json/ReaderBasedJsonParser.java b/src/main/java/com/fasterxml/jackson/core/json/ReaderBasedJsonParser.java index 281a0b4739..46eacb285f 100644 --- a/src/main/java/com/fasterxml/jackson/core/json/ReaderBasedJsonParser.java +++ b/src/main/java/com/fasterxml/jackson/core/json/ReaderBasedJsonParser.java @@ -1337,8 +1337,7 @@ protected final JsonToken _parseFloatThatStartsWithPeriod(final boolean neg) thr if (!isEnabled(JsonReadFeature.ALLOW_LEADING_DECIMAL_POINT_FOR_NUMBERS.mappedFeature())) { return _handleOddValue('.'); } - final int startPtr = neg ? _inputPtr-2 : _inputPtr; - return _parseFloat(INT_PERIOD, startPtr, _inputPtr, neg, 0); + return _parseFloat(INT_PERIOD, _inputPtr-1, _inputPtr, neg, 0); } /** diff --git a/src/test/java/com/fasterxml/jackson/core/read/NonStandardNumberParsingTest.java b/src/test/java/com/fasterxml/jackson/core/read/NonStandardNumberParsingTest.java index 2f32e9a72a..1bd6aea0f8 100644 --- a/src/test/java/com/fasterxml/jackson/core/read/NonStandardNumberParsingTest.java +++ b/src/test/java/com/fasterxml/jackson/core/read/NonStandardNumberParsingTest.java @@ -115,12 +115,6 @@ private void _testLeadingDotInDecimalAllowed(JsonFactory f, int mode) throws Exc assertEquals("0.125", p.getDecimalValue().toString()); assertEquals(".125", p.getText()); } - try (JsonParser p = createParser(f, mode, " -.125 ")) { - assertEquals(JsonToken.VALUE_NUMBER_FLOAT, p.nextToken()); - assertEquals(-0.125, p.getValueAsDouble()); - assertEquals("-0.125", p.getDecimalValue().toString()); - assertEquals("-.125", p.getText()); - } } private void _testLeadingPlusSignInDecimalAllowed(JsonFactory f, int mode) throws Exception diff --git a/src/test/java/com/fasterxml/jackson/failing/FailingNonStandardNumberParsingTest.java b/src/test/java/com/fasterxml/jackson/failing/FailingNonStandardNumberParsingTest.java new file mode 100644 index 0000000000..0f8201d918 --- /dev/null +++ b/src/test/java/com/fasterxml/jackson/failing/FailingNonStandardNumberParsingTest.java @@ -0,0 +1,44 @@ +package com.fasterxml.jackson.failing; + +import com.fasterxml.jackson.core.BaseTest; +import com.fasterxml.jackson.core.JsonFactory; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonToken; +import com.fasterxml.jackson.core.json.JsonReadFeature; + +public class FailingNonStandardNumberParsingTest + extends BaseTest +{ + private final JsonFactory JSON_F = JsonFactory.builder() + .enable(JsonReadFeature.ALLOW_LEADING_PLUS_SIGN_FOR_NUMBERS) + .enable(JsonReadFeature.ALLOW_LEADING_DECIMAL_POINT_FOR_NUMBERS) + .enable(JsonReadFeature.ALLOW_TRAILING_DECIMAL_POINT_FOR_NUMBERS) + .build(); + + protected JsonFactory jsonFactory() { + return JSON_F; + } + + public void testLeadingDotInNegativeDecimalAllowedAsync() throws Exception { + _testLeadingDotInNegativeDecimalAllowed(jsonFactory(), MODE_DATA_INPUT); + } + + public void testLeadingDotInNegativeDecimalAllowedBytes() throws Exception { + _testLeadingDotInNegativeDecimalAllowed(jsonFactory(), MODE_INPUT_STREAM); + _testLeadingDotInNegativeDecimalAllowed(jsonFactory(), MODE_INPUT_STREAM_THROTTLED); + } + + public void testLeadingDotInNegativeDecimalAllowedReader() throws Exception { + _testLeadingDotInNegativeDecimalAllowed(jsonFactory(), MODE_READER); + } + + private void _testLeadingDotInNegativeDecimalAllowed(JsonFactory f, int mode) throws Exception + { + try (JsonParser p = createParser(f, mode, " -.125 ")) { + assertEquals(JsonToken.VALUE_NUMBER_FLOAT, p.nextToken()); + assertEquals(-0.125, p.getValueAsDouble()); + assertEquals("-0.125", p.getDecimalValue().toString()); + assertEquals("-.125", p.getText()); + } + } +}