Skip to content

Commit caadcba

Browse files
authored
Merge pull request #794 from rudrajyotib/master
XML optLong/getLong equivalent updates for string to number conversion.
2 parents 411f711 + 04a4c5a commit caadcba

4 files changed

Lines changed: 54 additions & 12 deletions

File tree

src/main/java/org/json/XML.java

Lines changed: 51 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -486,8 +486,7 @@ public static Object stringToValue(String string) {
486486
* produced, then the value will just be a string.
487487
*/
488488

489-
char initial = string.charAt(0);
490-
if ((initial >= '0' && initial <= '9') || initial == '-') {
489+
if (potentialNumber(string)) {
491490
try {
492491
return stringToNumber(string);
493492
} catch (Exception ignore) {
@@ -496,10 +495,38 @@ public static Object stringToValue(String string) {
496495
return string;
497496
}
498497

498+
private static boolean potentialNumber(String value){
499+
if (value == null || value.isEmpty()){
500+
return false;
501+
}
502+
return potentialPositiveNumberStartingAtIndex(value, (value.charAt(0)=='-'?1:0));
503+
}
504+
505+
private static boolean potentialPositiveNumberStartingAtIndex(String value,int index){
506+
if (index >= value.length()){
507+
return false;
508+
}
509+
return digitAtIndex(value, (value.charAt(index)=='.'?index+1:index));
510+
}
511+
512+
private static boolean digitAtIndex(String value, int index){
513+
if (index >= value.length()){
514+
return false;
515+
}
516+
return value.charAt(index) >= '0' && value.charAt(index) <= '9';
517+
}
518+
499519
/**
500520
* direct copy of {@link JSONObject#stringToNumber(String)} to maintain Android support.
501521
*/
502-
private static Number stringToNumber(final String val) throws NumberFormatException {
522+
private static Number stringToNumber(final String input) throws NumberFormatException {
523+
String val = input;
524+
if (val.startsWith(".")){
525+
val = "0"+val;
526+
}
527+
if (val.startsWith("-.")){
528+
val = "-0."+val.substring(2);
529+
}
503530
char initial = val.charAt(0);
504531
if ((initial >= '0' && initial <= '9') || initial == '-') {
505532
// decimal representation
@@ -518,25 +545,25 @@ private static Number stringToNumber(final String val) throws NumberFormatExcept
518545
try {
519546
Double d = Double.valueOf(val);
520547
if(d.isNaN() || d.isInfinite()) {
521-
throw new NumberFormatException("val ["+val+"] is not a valid number.");
548+
throw new NumberFormatException("val ["+input+"] is not a valid number.");
522549
}
523550
return d;
524551
} catch (NumberFormatException ignore) {
525-
throw new NumberFormatException("val ["+val+"] is not a valid number.");
552+
throw new NumberFormatException("val ["+input+"] is not a valid number.");
526553
}
527554
}
528555
}
529-
// block items like 00 01 etc. Java number parsers treat these as Octal.
556+
val = removeLeadingZerosOfNumber(input);
530557
if(initial == '0' && val.length() > 1) {
531558
char at1 = val.charAt(1);
532559
if(at1 >= '0' && at1 <= '9') {
533-
throw new NumberFormatException("val ["+val+"] is not a valid number.");
560+
throw new NumberFormatException("val ["+input+"] is not a valid number.");
534561
}
535562
} else if (initial == '-' && val.length() > 2) {
536563
char at1 = val.charAt(1);
537564
char at2 = val.charAt(2);
538565
if(at1 == '0' && at2 >= '0' && at2 <= '9') {
539-
throw new NumberFormatException("val ["+val+"] is not a valid number.");
566+
throw new NumberFormatException("val ["+input+"] is not a valid number.");
540567
}
541568
}
542569
// integer representation.
@@ -556,7 +583,7 @@ private static Number stringToNumber(final String val) throws NumberFormatExcept
556583
}
557584
return bi;
558585
}
559-
throw new NumberFormatException("val ["+val+"] is not a valid number.");
586+
throw new NumberFormatException("val ["+input+"] is not a valid number.");
560587
}
561588

562589
/**
@@ -973,4 +1000,19 @@ private static final String indent(int indent) {
9731000
}
9741001
return sb.toString();
9751002
}
1003+
1004+
private static String removeLeadingZerosOfNumber(String value){
1005+
if (value.equals("-")){return value;}
1006+
boolean negativeFirstChar = (value.charAt(0) == '-');
1007+
int counter = negativeFirstChar ? 1:0;
1008+
while (counter < value.length()){
1009+
if (value.charAt(counter) != '0'){
1010+
if (negativeFirstChar) {return "-".concat(value.substring(counter));}
1011+
return value.substring(counter);
1012+
}
1013+
++counter;
1014+
}
1015+
if (negativeFirstChar) {return "-0";}
1016+
return "0";
1017+
}
9761018
}

src/test/java/org/json/junit/JSONMLTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -709,7 +709,7 @@ public void commentsInXML() {
709709
@Test
710710
public void testToJSONArray_jsonOutput() {
711711
final String originalXml = "<root><id>01</id><id>1</id><id>00</id><id>0</id><item id=\"01\"/><title>True</title></root>";
712-
final String expectedJsonString = "[\"root\",[\"id\",\"01\"],[\"id\",1],[\"id\",\"00\"],[\"id\",0],[\"item\",{\"id\":\"01\"}],[\"title\",true]]";
712+
final String expectedJsonString = "[\"root\",[\"id\",1],[\"id\",1],[\"id\",0],[\"id\",0],[\"item\",{\"id\":1}],[\"title\",true]]";
713713
final JSONArray actualJsonOutput = JSONML.toJSONArray(originalXml, false);
714714
assertEquals(expectedJsonString, actualJsonOutput.toString());
715715
}

src/test/java/org/json/junit/XMLConfigurationTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -733,7 +733,7 @@ public void contentOperations() {
733733
@Test
734734
public void testToJSONArray_jsonOutput() {
735735
final String originalXml = "<root><id>01</id><id>1</id><id>00</id><id>0</id><item id=\"01\"/><title>True</title></root>";
736-
final JSONObject expected = new JSONObject("{\"root\":{\"item\":{\"id\":\"01\"},\"id\":[\"01\",1,\"00\",0],\"title\":true}}");
736+
final JSONObject expected = new JSONObject("{\"root\":{\"item\":{\"id\":1},\"id\":[1,1,0,0],\"title\":true}}");
737737
final JSONObject actualJsonOutput = XML.toJSONObject(originalXml,
738738
new XMLParserConfiguration().withKeepStrings(false));
739739
Util.compareActualVsExpectedJsonObjects(actualJsonOutput,expected);

src/test/java/org/json/junit/XMLTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -791,7 +791,7 @@ private void compareFileToJSONObject(String xmlStr, String expectedStr) {
791791
@Test
792792
public void testToJSONArray_jsonOutput() {
793793
final String originalXml = "<root><id>01</id><id>1</id><id>00</id><id>0</id><item id=\"01\"/><title>True</title></root>";
794-
final JSONObject expectedJson = new JSONObject("{\"root\":{\"item\":{\"id\":\"01\"},\"id\":[\"01\",1,\"00\",0],\"title\":true}}");
794+
final JSONObject expectedJson = new JSONObject("{\"root\":{\"item\":{\"id\":1},\"id\":[1,1,0,0],\"title\":true}}");
795795
final JSONObject actualJsonOutput = XML.toJSONObject(originalXml, false);
796796

797797
Util.compareActualVsExpectedJsonObjects(actualJsonOutput,expectedJson);

0 commit comments

Comments
 (0)