Skip to content

Commit c73bde2

Browse files
authored
Fix NumberInput.looksLikeValidNumber() implementation (#1241)
1 parent 1c656ae commit c73bde2

File tree

5 files changed

+37
-7
lines changed

5 files changed

+37
-7
lines changed

release-notes/VERSION-2.x

+5
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ a pure JSON library.
1414
=== Releases ===
1515
------------------------------------------------------------------------
1616

17+
2.17.1 (not yet released)
18+
19+
#1241: Fix `NumberInput.looksLikeValidNumber()` implementation
20+
(contributed by @pjfanning)
21+
1722
2.17.0 (12-Mar-2024)
1823

1924
#507: Add `JsonWriteFeature.ESCAPE_FORWARD_SLASHES` to allow escaping of '/' for

src/main/java/com/fasterxml/jackson/core/io/NumberInput.java

+13-2
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public final class NumberInput
3939
* @since 2.17
4040
*/
4141
private final static Pattern PATTERN_FLOAT = Pattern.compile(
42-
"[+-]?[0-9]+(\\.[0-9]+)?([eE][+-]?[0-9]+)?");
42+
"[+-]?[0-9]*[\\.]?[0-9]+([eE][+-]?[0-9]+)?");
4343

4444
/**
4545
* 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
570570
*<p>
571571
* Note: no trimming ({@code String.trim()}) nor null checks are performed
572572
* on String passed.
573+
*<p>
574+
* Note: this method returning {@code true} DOES NOT GUARANTEE String is valid
575+
* number but just that it looks close enough.
573576
*
574577
* @param s String to validate
575578
*
@@ -578,6 +581,14 @@ public static BigInteger parseBigIntegerWithRadix(final String s, final int radi
578581
* @since 2.17
579582
*/
580583
public static boolean looksLikeValidNumber(final String s) {
581-
return (s != null) && PATTERN_FLOAT.matcher(s).matches();
584+
// While PATTERN_FLOAT handles most cases we can optimize some simple ones:
585+
if (s == null || s.isEmpty()) {
586+
return false;
587+
}
588+
if (s.length() == 1) {
589+
char c = s.charAt(0);
590+
return (c <= '9') && (c >= '0');
591+
}
592+
return PATTERN_FLOAT.matcher(s).matches();
582593
}
583594
}

src/test/java/com/fasterxml/jackson/core/JUnit5TestBase.java

-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import com.fasterxml.jackson.core.testsupport.TestSupport;
1010
import com.fasterxml.jackson.core.testsupport.ThrottledInputStream;
1111
import com.fasterxml.jackson.core.testsupport.ThrottledReader;
12-
import org.junit.jupiter.api.Test;
1312

1413
import static org.junit.jupiter.api.Assertions.assertEquals;
1514
import static org.junit.jupiter.api.Assertions.fail;

src/test/java/com/fasterxml/jackson/core/io/NumberInputTest.java

+16-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import static org.junit.jupiter.api.Assertions.*;
88

99
class NumberInputTest
10-
extends com.fasterxml.jackson.core.JUnit5TestBase
10+
extends com.fasterxml.jackson.core.JUnit5TestBase
1111
{
1212
@Test
1313
void nastySmallDouble()
@@ -78,12 +78,24 @@ void looksLikeValidNumber()
7878
assertTrue(NumberInput.looksLikeValidNumber("0"));
7979
assertTrue(NumberInput.looksLikeValidNumber("1"));
8080
assertTrue(NumberInput.looksLikeValidNumber("-1"));
81+
assertTrue(NumberInput.looksLikeValidNumber("+1")); // non-JSON
8182
assertTrue(NumberInput.looksLikeValidNumber("0001")); // non-JSON
8283

84+
// https://github.com/FasterXML/jackson-databind/issues/4435
85+
assertTrue(NumberInput.looksLikeValidNumber(".0"));
86+
assertTrue(NumberInput.looksLikeValidNumber(".01"));
87+
assertTrue(NumberInput.looksLikeValidNumber("+.01"));
88+
assertTrue(NumberInput.looksLikeValidNumber("-.01"));
89+
assertTrue(NumberInput.looksLikeValidNumber("-.0"));
90+
8391
assertTrue(NumberInput.looksLikeValidNumber("0.01"));
8492
assertTrue(NumberInput.looksLikeValidNumber("-0.10"));
8593
assertTrue(NumberInput.looksLikeValidNumber("+0.25")); // non-JSON
8694

95+
assertTrue(NumberInput.looksLikeValidNumber("10.33"));
96+
assertTrue(NumberInput.looksLikeValidNumber("-1.39"));
97+
assertTrue(NumberInput.looksLikeValidNumber("+125.0")); // non-JSON
98+
8799
assertTrue(NumberInput.looksLikeValidNumber("1E10"));
88100
assertTrue(NumberInput.looksLikeValidNumber("-1E10"));
89101
assertTrue(NumberInput.looksLikeValidNumber("1e-10"));
@@ -93,7 +105,10 @@ void looksLikeValidNumber()
93105
assertTrue(NumberInput.looksLikeValidNumber("1.4e+45"));
94106

95107
assertFalse(NumberInput.looksLikeValidNumber(""));
108+
assertFalse(NumberInput.looksLikeValidNumber(" "));
96109
assertFalse(NumberInput.looksLikeValidNumber(" "));
110+
assertFalse(NumberInput.looksLikeValidNumber("."));
111+
assertFalse(NumberInput.looksLikeValidNumber("0."));
97112
assertFalse(NumberInput.looksLikeValidNumber("10_000"));
98113
}
99114
}

src/test/java/com/fasterxml/jackson/core/read/TrailingCommasTest.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@
1717
@SuppressWarnings("resource")
1818
public class TrailingCommasTest extends JUnit5TestBase {
1919

20-
private JsonFactory factory;
21-
private Set<JsonReadFeature> features;
22-
private int mode;
20+
JsonFactory factory;
21+
Set<JsonReadFeature> features;
22+
int mode;
2323

2424
public void initTrailingCommasTest(int mode, List<JsonReadFeature> features) {
2525
this.features = new HashSet<>(features);

0 commit comments

Comments
 (0)