diff --git a/src/main/java/org/json/XML.java b/src/main/java/org/json/XML.java
index 925f056b1..533192313 100644
--- a/src/main/java/org/json/XML.java
+++ b/src/main/java/org/json/XML.java
@@ -486,8 +486,7 @@ public static Object stringToValue(String string) {
* produced, then the value will just be a string.
*/
- char initial = string.charAt(0);
- if ((initial >= '0' && initial <= '9') || initial == '-') {
+ if (potentialNumber(string)) {
try {
return stringToNumber(string);
} catch (Exception ignore) {
@@ -496,10 +495,38 @@ public static Object stringToValue(String string) {
return string;
}
+ private static boolean potentialNumber(String value){
+ if (value == null || value.isEmpty()){
+ return false;
+ }
+ return potentialPositiveNumberStartingAtIndex(value, (value.charAt(0)=='-'?1:0));
+ }
+
+ private static boolean potentialPositiveNumberStartingAtIndex(String value,int index){
+ if (index >= value.length()){
+ return false;
+ }
+ return digitAtIndex(value, (value.charAt(index)=='.'?index+1:index));
+ }
+
+ private static boolean digitAtIndex(String value, int index){
+ if (index >= value.length()){
+ return false;
+ }
+ return value.charAt(index) >= '0' && value.charAt(index) <= '9';
+ }
+
/**
* direct copy of {@link JSONObject#stringToNumber(String)} to maintain Android support.
*/
- private static Number stringToNumber(final String val) throws NumberFormatException {
+ private static Number stringToNumber(final String input) throws NumberFormatException {
+ String val = input;
+ if (val.startsWith(".")){
+ val = "0"+val;
+ }
+ if (val.startsWith("-.")){
+ val = "-0."+val.substring(2);
+ }
char initial = val.charAt(0);
if ((initial >= '0' && initial <= '9') || initial == '-') {
// decimal representation
@@ -518,25 +545,25 @@ private static Number stringToNumber(final String val) throws NumberFormatExcept
try {
Double d = Double.valueOf(val);
if(d.isNaN() || d.isInfinite()) {
- throw new NumberFormatException("val ["+val+"] is not a valid number.");
+ throw new NumberFormatException("val ["+input+"] is not a valid number.");
}
return d;
} catch (NumberFormatException ignore) {
- throw new NumberFormatException("val ["+val+"] is not a valid number.");
+ throw new NumberFormatException("val ["+input+"] is not a valid number.");
}
}
}
- // block items like 00 01 etc. Java number parsers treat these as Octal.
+ val = removeLeadingZerosOfNumber(input);
if(initial == '0' && val.length() > 1) {
char at1 = val.charAt(1);
if(at1 >= '0' && at1 <= '9') {
- throw new NumberFormatException("val ["+val+"] is not a valid number.");
+ throw new NumberFormatException("val ["+input+"] is not a valid number.");
}
} else if (initial == '-' && val.length() > 2) {
char at1 = val.charAt(1);
char at2 = val.charAt(2);
if(at1 == '0' && at2 >= '0' && at2 <= '9') {
- throw new NumberFormatException("val ["+val+"] is not a valid number.");
+ throw new NumberFormatException("val ["+input+"] is not a valid number.");
}
}
// integer representation.
@@ -556,7 +583,7 @@ private static Number stringToNumber(final String val) throws NumberFormatExcept
}
return bi;
}
- throw new NumberFormatException("val ["+val+"] is not a valid number.");
+ throw new NumberFormatException("val ["+input+"] is not a valid number.");
}
/**
@@ -973,4 +1000,19 @@ private static final String indent(int indent) {
}
return sb.toString();
}
+
+ private static String removeLeadingZerosOfNumber(String value){
+ if (value.equals("-")){return value;}
+ boolean negativeFirstChar = (value.charAt(0) == '-');
+ int counter = negativeFirstChar ? 1:0;
+ while (counter < value.length()){
+ if (value.charAt(counter) != '0'){
+ if (negativeFirstChar) {return "-".concat(value.substring(counter));}
+ return value.substring(counter);
+ }
+ ++counter;
+ }
+ if (negativeFirstChar) {return "-0";}
+ return "0";
+ }
}
diff --git a/src/test/java/org/json/junit/JSONMLTest.java b/src/test/java/org/json/junit/JSONMLTest.java
index 154af645f..e6abd151e 100644
--- a/src/test/java/org/json/junit/JSONMLTest.java
+++ b/src/test/java/org/json/junit/JSONMLTest.java
@@ -709,7 +709,7 @@ public void commentsInXML() {
@Test
public void testToJSONArray_jsonOutput() {
final String originalXml = "011000- True
";
- final String expectedJsonString = "[\"root\",[\"id\",\"01\"],[\"id\",1],[\"id\",\"00\"],[\"id\",0],[\"item\",{\"id\":\"01\"}],[\"title\",true]]";
+ final String expectedJsonString = "[\"root\",[\"id\",1],[\"id\",1],[\"id\",0],[\"id\",0],[\"item\",{\"id\":1}],[\"title\",true]]";
final JSONArray actualJsonOutput = JSONML.toJSONArray(originalXml, false);
assertEquals(expectedJsonString, actualJsonOutput.toString());
}
diff --git a/src/test/java/org/json/junit/XMLConfigurationTest.java b/src/test/java/org/json/junit/XMLConfigurationTest.java
index 21a2b595e..2eaaf99e8 100755
--- a/src/test/java/org/json/junit/XMLConfigurationTest.java
+++ b/src/test/java/org/json/junit/XMLConfigurationTest.java
@@ -733,7 +733,7 @@ public void contentOperations() {
@Test
public void testToJSONArray_jsonOutput() {
final String originalXml = "011000- True
";
- final JSONObject expected = new JSONObject("{\"root\":{\"item\":{\"id\":\"01\"},\"id\":[\"01\",1,\"00\",0],\"title\":true}}");
+ final JSONObject expected = new JSONObject("{\"root\":{\"item\":{\"id\":1},\"id\":[1,1,0,0],\"title\":true}}");
final JSONObject actualJsonOutput = XML.toJSONObject(originalXml,
new XMLParserConfiguration().withKeepStrings(false));
Util.compareActualVsExpectedJsonObjects(actualJsonOutput,expected);
diff --git a/src/test/java/org/json/junit/XMLTest.java b/src/test/java/org/json/junit/XMLTest.java
index 2399b8161..63135eb00 100644
--- a/src/test/java/org/json/junit/XMLTest.java
+++ b/src/test/java/org/json/junit/XMLTest.java
@@ -791,7 +791,7 @@ private void compareFileToJSONObject(String xmlStr, String expectedStr) {
@Test
public void testToJSONArray_jsonOutput() {
final String originalXml = "011000- True
";
- final JSONObject expectedJson = new JSONObject("{\"root\":{\"item\":{\"id\":\"01\"},\"id\":[\"01\",1,\"00\",0],\"title\":true}}");
+ final JSONObject expectedJson = new JSONObject("{\"root\":{\"item\":{\"id\":1},\"id\":[1,1,0,0],\"title\":true}}");
final JSONObject actualJsonOutput = XML.toJSONObject(originalXml, false);
Util.compareActualVsExpectedJsonObjects(actualJsonOutput,expectedJson);