From f099a5f8eb3c9db19047e7059f13142b1210b5be Mon Sep 17 00:00:00 2001 From: shoothzj Date: Thu, 12 Aug 2021 16:28:06 +0800 Subject: [PATCH] Fix the incorrect double compare with e,E+,e+ --- .../minidev/json/parser/JSONParserBase.java | 35 +++++++++++++++++-- .../json/test/TestBigDigitUnrestricted.java | 2 +- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/json-smart/src/main/java/net/minidev/json/parser/JSONParserBase.java b/json-smart/src/main/java/net/minidev/json/parser/JSONParserBase.java index afafd72..5a0e67f 100644 --- a/json-smart/src/main/java/net/minidev/json/parser/JSONParserBase.java +++ b/json-smart/src/main/java/net/minidev/json/parser/JSONParserBase.java @@ -148,14 +148,16 @@ protected Number extractFloat() throws ParseException { // follow JSonIJ parsing method if (xs.length() > 18) { - BigDecimal big = new BigDecimal(xs); // use extra CPU to check if the result can be return as double without precision lost if (!unrestictBigDigit) { double asDouble = Double.parseDouble(xs); - if (String.valueOf(asDouble).equals(xs)) + final String doubleStr = String.valueOf(asDouble); + // we need a compare compat `e` `E` `e+` `E+` + if (compareDoublePrecision(doubleStr, xs)){ return asDouble; + } } - return big; + return new BigDecimal(xs); } return Double.parseDouble(xs); @@ -165,6 +167,33 @@ protected Number extractFloat() throws ParseException { } } + private boolean compareDoublePrecision(String convert, String origin) { + final char[] charArray = convert.toCharArray(); + final char[] originArray = origin.toCharArray(); + if (charArray.length > originArray.length) { + return false; + } + int j = 0; + for (int i = 0; i < charArray.length; i++) { + if (charArray[i] < '0' || charArray[i] > '9') { + if (originArray[j] >= '0' && originArray[j] <= '9') { + return false; + } else { + j++; + if (originArray[j] == '+') { + j++; + } + continue; + } + } + if (charArray[i] != originArray[j]) { + return false; + } + j++; + } + return j == originArray.length; + } + /** * use to return Primitive Type, or String, Or JsonObject or JsonArray * generated by a ContainerFactory diff --git a/json-smart/src/test/java/net/minidev/json/test/TestBigDigitUnrestricted.java b/json-smart/src/test/java/net/minidev/json/test/TestBigDigitUnrestricted.java index 8619a11..5d6933b 100644 --- a/json-smart/src/test/java/net/minidev/json/test/TestBigDigitUnrestricted.java +++ b/json-smart/src/test/java/net/minidev/json/test/TestBigDigitUnrestricted.java @@ -10,7 +10,7 @@ import org.junit.jupiter.api.Test; public class TestBigDigitUnrestricted { - public static String[] VALID_DOUBLE_JSON = new String[] {"{\"v\":0.12345678912345678}"}; + public static String[] VALID_DOUBLE_JSON = new String[] {"{\"v\":0.12345678912345678}", "\"v\":\"1.7976931348623157E308\"", "\"v\":\"1.7976931348623157E+308\"", "\"v\":\"1.7976931348623157e+308\""}; @Test public void testRestrictedBigDigit() throws Exception {