diff --git a/release-notes/VERSION-2.x b/release-notes/VERSION-2.x index 34bbd09d50..5c29854ff0 100644 --- a/release-notes/VERSION-2.x +++ b/release-notes/VERSION-2.x @@ -14,6 +14,11 @@ a pure JSON library. === Releases === ------------------------------------------------------------------------ +2.17.1 (not yet released) + +#1241: Fix `NumberInput.looksLikeValidNumber()` implementation + (contributed by @pjfanning) + 2.17.0 (12-Mar-2024) #507: Add `JsonWriteFeature.ESCAPE_FORWARD_SLASHES` to allow escaping of '/' for diff --git a/src/main/java/com/fasterxml/jackson/core/io/NumberInput.java b/src/main/java/com/fasterxml/jackson/core/io/NumberInput.java index 86c73a8986..bde9e32a63 100644 --- a/src/main/java/com/fasterxml/jackson/core/io/NumberInput.java +++ b/src/main/java/com/fasterxml/jackson/core/io/NumberInput.java @@ -39,7 +39,7 @@ public final class NumberInput * @since 2.17 */ private final static Pattern PATTERN_FLOAT = Pattern.compile( - "[+-]?[0-9]+(\\.[0-9]+)?([eE][+-]?[0-9]+)?"); + "[+-]?[0-9]*[\\.]?[0-9]+([eE][+-]?[0-9]+)?"); /** * Fast method for parsing unsigned integers that are known to fit into @@ -570,6 +570,9 @@ public static BigInteger parseBigIntegerWithRadix(final String s, final int radi *

* Note: no trimming ({@code String.trim()}) nor null checks are performed * on String passed. + *

+ * Note: this method returning {@code true} DOES NOT GUARANTEE String is valid + * number but just that it looks close enough. * * @param s String to validate * @@ -578,6 +581,14 @@ public static BigInteger parseBigIntegerWithRadix(final String s, final int radi * @since 2.17 */ public static boolean looksLikeValidNumber(final String s) { - return (s != null) && PATTERN_FLOAT.matcher(s).matches(); + // While PATTERN_FLOAT handles most cases we can optimize some simple ones: + if (s == null || s.isEmpty()) { + return false; + } + if (s.length() == 1) { + char c = s.charAt(0); + return (c <= '9') && (c >= '0'); + } + return PATTERN_FLOAT.matcher(s).matches(); } } diff --git a/src/test/java/com/fasterxml/jackson/core/JUnit5TestBase.java b/src/test/java/com/fasterxml/jackson/core/JUnit5TestBase.java index 983c4381cc..0a71c7d41e 100644 --- a/src/test/java/com/fasterxml/jackson/core/JUnit5TestBase.java +++ b/src/test/java/com/fasterxml/jackson/core/JUnit5TestBase.java @@ -9,7 +9,6 @@ import com.fasterxml.jackson.core.testsupport.TestSupport; import com.fasterxml.jackson.core.testsupport.ThrottledInputStream; import com.fasterxml.jackson.core.testsupport.ThrottledReader; -import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.fail; diff --git a/src/test/java/com/fasterxml/jackson/core/io/NumberInputTest.java b/src/test/java/com/fasterxml/jackson/core/io/NumberInputTest.java index fbbad879d1..a84251eda3 100644 --- a/src/test/java/com/fasterxml/jackson/core/io/NumberInputTest.java +++ b/src/test/java/com/fasterxml/jackson/core/io/NumberInputTest.java @@ -7,7 +7,7 @@ import static org.junit.jupiter.api.Assertions.*; class NumberInputTest - extends com.fasterxml.jackson.core.JUnit5TestBase + extends com.fasterxml.jackson.core.JUnit5TestBase { @Test void nastySmallDouble() @@ -78,12 +78,24 @@ void looksLikeValidNumber() assertTrue(NumberInput.looksLikeValidNumber("0")); assertTrue(NumberInput.looksLikeValidNumber("1")); assertTrue(NumberInput.looksLikeValidNumber("-1")); + assertTrue(NumberInput.looksLikeValidNumber("+1")); // non-JSON assertTrue(NumberInput.looksLikeValidNumber("0001")); // non-JSON + // https://github.com/FasterXML/jackson-databind/issues/4435 + assertTrue(NumberInput.looksLikeValidNumber(".0")); + assertTrue(NumberInput.looksLikeValidNumber(".01")); + assertTrue(NumberInput.looksLikeValidNumber("+.01")); + assertTrue(NumberInput.looksLikeValidNumber("-.01")); + assertTrue(NumberInput.looksLikeValidNumber("-.0")); + assertTrue(NumberInput.looksLikeValidNumber("0.01")); assertTrue(NumberInput.looksLikeValidNumber("-0.10")); assertTrue(NumberInput.looksLikeValidNumber("+0.25")); // non-JSON + assertTrue(NumberInput.looksLikeValidNumber("10.33")); + assertTrue(NumberInput.looksLikeValidNumber("-1.39")); + assertTrue(NumberInput.looksLikeValidNumber("+125.0")); // non-JSON + assertTrue(NumberInput.looksLikeValidNumber("1E10")); assertTrue(NumberInput.looksLikeValidNumber("-1E10")); assertTrue(NumberInput.looksLikeValidNumber("1e-10")); @@ -93,7 +105,10 @@ void looksLikeValidNumber() assertTrue(NumberInput.looksLikeValidNumber("1.4e+45")); assertFalse(NumberInput.looksLikeValidNumber("")); + assertFalse(NumberInput.looksLikeValidNumber(" ")); assertFalse(NumberInput.looksLikeValidNumber(" ")); + assertFalse(NumberInput.looksLikeValidNumber(".")); + assertFalse(NumberInput.looksLikeValidNumber("0.")); assertFalse(NumberInput.looksLikeValidNumber("10_000")); } } diff --git a/src/test/java/com/fasterxml/jackson/core/read/TrailingCommasTest.java b/src/test/java/com/fasterxml/jackson/core/read/TrailingCommasTest.java index afbb68413a..46be006277 100644 --- a/src/test/java/com/fasterxml/jackson/core/read/TrailingCommasTest.java +++ b/src/test/java/com/fasterxml/jackson/core/read/TrailingCommasTest.java @@ -17,9 +17,9 @@ @SuppressWarnings("resource") public class TrailingCommasTest extends JUnit5TestBase { - private JsonFactory factory; - private Set features; - private int mode; + JsonFactory factory; + Set features; + int mode; public void initTrailingCommasTest(int mode, List features) { this.features = new HashSet<>(features);