Skip to content

Commit 3f97826

Browse files
authored
Merge pull request #869 from stleary/revert-recent-objLong-getLong-changes
Revert recent obj long get long changes
2 parents d36066c + d520210 commit 3f97826

12 files changed

+242
-581
lines changed

src/main/java/org/json/JSONArray.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ public Number getNumber(int index) throws JSONException {
360360
if (object instanceof Number) {
361361
return (Number)object;
362362
}
363-
return NumberConversionUtil.stringToNumber(object.toString());
363+
return JSONObject.stringToNumber(object.toString());
364364
} catch (Exception e) {
365365
throw wrongValueFormatException(index, "number", object, e);
366366
}
@@ -1107,7 +1107,7 @@ public Number optNumber(int index, Number defaultValue) {
11071107

11081108
if (val instanceof String) {
11091109
try {
1110-
return NumberConversionUtil.stringToNumber((String) val);
1110+
return JSONObject.stringToNumber((String) val);
11111111
} catch (Exception e) {
11121112
return defaultValue;
11131113
}

src/main/java/org/json/JSONObject.java

Lines changed: 90 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,6 @@
2828
import java.util.Set;
2929
import java.util.regex.Pattern;
3030

31-
import static org.json.NumberConversionUtil.potentialNumber;
32-
import static org.json.NumberConversionUtil.stringToNumber;
33-
3431
/**
3532
* A JSONObject is an unordered collection of name/value pairs. Its external
3633
* form is a string wrapped in curly braces with colons between the names and
@@ -2460,7 +2457,8 @@ public static Object stringToValue(String string) {
24602457
* produced, then the value will just be a string.
24612458
*/
24622459

2463-
if (potentialNumber(string)) {
2460+
char initial = string.charAt(0);
2461+
if ((initial >= '0' && initial <= '9') || initial == '-') {
24642462
try {
24652463
return stringToNumber(string);
24662464
} catch (Exception ignore) {
@@ -2469,8 +2467,75 @@ public static Object stringToValue(String string) {
24692467
return string;
24702468
}
24712469

2472-
2473-
2470+
/**
2471+
* Converts a string to a number using the narrowest possible type. Possible
2472+
* returns for this function are BigDecimal, Double, BigInteger, Long, and Integer.
2473+
* When a Double is returned, it should always be a valid Double and not NaN or +-infinity.
2474+
*
2475+
* @param val value to convert
2476+
* @return Number representation of the value.
2477+
* @throws NumberFormatException thrown if the value is not a valid number. A public
2478+
* caller should catch this and wrap it in a {@link JSONException} if applicable.
2479+
*/
2480+
protected static Number stringToNumber(final String val) throws NumberFormatException {
2481+
char initial = val.charAt(0);
2482+
if ((initial >= '0' && initial <= '9') || initial == '-') {
2483+
// decimal representation
2484+
if (isDecimalNotation(val)) {
2485+
// Use a BigDecimal all the time so we keep the original
2486+
// representation. BigDecimal doesn't support -0.0, ensure we
2487+
// keep that by forcing a decimal.
2488+
try {
2489+
BigDecimal bd = new BigDecimal(val);
2490+
if(initial == '-' && BigDecimal.ZERO.compareTo(bd)==0) {
2491+
return Double.valueOf(-0.0);
2492+
}
2493+
return bd;
2494+
} catch (NumberFormatException retryAsDouble) {
2495+
// this is to support "Hex Floats" like this: 0x1.0P-1074
2496+
try {
2497+
Double d = Double.valueOf(val);
2498+
if(d.isNaN() || d.isInfinite()) {
2499+
throw new NumberFormatException("val ["+val+"] is not a valid number.");
2500+
}
2501+
return d;
2502+
} catch (NumberFormatException ignore) {
2503+
throw new NumberFormatException("val ["+val+"] is not a valid number.");
2504+
}
2505+
}
2506+
}
2507+
// block items like 00 01 etc. Java number parsers treat these as Octal.
2508+
if(initial == '0' && val.length() > 1) {
2509+
char at1 = val.charAt(1);
2510+
if(at1 >= '0' && at1 <= '9') {
2511+
throw new NumberFormatException("val ["+val+"] is not a valid number.");
2512+
}
2513+
} else if (initial == '-' && val.length() > 2) {
2514+
char at1 = val.charAt(1);
2515+
char at2 = val.charAt(2);
2516+
if(at1 == '0' && at2 >= '0' && at2 <= '9') {
2517+
throw new NumberFormatException("val ["+val+"] is not a valid number.");
2518+
}
2519+
}
2520+
// integer representation.
2521+
// This will narrow any values to the smallest reasonable Object representation
2522+
// (Integer, Long, or BigInteger)
2523+
2524+
// BigInteger down conversion: We use a similar bitLength compare as
2525+
// BigInteger#intValueExact uses. Increases GC, but objects hold
2526+
// only what they need. i.e. Less runtime overhead if the value is
2527+
// long lived.
2528+
BigInteger bi = new BigInteger(val);
2529+
if(bi.bitLength() <= 31){
2530+
return Integer.valueOf(bi.intValue());
2531+
}
2532+
if(bi.bitLength() <= 63){
2533+
return Long.valueOf(bi.longValue());
2534+
}
2535+
return bi;
2536+
}
2537+
throw new NumberFormatException("val ["+val+"] is not a valid number.");
2538+
}
24742539

24752540
/**
24762541
* Throw an exception if the object is a NaN or infinite number.
@@ -2896,5 +2961,23 @@ private static JSONException recursivelyDefinedObjectException(String key) {
28962961
);
28972962
}
28982963

2899-
2964+
/**
2965+
* For a prospective number, remove the leading zeros
2966+
* @param value prospective number
2967+
* @return number without leading zeros
2968+
*/
2969+
private static String removeLeadingZerosOfNumber(String value){
2970+
if (value.equals("-")){return value;}
2971+
boolean negativeFirstChar = (value.charAt(0) == '-');
2972+
int counter = negativeFirstChar ? 1:0;
2973+
while (counter < value.length()){
2974+
if (value.charAt(counter) != '0'){
2975+
if (negativeFirstChar) {return "-".concat(value.substring(counter));}
2976+
return value.substring(counter);
2977+
}
2978+
++counter;
2979+
}
2980+
if (negativeFirstChar) {return "-0";}
2981+
return "0";
2982+
}
29002983
}

src/main/java/org/json/NumberConversionUtil.java

Lines changed: 0 additions & 152 deletions
This file was deleted.

0 commit comments

Comments
 (0)