diff --git a/README.md b/README.md
index e999230ba..9f0134206 100644
--- a/README.md
+++ b/README.md
@@ -8,7 +8,7 @@ JSON in Java [package org.json]
[](https://mvnrepository.com/artifact/org.json/json)
-**[Click here if you just want the latest release jar file.](https://search.maven.org/remotecontent?filepath=org/json/json/20230618/json-20230618.jar)**
+**[Click here if you just want the latest release jar file.](https://search.maven.org/remotecontent?filepath=org/json/json/20231013/json-20231013.jar)**
# Overview
diff --git a/build.gradle b/build.gradle
index 8a3708a74..fbc2ff1f1 100644
--- a/build.gradle
+++ b/build.gradle
@@ -20,7 +20,7 @@ repositories {
}
dependencies {
- testImplementation 'junit:junit:4.13.1'
+ testImplementation 'junit:junit:4.13.2'
testImplementation 'com.jayway.jsonpath:json-path:2.1.0'
testImplementation 'org.mockito:mockito-core:4.2.0'
}
diff --git a/docs/RELEASES.md b/docs/RELEASES.md
index ae439831c..2b8aaa267 100644
--- a/docs/RELEASES.md
+++ b/docs/RELEASES.md
@@ -5,6 +5,8 @@ and artifactId "json". For example:
[https://search.maven.org/search?q=g:org.json%20AND%20a:json&core=gav](https://search.maven.org/search?q=g:org.json%20AND%20a:json&core=gav)
~~~
+20231013 First release with minimum Java version 1.8. Recent commits, including fixes for CVE-2023-5072.
+
20230618 Final release with Java 1.6 compatibility. Future releases will require Java 1.8 or greater.
20230227 Fix for CVE-2022-45688 and recent commits
diff --git a/pom.xml b/pom.xml
index 720529c50..77bbdaca3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
org.json
json
- 20230618
+ 20231013
bundle
JSON in Java
@@ -15,7 +15,7 @@
It also includes the capability to convert between JSON and XML, HTTP
headers, Cookies, and CDL.
- This is a reference implementation. There is a large number of JSON packages
+ This is a reference implementation. There are a large number of JSON packages
in Java. Perhaps someday the Java community will standardize on one. Until
then, choose carefully.
@@ -57,7 +57,7 @@
junit
junit
- 4.13.1
+ 4.13.2
test
@@ -159,35 +159,17 @@
false
-
- org.moditect
- moditect-maven-plugin
- 1.0.0.Final
-
-
- add-module-infos
- package
-
- add-module-info
-
-
- 9
-
-
- org.json
-
- org.json;
-
-
-
-
-
-
-
org.apache.maven.plugins
maven-jar-plugin
3.3.0
+
+
+
+ org.json
+
+
+
diff --git a/src/main/java/org/json/JSONArray.java b/src/main/java/org/json/JSONArray.java
index 375d03888..b0c912d1f 100644
--- a/src/main/java/org/json/JSONArray.java
+++ b/src/main/java/org/json/JSONArray.java
@@ -924,30 +924,57 @@ public BigDecimal optBigDecimal(int index, BigDecimal defaultValue) {
}
/**
- * Get the optional JSONArray associated with an index.
+ * Get the optional JSONArray associated with an index. Null is returned if
+ * there is no value at that index or if the value is not a JSONArray.
*
* @param index
- * subscript
- * @return A JSONArray value, or null if the index has no value, or if the
- * value is not a JSONArray.
+ * The index must be between 0 and length() - 1.
+ * @return A JSONArray value.
*/
public JSONArray optJSONArray(int index) {
- Object o = this.opt(index);
- return o instanceof JSONArray ? (JSONArray) o : null;
+ return this.optJSONArray(index, null);
+ }
+
+ /**
+ * Get the optional JSONArray associated with an index. The defaultValue is returned if
+ * there is no value at that index or if the value is not a JSONArray.
+ *
+ * @param index
+ * The index must be between 0 and length() - 1.
+ * @param defaultValue
+ * The default.
+ * @return A JSONArray value.
+ */
+ public JSONArray optJSONArray(int index, JSONArray defaultValue) {
+ Object object = this.opt(index);
+ return object instanceof JSONArray ? (JSONArray) object : defaultValue;
}
/**
* Get the optional JSONObject associated with an index. Null is returned if
- * the key is not found, or null if the index has no value, or if the value
- * is not a JSONObject.
+ * there is no value at that index or if the value is not a JSONObject.
*
* @param index
* The index must be between 0 and length() - 1.
* @return A JSONObject value.
*/
public JSONObject optJSONObject(int index) {
- Object o = this.opt(index);
- return o instanceof JSONObject ? (JSONObject) o : null;
+ return this.optJSONObject(index, null);
+ }
+
+ /**
+ * Get the optional JSONObject associated with an index. The defaultValue is returned if
+ * there is no value at that index or if the value is not a JSONObject.
+ *
+ * @param index
+ * The index must be between 0 and length() - 1.
+ * @param defaultValue
+ * The default.
+ * @return A JSONObject value.
+ */
+ public JSONObject optJSONObject(int index, JSONObject defaultValue) {
+ Object object = this.opt(index);
+ return object instanceof JSONObject ? (JSONObject) object : defaultValue;
}
/**
@@ -1619,9 +1646,7 @@ public String toString() {
@SuppressWarnings("resource")
public String toString(int indentFactor) throws JSONException {
StringWriter sw = new StringWriter();
- synchronized (sw.getBuffer()) {
- return this.write(sw, indentFactor, 0).toString();
- }
+ return this.write(sw, indentFactor, 0).toString();
}
/**
diff --git a/src/main/java/org/json/JSONObject.java b/src/main/java/org/json/JSONObject.java
index 5e00eb9a3..fbf225e9f 100644
--- a/src/main/java/org/json/JSONObject.java
+++ b/src/main/java/org/json/JSONObject.java
@@ -208,22 +208,14 @@ public JSONObject(JSONTokener x) throws JSONException {
throw x.syntaxError("A JSONObject text must begin with '{'");
}
for (;;) {
- char prev = x.getPrevious();
c = x.nextClean();
switch (c) {
case 0:
throw x.syntaxError("A JSONObject text must end with '}'");
case '}':
return;
- case '{':
- case '[':
- if(prev=='{') {
- throw x.syntaxError("A JSON Object can not directly nest another JSON Object or JSON Array.");
- }
- // fall through
default:
- x.back();
- key = x.nextValue().toString();
+ key = x.nextSimpleValue(c).toString();
}
// The key is followed by ':'.
@@ -291,6 +283,7 @@ public JSONObject(Map, ?> m) {
}
final Object value = e.getValue();
if (value != null) {
+ testValidity(value);
this.map.put(String.valueOf(e.getKey()), wrap(value));
}
}
@@ -354,6 +347,8 @@ public JSONObject(Map, ?> m) {
* @param bean
* An object that has getter methods that should be used to make
* a JSONObject.
+ * @throws JSONException
+ * If a getter returned a non-finite number.
*/
public JSONObject(Object bean) {
this();
@@ -1512,8 +1507,22 @@ public Integer optIntegerObject(String key, Integer defaultValue) {
* @return A JSONArray which is the value.
*/
public JSONArray optJSONArray(String key) {
- Object o = this.opt(key);
- return o instanceof JSONArray ? (JSONArray) o : null;
+ return this.optJSONArray(key, null);
+ }
+
+ /**
+ * Get an optional JSONArray associated with a key, or the default if there
+ * is no such key, or if its value is not a JSONArray.
+ *
+ * @param key
+ * A key string.
+ * @param defaultValue
+ * The default.
+ * @return A JSONArray which is the value.
+ */
+ public JSONArray optJSONArray(String key, JSONArray defaultValue) {
+ Object object = this.opt(key);
+ return object instanceof JSONArray ? (JSONArray) object : defaultValue;
}
/**
@@ -1685,6 +1694,8 @@ public String optString(String key, String defaultValue) {
*
* @param bean
* the bean
+ * @throws JSONException
+ * If a getter returned a non-finite number.
*/
private void populateMap(Object bean) {
populateMap(bean, Collections.newSetFromMap(new IdentityHashMap()));
@@ -1712,21 +1723,22 @@ && isValidMethodName(method.getName())) {
final Object result = method.invoke(bean);
if (result != null) {
// check cyclic dependency and throw error if needed
- // the wrap and populateMap combination method is
+ // the wrap and populateMap combination method is
// itself DFS recursive
if (objectsRecord.contains(result)) {
throw recursivelyDefinedObjectException(key);
}
-
+
objectsRecord.add(result);
+ testValidity(result);
this.map.put(key, wrap(result, objectsRecord));
objectsRecord.remove(result);
// we don't use the result anywhere outside of wrap
// if it's a resource we should be sure to close it
- // after calling toString
+ // after calling toString
if (result instanceof Closeable) {
try {
((Closeable) result).close();
@@ -2177,13 +2189,11 @@ public Object optQuery(JSONPointer jsonPointer) {
@SuppressWarnings("resource")
public static String quote(String string) {
StringWriter sw = new StringWriter();
- synchronized (sw.getBuffer()) {
- try {
- return quote(string, sw).toString();
- } catch (IOException ignored) {
- // will never happen - we are writing to a string writer
- return "";
- }
+ try {
+ return quote(string, sw).toString();
+ } catch (IOException ignored) {
+ // will never happen - we are writing to a string writer
+ return "";
}
}
@@ -2375,14 +2385,21 @@ protected static boolean isDecimalNotation(final String val) {
* returns for this function are BigDecimal, Double, BigInteger, Long, and Integer.
* When a Double is returned, it should always be a valid Double and not NaN or +-infinity.
*
- * @param val value to convert
+ * @param input value to convert
* @return Number representation of the value.
* @throws NumberFormatException thrown if the value is not a valid number. A public
* caller should catch this and wrap it in a {@link JSONException} if applicable.
*/
- protected static Number stringToNumber(final String val) throws NumberFormatException {
+ protected 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 == '-') {
+ if ((initial >= '0' && initial <= '9') || initial == '-' ) {
// decimal representation
if (isDecimalNotation(val)) {
// Use a BigDecimal all the time so we keep the original
@@ -2399,25 +2416,26 @@ protected static Number stringToNumber(final String val) throws NumberFormatExce
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);
+ initial = val.charAt(0);
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.
@@ -2437,7 +2455,7 @@ protected static Number stringToNumber(final String val) throws NumberFormatExce
}
return bi;
}
- throw new NumberFormatException("val ["+val+"] is not a valid number.");
+ throw new NumberFormatException("val ["+input+"] is not a valid number.");
}
/**
@@ -2473,8 +2491,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) {
@@ -2483,6 +2500,28 @@ 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';
+ }
+
/**
* Throw an exception if the object is a NaN or infinite number.
*
@@ -2570,9 +2609,7 @@ public String toString() {
@SuppressWarnings("resource")
public String toString(int indentFactor) throws JSONException {
StringWriter w = new StringWriter();
- synchronized (w.getBuffer()) {
- return this.write(w, indentFactor, 0).toString();
- }
+ return this.write(w, indentFactor, 0).toString();
}
/**
@@ -2884,4 +2921,24 @@ private static JSONException recursivelyDefinedObjectException(String key) {
"JavaBean object contains recursively defined member variable of key " + quote(key)
);
}
+
+ /**
+ * For a prospective number, remove the leading zeros
+ * @param value prospective number
+ * @return number without leading zeros
+ */
+ 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/main/java/org/json/JSONTokener.java b/src/main/java/org/json/JSONTokener.java
index 5dc8ae85a..4a83a6971 100644
--- a/src/main/java/org/json/JSONTokener.java
+++ b/src/main/java/org/json/JSONTokener.java
@@ -402,12 +402,7 @@ public String nextTo(String delimiters) throws JSONException {
*/
public Object nextValue() throws JSONException {
char c = this.nextClean();
- String string;
-
switch (c) {
- case '"':
- case '\'':
- return this.nextString(c);
case '{':
this.back();
try {
@@ -423,6 +418,17 @@ public Object nextValue() throws JSONException {
throw new JSONException("JSON Array or Object depth too large to process.", e);
}
}
+ return nextSimpleValue(c);
+ }
+
+ Object nextSimpleValue(char c) {
+ String string;
+
+ switch (c) {
+ case '"':
+ case '\'':
+ return this.nextString(c);
+ }
/*
* Handle unquoted text. This could be the values true, false, or
diff --git a/src/test/java/org/json/junit/JSONArrayTest.java b/src/test/java/org/json/junit/JSONArrayTest.java
index ad938cf50..e877070d0 100644
--- a/src/test/java/org/json/junit/JSONArrayTest.java
+++ b/src/test/java/org/json/junit/JSONArrayTest.java
@@ -118,7 +118,7 @@ public void nullException() {
* Expects a JSONException.
*/
@Test
- public void emptStr() {
+ public void emptyStr() {
String str = "";
try {
assertNull("Should throw an exception", new JSONArray(str));
@@ -460,6 +460,20 @@ public void failedGetArrayValues() {
Util.checkJSONArrayMaps(jsonArray);
}
+ /**
+ * The JSON parser is permissive of unambiguous unquoted keys and values.
+ * Such JSON text should be allowed, even if it does not strictly conform
+ * to the spec. However, after being parsed, toString() should emit strictly
+ * conforming JSON text.
+ */
+ @Test
+ public void unquotedText() {
+ String str = "[value1, something!, (parens), foo@bar.com, 23, 23+45]";
+ JSONArray jsonArray = new JSONArray(str);
+ List expected = Arrays.asList("value1", "something!", "(parens)", "foo@bar.com", 23, "23+45");
+ assertEquals(expected, jsonArray.toList());
+ }
+
/**
* Exercise JSONArray.join() by converting a JSONArray into a
* comma-separated string. Since this is very nearly a JSON document,
@@ -595,13 +609,17 @@ public void opt() {
JSONArray nestedJsonArray = jsonArray.optJSONArray(9);
assertTrue("Array opt JSONArray", nestedJsonArray != null);
- assertTrue("Array opt JSONArray default",
+ assertTrue("Array opt JSONArray null",
null == jsonArray.optJSONArray(99));
+ assertTrue("Array opt JSONArray default",
+ "value".equals(jsonArray.optJSONArray(99, new JSONArray("[\"value\"]")).getString(0)));
JSONObject nestedJsonObject = jsonArray.optJSONObject(10);
assertTrue("Array opt JSONObject", nestedJsonObject != null);
- assertTrue("Array opt JSONObject default",
+ assertTrue("Array opt JSONObject null",
null == jsonArray.optJSONObject(99));
+ assertTrue("Array opt JSONObject default",
+ "value".equals(jsonArray.optJSONObject(99, new JSONObject("{\"key\":\"value\"}")).getString("key")));
assertTrue("Array opt long",
0 == jsonArray.optLong(11));
@@ -1369,7 +1387,7 @@ public void jsonArrayClearMethodTest() {
@Test(expected = JSONException.class)
public void issue654StackOverflowInputWellFormed() {
//String input = new String(java.util.Base64.getDecoder().decode(base64Bytes));
- final InputStream resourceAsStream = JSONObjectTest.class.getClassLoader().getResourceAsStream("Issue654WellFormedArray.json");
+ final InputStream resourceAsStream = JSONArrayTest.class.getClassLoader().getResourceAsStream("Issue654WellFormedArray.json");
JSONTokener tokener = new JSONTokener(resourceAsStream);
JSONArray json_input = new JSONArray(tokener);
assertNotNull(json_input);
diff --git a/src/test/java/org/json/junit/JSONObjectDecimalTest.java b/src/test/java/org/json/junit/JSONObjectDecimalTest.java
new file mode 100644
index 000000000..3302f0a24
--- /dev/null
+++ b/src/test/java/org/json/junit/JSONObjectDecimalTest.java
@@ -0,0 +1,100 @@
+package org.json.junit;
+
+import org.json.JSONObject;
+import org.junit.Test;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+import static org.junit.Assert.assertEquals;
+
+public class JSONObjectDecimalTest {
+
+ @Test
+ public void shouldParseDecimalNumberThatStartsWithDecimalPoint(){
+ JSONObject jsonObject = new JSONObject("{value:0.50}");
+ assertEquals("Float not recognized", 0.5f, jsonObject.getFloat("value"), 0.0f);
+ assertEquals("Float not recognized", 0.5f, jsonObject.optFloat("value"), 0.0f);
+ assertEquals("Float not recognized", 0.5f, jsonObject.optFloatObject("value"), 0.0f);
+ assertEquals("Double not recognized", 0.5d, jsonObject.optDouble("value"), 0.0f);
+ assertEquals("Double not recognized", 0.5d, jsonObject.optDoubleObject("value"), 0.0f);
+ assertEquals("Double not recognized", 0.5d, jsonObject.getDouble("value"), 0.0f);
+ assertEquals("Long not recognized", 0, jsonObject.optLong("value"), 0);
+ assertEquals("Long not recognized", 0, jsonObject.getLong("value"), 0);
+ assertEquals("Long not recognized", 0, jsonObject.optLongObject("value"), 0);
+ assertEquals("Integer not recognized", 0, jsonObject.optInt("value"), 0);
+ assertEquals("Integer not recognized", 0, jsonObject.getInt("value"), 0);
+ assertEquals("Integer not recognized", 0, jsonObject.optIntegerObject("value"), 0);
+ assertEquals("Number not recognized", 0, jsonObject.getNumber("value").intValue(), 0);
+ assertEquals("Number not recognized", 0, jsonObject.getNumber("value").longValue(), 0);
+ assertEquals("BigDecimal not recognized", 0, BigDecimal.valueOf(.5).compareTo(jsonObject.getBigDecimal("value")));
+ assertEquals("BigInteger not recognized",0, BigInteger.valueOf(0).compareTo(jsonObject.getBigInteger("value")));
+ }
+
+
+
+ @Test
+ public void shouldParseNegativeDecimalNumberThatStartsWithDecimalPoint(){
+ JSONObject jsonObject = new JSONObject("{value:-.50}");
+ assertEquals("Float not recognized", -0.5f, jsonObject.getFloat("value"), 0.0f);
+ assertEquals("Float not recognized", -0.5f, jsonObject.optFloat("value"), 0.0f);
+ assertEquals("Float not recognized", -0.5f, jsonObject.optFloatObject("value"), 0.0f);
+ assertEquals("Double not recognized", -0.5d, jsonObject.optDouble("value"), 0.0f);
+ assertEquals("Double not recognized", -0.5d, jsonObject.optDoubleObject("value"), 0.0f);
+ assertEquals("Double not recognized", -0.5d, jsonObject.getDouble("value"), 0.0f);
+ assertEquals("Long not recognized", 0, jsonObject.optLong("value"), 0);
+ assertEquals("Long not recognized", 0, jsonObject.getLong("value"), 0);
+ assertEquals("Long not recognized", 0, jsonObject.optLongObject("value"), 0);
+ assertEquals("Integer not recognized", 0, jsonObject.optInt("value"), 0);
+ assertEquals("Integer not recognized", 0, jsonObject.getInt("value"), 0);
+ assertEquals("Integer not recognized", 0, jsonObject.optIntegerObject("value"), 0);
+ assertEquals("Number not recognized", 0, jsonObject.getNumber("value").intValue(), 0);
+ assertEquals("Number not recognized", 0, jsonObject.getNumber("value").longValue(), 0);
+ assertEquals("BigDecimal not recognized", 0, BigDecimal.valueOf(-.5).compareTo(jsonObject.getBigDecimal("value")));
+ assertEquals("BigInteger not recognized",0, BigInteger.valueOf(0).compareTo(jsonObject.getBigInteger("value")));
+ }
+
+ @Test
+ public void shouldParseDecimalNumberThatHasZeroBeforeWithDecimalPoint(){
+ JSONObject jsonObject = new JSONObject("{value:00.050}");
+ assertEquals("Float not recognized", 0.05f, jsonObject.getFloat("value"), 0.0f);
+ assertEquals("Float not recognized", 0.05f, jsonObject.optFloat("value"), 0.0f);
+ assertEquals("Float not recognized", 0.05f, jsonObject.optFloatObject("value"), 0.0f);
+ assertEquals("Double not recognized", 0.05d, jsonObject.optDouble("value"), 0.0f);
+ assertEquals("Double not recognized", 0.05d, jsonObject.optDoubleObject("value"), 0.0f);
+ assertEquals("Double not recognized", 0.05d, jsonObject.getDouble("value"), 0.0f);
+ assertEquals("Long not recognized", 0, jsonObject.optLong("value"), 0);
+ assertEquals("Long not recognized", 0, jsonObject.getLong("value"), 0);
+ assertEquals("Long not recognized", 0, jsonObject.optLongObject("value"), 0);
+ assertEquals("Integer not recognized", 0, jsonObject.optInt("value"), 0);
+ assertEquals("Integer not recognized", 0, jsonObject.getInt("value"), 0);
+ assertEquals("Integer not recognized", 0, jsonObject.optIntegerObject("value"), 0);
+ assertEquals("Number not recognized", 0, jsonObject.getNumber("value").intValue(), 0);
+ assertEquals("Number not recognized", 0, jsonObject.getNumber("value").longValue(), 0);
+ assertEquals("BigDecimal not recognized", 0, BigDecimal.valueOf(.05).compareTo(jsonObject.getBigDecimal("value")));
+ assertEquals("BigInteger not recognized",0, BigInteger.valueOf(0).compareTo(jsonObject.getBigInteger("value")));
+ }
+
+ @Test
+ public void shouldParseNegativeDecimalNumberThatHasZeroBeforeWithDecimalPoint(){
+ JSONObject jsonObject = new JSONObject("{value:-00.050}");
+ assertEquals("Float not recognized", -0.05f, jsonObject.getFloat("value"), 0.0f);
+ assertEquals("Float not recognized", -0.05f, jsonObject.optFloat("value"), 0.0f);
+ assertEquals("Float not recognized", -0.05f, jsonObject.optFloatObject("value"), 0.0f);
+ assertEquals("Double not recognized", -0.05d, jsonObject.optDouble("value"), 0.0f);
+ assertEquals("Double not recognized", -0.05d, jsonObject.optDoubleObject("value"), 0.0f);
+ assertEquals("Double not recognized", -0.05d, jsonObject.getDouble("value"), 0.0f);
+ assertEquals("Long not recognized", 0, jsonObject.optLong("value"), 0);
+ assertEquals("Long not recognized", 0, jsonObject.getLong("value"), 0);
+ assertEquals("Long not recognized", 0, jsonObject.optLongObject("value"), 0);
+ assertEquals("Integer not recognized", 0, jsonObject.optInt("value"), 0);
+ assertEquals("Integer not recognized", 0, jsonObject.getInt("value"), 0);
+ assertEquals("Integer not recognized", 0, jsonObject.optIntegerObject("value"), 0);
+ assertEquals("Number not recognized", 0, jsonObject.getNumber("value").intValue(), 0);
+ assertEquals("Number not recognized", 0, jsonObject.getNumber("value").longValue(), 0);
+ assertEquals("BigDecimal not recognized", 0, BigDecimal.valueOf(-.05).compareTo(jsonObject.getBigDecimal("value")));
+ assertEquals("BigInteger not recognized",0, BigInteger.valueOf(0).compareTo(jsonObject.getBigInteger("value")));
+ }
+
+
+}
diff --git a/src/test/java/org/json/junit/JSONObjectNumberTest.java b/src/test/java/org/json/junit/JSONObjectNumberTest.java
index 43173a288..14e68d66b 100644
--- a/src/test/java/org/json/junit/JSONObjectNumberTest.java
+++ b/src/test/java/org/json/junit/JSONObjectNumberTest.java
@@ -23,7 +23,10 @@ public class JSONObjectNumberTest {
@Parameters(name = "{index}: {0}")
public static Collection data() {
return Arrays.asList(new Object[][]{
- {"{value:50}", 1},
+ {"{value:0050}", 1},
+ {"{value:0050.0000}", 1},
+ {"{value:-0050}", -1},
+ {"{value:-0050.0000}", -1},
{"{value:50.0}", 1},
{"{value:5e1}", 1},
{"{value:5E1}", 1},
@@ -32,6 +35,7 @@ public static Collection data() {
{"{value:-50}", -1},
{"{value:-50.0}", -1},
{"{value:-5e1}", -1},
+ {"{value:-0005e1}", -1},
{"{value:-5E1}", -1},
{"{value:-5e1}", -1},
{"{value:'-50'}", -1}
diff --git a/src/test/java/org/json/junit/JSONObjectTest.java b/src/test/java/org/json/junit/JSONObjectTest.java
index 2de8f815c..5adb6ce51 100644
--- a/src/test/java/org/json/junit/JSONObjectTest.java
+++ b/src/test/java/org/json/junit/JSONObjectTest.java
@@ -4,11 +4,13 @@
Public Domain.
*/
+import static java.lang.Double.NaN;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
@@ -205,13 +207,17 @@ public void jsonObjectByNullBean() {
*/
@Test
public void unquotedText() {
- String str = "{key1:value1, key2:42}";
+ String str = "{key1:value1, key2:42, 1.2 : 3.4, -7e5 : something!}";
JSONObject jsonObject = new JSONObject(str);
String textStr = jsonObject.toString();
assertTrue("expected key1", textStr.contains("\"key1\""));
assertTrue("expected value1", textStr.contains("\"value1\""));
assertTrue("expected key2", textStr.contains("\"key2\""));
assertTrue("expected 42", textStr.contains("42"));
+ assertTrue("expected 1.2", textStr.contains("\"1.2\""));
+ assertTrue("expected 3.4", textStr.contains("3.4"));
+ assertTrue("expected -7E+5", textStr.contains("\"-7E+5\""));
+ assertTrue("expected something!", textStr.contains("\"something!\""));
Util.checkJSONObjectMaps(jsonObject);
}
@@ -777,7 +783,7 @@ public void jsonObjectAccumulate() {
jsonObject.accumulate("myArray", -23.45e7);
// include an unsupported object for coverage
try {
- jsonObject.accumulate("myArray", Double.NaN);
+ jsonObject.accumulate("myArray", NaN);
fail("Expected exception");
} catch (JSONException ignored) {}
@@ -809,7 +815,7 @@ public void jsonObjectAppend() {
jsonObject.append("myArray", -23.45e7);
// include an unsupported object for coverage
try {
- jsonObject.append("myArray", Double.NaN);
+ jsonObject.append("myArray", NaN);
fail("Expected exception");
} catch (JSONException ignored) {}
@@ -834,7 +840,7 @@ public void jsonObjectAppend() {
public void jsonObjectDoubleToString() {
String [] expectedStrs = {"1", "1", "-23.4", "-2.345E68", "null", "null" };
Double [] doubles = { 1.0, 00001.00000, -23.4, -23.45e67,
- Double.NaN, Double.NEGATIVE_INFINITY };
+ NaN, Double.NEGATIVE_INFINITY };
for (int i = 0; i < expectedStrs.length; ++i) {
String actualStr = JSONObject.doubleToString(doubles[i]);
assertTrue("value expected ["+expectedStrs[i]+
@@ -889,11 +895,11 @@ public void jsonObjectValues() {
assertTrue("opt doubleKey should be double",
jsonObject.optDouble("doubleKey") == -23.45e7);
assertTrue("opt doubleKey with Default should be double",
- jsonObject.optDouble("doubleStrKey", Double.NaN) == 1);
+ jsonObject.optDouble("doubleStrKey", NaN) == 1);
assertTrue("opt doubleKey should be Double",
Double.valueOf(-23.45e7).equals(jsonObject.optDoubleObject("doubleKey")));
assertTrue("opt doubleKey with Default should be Double",
- Double.valueOf(1).equals(jsonObject.optDoubleObject("doubleStrKey", Double.NaN)));
+ Double.valueOf(1).equals(jsonObject.optDoubleObject("doubleStrKey", NaN)));
assertTrue("opt negZeroKey should be a Double",
jsonObject.opt("negZeroKey") instanceof Double);
assertTrue("get negZeroKey should be a Double",
@@ -1059,12 +1065,21 @@ public void jsonInvalidNumberValues() {
"\"tooManyZeros\":00,"+
"\"negativeInfinite\":-Infinity,"+
"\"negativeNaN\":-NaN,"+
+ "\"negativeNaNWithLeadingZeros\":-00NaN,"+
"\"negativeFraction\":-.01,"+
"\"tooManyZerosFraction\":00.001,"+
"\"negativeHexFloat\":-0x1.fffp1,"+
"\"hexFloat\":0x1.0P-1074,"+
"\"floatIdentifier\":0.1f,"+
- "\"doubleIdentifier\":0.1d"+
+ "\"doubleIdentifier\":0.1d,"+
+ "\"doubleIdentifierWithMultipleLeadingZerosBeforeDecimal\":0000000.1d,"+
+ "\"negativeDoubleIdentifierWithMultipleLeadingZerosBeforeDecimal\":-0000000.1d,"+
+ "\"doubleIdentifierWithMultipleLeadingZerosAfterDecimal\":0000000.0001d,"+
+ "\"negativeDoubleIdentifierWithMultipleLeadingZerosAfterDecimal\":-0000000.0001d,"+
+ "\"integerWithLeadingZeros\":000900,"+
+ "\"integerWithAllZeros\":00000,"+
+ "\"compositeWithLeadingZeros\":00800.90d,"+
+ "\"decimalPositiveWithoutNumberBeforeDecimalPoint\":.90,"+
"}";
JSONObject jsonObject = new JSONObject(str);
Object obj;
@@ -1074,17 +1089,24 @@ public void jsonInvalidNumberValues() {
assertTrue("hexNumber currently evaluates to string",
obj.equals("-0x123"));
assertTrue( "tooManyZeros currently evaluates to string",
- jsonObject.get( "tooManyZeros" ).equals("00"));
+ jsonObject.get( "tooManyZeros" ).equals(0));
obj = jsonObject.get("negativeInfinite");
assertTrue( "negativeInfinite currently evaluates to string",
obj.equals("-Infinity"));
obj = jsonObject.get("negativeNaN");
assertTrue( "negativeNaN currently evaluates to string",
obj.equals("-NaN"));
+ obj = jsonObject.get("negativeNaNWithLeadingZeros");
+ assertTrue( "negativeNaNWithLeadingZeros currently evaluates to string",
+ obj.equals("-00NaN"));
assertTrue( "negativeFraction currently evaluates to double -0.01",
jsonObject.get( "negativeFraction" ).equals(BigDecimal.valueOf(-0.01)));
assertTrue( "tooManyZerosFraction currently evaluates to double 0.001",
jsonObject.get( "tooManyZerosFraction" ).equals(BigDecimal.valueOf(0.001)));
+ assertTrue( "tooManyZerosFraction currently evaluates to double 0.001",
+ jsonObject.getLong( "tooManyZerosFraction" )==0);
+ assertTrue( "tooManyZerosFraction currently evaluates to double 0.001",
+ jsonObject.optLong( "tooManyZerosFraction" )==0);
assertTrue( "negativeHexFloat currently evaluates to double -3.99951171875",
jsonObject.get( "negativeHexFloat" ).equals(Double.valueOf(-3.99951171875)));
assertTrue("hexFloat currently evaluates to double 4.9E-324",
@@ -1093,6 +1115,53 @@ public void jsonInvalidNumberValues() {
jsonObject.get("floatIdentifier").equals(Double.valueOf(0.1)));
assertTrue("doubleIdentifier currently evaluates to double 0.1",
jsonObject.get("doubleIdentifier").equals(Double.valueOf(0.1)));
+ assertTrue("doubleIdentifierWithMultipleLeadingZerosBeforeDecimal currently evaluates to double 0.1",
+ jsonObject.get("doubleIdentifierWithMultipleLeadingZerosBeforeDecimal").equals(Double.valueOf(0.1)));
+ assertTrue("negativeDoubleIdentifierWithMultipleLeadingZerosBeforeDecimal currently evaluates to double -0.1",
+ jsonObject.get("negativeDoubleIdentifierWithMultipleLeadingZerosBeforeDecimal").equals(Double.valueOf(-0.1)));
+ assertTrue("doubleIdentifierWithMultipleLeadingZerosAfterDecimal currently evaluates to double 0.0001",
+ jsonObject.get("doubleIdentifierWithMultipleLeadingZerosAfterDecimal").equals(Double.valueOf(0.0001)));
+ assertTrue("doubleIdentifierWithMultipleLeadingZerosAfterDecimal currently evaluates to double 0.0001",
+ jsonObject.get("doubleIdentifierWithMultipleLeadingZerosAfterDecimal").equals(Double.valueOf(0.0001)));
+ assertTrue("negativeDoubleIdentifierWithMultipleLeadingZerosAfterDecimal currently evaluates to double -0.0001",
+ jsonObject.get("negativeDoubleIdentifierWithMultipleLeadingZerosAfterDecimal").equals(Double.valueOf(-0.0001)));
+ assertTrue("Integer does not evaluate to 900",
+ jsonObject.get("integerWithLeadingZeros").equals(900));
+ assertTrue("Integer does not evaluate to 900",
+ jsonObject.getInt("integerWithLeadingZeros")==900);
+ assertTrue("Integer does not evaluate to 900",
+ jsonObject.optInt("integerWithLeadingZeros")==900);
+ assertTrue("Integer does not evaluate to 0",
+ jsonObject.get("integerWithAllZeros").equals(0));
+ assertTrue("Integer does not evaluate to 0",
+ jsonObject.getInt("integerWithAllZeros")==0);
+ assertTrue("Integer does not evaluate to 0",
+ jsonObject.optInt("integerWithAllZeros")==0);
+ assertTrue("Double does not evaluate to 800.90",
+ jsonObject.get("compositeWithLeadingZeros").equals(800.90));
+ assertTrue("Double does not evaluate to 800.90",
+ jsonObject.getDouble("compositeWithLeadingZeros")==800.9d);
+ assertTrue("Integer does not evaluate to 800",
+ jsonObject.optInt("compositeWithLeadingZeros")==800);
+ assertTrue("Long does not evaluate to 800.90",
+ jsonObject.getLong("compositeWithLeadingZeros")==800);
+ assertTrue("Long does not evaluate to 800.90",
+ jsonObject.optLong("compositeWithLeadingZeros")==800);
+ assertEquals("Get long of decimalPositiveWithoutNumberBeforeDecimalPoint does not match",
+ 0.9d,jsonObject.getDouble("decimalPositiveWithoutNumberBeforeDecimalPoint"), 0.0d);
+ assertEquals("Get long of decimalPositiveWithoutNumberBeforeDecimalPoint does not match",
+ 0.9d,jsonObject.optDouble("decimalPositiveWithoutNumberBeforeDecimalPoint"), 0.0d);
+ assertEquals("Get long of decimalPositiveWithoutNumberBeforeDecimalPoint does not match",
+ 0.0d,jsonObject.optLong("decimalPositiveWithoutNumberBeforeDecimalPoint"), 0.0d);
+
+ assertEquals("Get long of doubleIdentifierWithMultipleLeadingZerosAfterDecimal does not match",
+ 0.0001d,jsonObject.getDouble("doubleIdentifierWithMultipleLeadingZerosAfterDecimal"), 0.0d);
+ assertEquals("Get long of doubleIdentifierWithMultipleLeadingZerosAfterDecimal does not match",
+ 0.0001d,jsonObject.optDouble("doubleIdentifierWithMultipleLeadingZerosAfterDecimal"), 0.0d);
+ assertEquals("Get long of doubleIdentifierWithMultipleLeadingZerosAfterDecimal does not match",
+ 0.0d, jsonObject.getLong("doubleIdentifierWithMultipleLeadingZerosAfterDecimal") , 0.0d);
+ assertEquals("Get long of doubleIdentifierWithMultipleLeadingZerosAfterDecimal does not match",
+ 0.0d,jsonObject.optLong("doubleIdentifierWithMultipleLeadingZerosAfterDecimal"), 0.0d);
Util.checkJSONObjectMaps(jsonObject);
}
@@ -1968,7 +2037,7 @@ public void jsonObjectToStringIndent() {
@Test
public void jsonObjectToStringSuppressWarningOnCastToMap() {
JSONObject jsonObject = new JSONObject();
- Map map = new HashMap();
+ Map map = new HashMap<>();
map.put("abc", "def");
jsonObject.put("key", map);
@@ -2224,6 +2293,42 @@ public void jsonObjectParsingErrors() {
"Expected a ',' or '}' at 15 [character 16 line 1]",
e.getMessage());
}
+ try {
+ // key is a nested map
+ String str = "{{\"foo\": \"bar\"}: \"baz\"}";
+ assertNull("Expected an exception",new JSONObject(str));
+ } catch (JSONException e) {
+ assertEquals("Expecting an exception message",
+ "Missing value at 1 [character 2 line 1]",
+ e.getMessage());
+ }
+ try {
+ // key is a nested array containing a map
+ String str = "{\"a\": 1, [{\"foo\": \"bar\"}]: \"baz\"}";
+ assertNull("Expected an exception",new JSONObject(str));
+ } catch (JSONException e) {
+ assertEquals("Expecting an exception message",
+ "Missing value at 9 [character 10 line 1]",
+ e.getMessage());
+ }
+ try {
+ // key contains }
+ String str = "{foo}: 2}";
+ assertNull("Expected an exception",new JSONObject(str));
+ } catch (JSONException e) {
+ assertEquals("Expecting an exception message",
+ "Expected a ':' after a key at 5 [character 6 line 1]",
+ e.getMessage());
+ }
+ try {
+ // key contains ]
+ String str = "{foo]: 2}";
+ assertNull("Expected an exception",new JSONObject(str));
+ } catch (JSONException e) {
+ assertEquals("Expecting an exception message",
+ "Expected a ':' after a key at 5 [character 6 line 1]",
+ e.getMessage());
+ }
try {
// \0 after ,
String str = "{\"myKey\":true, \0\"myOtherKey\":false}";
@@ -2287,7 +2392,7 @@ public void jsonObjectParsingErrors() {
}
try {
// test validity of invalid double
- JSONObject.testValidity(Double.NaN);
+ JSONObject.testValidity(NaN);
fail("Expected an exception");
} catch (JSONException e) {
assertTrue("", true);
@@ -2510,6 +2615,8 @@ public void jsonObjectOptDefault() {
MyEnum.VAL1.equals(jsonObject.optEnum(MyEnum.class, "myKey", MyEnum.VAL1)));
assertTrue("optJSONArray() should return null ",
null==jsonObject.optJSONArray("myKey"));
+ assertTrue("optJSONArray() should return default JSONArray",
+ "value".equals(jsonObject.optJSONArray("myKey", new JSONArray("[\"value\"]")).getString(0)));
assertTrue("optJSONObject() should return default JSONObject ",
jsonObject.optJSONObject("myKey", new JSONObject("{\"testKey\":\"testValue\"}")).getString("testKey").equals("testValue"));
assertTrue("optLong() should return default long",
@@ -2555,6 +2662,8 @@ public void jsonObjectOptNoKey() {
Integer.valueOf(42).equals(jsonObject.optIntegerObject("myKey", 42)));
assertTrue("optEnum() should return default Enum",
MyEnum.VAL1.equals(jsonObject.optEnum(MyEnum.class, "myKey", MyEnum.VAL1)));
+ assertTrue("optJSONArray() should return default JSONArray",
+ "value".equals(jsonObject.optJSONArray("myKey", new JSONArray("[\"value\"]")).getString(0)));
assertTrue("optJSONArray() should return null ",
null==jsonObject.optJSONArray("myKey"));
assertTrue("optJSONObject() should return default JSONObject ",
@@ -3239,7 +3348,7 @@ public void testSingletonEnumBean() {
@SuppressWarnings("boxing")
@Test
public void testGenericBean() {
- GenericBean bean = new GenericBean(42);
+ GenericBean bean = new GenericBean<>(42);
final JSONObject jo = new JSONObject(bean);
assertEquals(jo.keySet().toString(), 8, jo.length());
assertEquals(42, jo.get("genericValue"));
@@ -3288,6 +3397,7 @@ public void testWierdListBean() {
* Sample test case from https://github.com/stleary/JSON-java/issues/531
* which verifies that no regression in double/BigDecimal support is present.
*/
+ @Test
public void testObjectToBigDecimal() {
double value = 1412078745.01074;
Reader reader = new StringReader("[{\"value\": " + value + "}]");
@@ -3582,4 +3692,25 @@ public String toJSONString() {
.put("b", 2);
assertFalse(jo1.similar(jo3));
}
+
+ private static final Number[] NON_FINITE_NUMBERS = { Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.NaN,
+ Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY, Float.NaN };
+
+ @Test
+ public void issue713MapConstructorWithNonFiniteNumbers() {
+ for (Number nonFinite : NON_FINITE_NUMBERS) {
+ Map map = new HashMap<>();
+ map.put("a", nonFinite);
+
+ assertThrows(JSONException.class, () -> new JSONObject(map));
+ }
+ }
+
+ @Test
+ public void issue713BeanConstructorWithNonFiniteNumbers() {
+ for (Number nonFinite : NON_FINITE_NUMBERS) {
+ GenericBean bean = new GenericBean<>(nonFinite);
+ assertThrows(JSONException.class, () -> new JSONObject(bean));
+ }
+ }
}
diff --git a/src/test/java/org/json/junit/JsonNumberZeroTest.java b/src/test/java/org/json/junit/JsonNumberZeroTest.java
new file mode 100644
index 000000000..bfa4ca9d8
--- /dev/null
+++ b/src/test/java/org/json/junit/JsonNumberZeroTest.java
@@ -0,0 +1,55 @@
+package org.json.junit;
+
+import org.json.JSONObject;
+import org.junit.Test;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+import static org.junit.Assert.assertEquals;
+
+public class JsonNumberZeroTest {
+
+ @Test
+ public void shouldParseNegativeZeroValueWithMultipleZeroDigit(){
+ JSONObject jsonObject = new JSONObject("{value:-0000}");
+ assertEquals("Float not recognized", -0f, jsonObject.getFloat("value"), 0.0f);
+ assertEquals("Float not recognized", -0f, jsonObject.optFloat("value"), 0.0f);
+ assertEquals("Float not recognized", -0f, jsonObject.optFloatObject("value"), 0.0f);
+ assertEquals("Double not recognized", -0d, jsonObject.optDouble("value"), 0.0f);
+ assertEquals("Double not recognized", -0.0d, jsonObject.optDoubleObject("value"), 0.0f);
+ assertEquals("Double not recognized", -0.0d, jsonObject.getDouble("value"), 0.0f);
+ assertEquals("Long not recognized", 0, jsonObject.optLong("value"), 0);
+ assertEquals("Long not recognized", 0, jsonObject.getLong("value"), 0);
+ assertEquals("Long not recognized", 0, jsonObject.optLongObject("value"), 0);
+ assertEquals("Integer not recognized", 0, jsonObject.optInt("value"), 0);
+ assertEquals("Integer not recognized", 0, jsonObject.getInt("value"), 0);
+ assertEquals("Integer not recognized", 0, jsonObject.optIntegerObject("value"), 0);
+ assertEquals("Number not recognized", 0, jsonObject.getNumber("value").intValue(), 0);
+ assertEquals("Number not recognized", 0, jsonObject.getNumber("value").longValue(), 0);
+ assertEquals("BigDecimal not recognized", 0, BigDecimal.valueOf(-0).compareTo(jsonObject.getBigDecimal("value")));
+ assertEquals("BigInteger not recognized",0, BigInteger.valueOf(0).compareTo(jsonObject.getBigInteger("value")));
+ }
+
+ @Test
+ public void shouldParseZeroValueWithMultipleZeroDigit(){
+ JSONObject jsonObject = new JSONObject("{value:0000}");
+ assertEquals("Float not recognized", 0f, jsonObject.getFloat("value"), 0.0f);
+ assertEquals("Float not recognized", 0f, jsonObject.optFloat("value"), 0.0f);
+ assertEquals("Float not recognized", 0f, jsonObject.optFloatObject("value"), 0.0f);
+ assertEquals("Double not recognized", 0d, jsonObject.optDouble("value"), 0.0f);
+ assertEquals("Double not recognized", 0.0d, jsonObject.optDoubleObject("value"), 0.0f);
+ assertEquals("Double not recognized", 0.0d, jsonObject.getDouble("value"), 0.0f);
+ assertEquals("Long not recognized", 0, jsonObject.optLong("value"), 0);
+ assertEquals("Long not recognized", 0, jsonObject.getLong("value"), 0);
+ assertEquals("Long not recognized", 0, jsonObject.optLongObject("value"), 0);
+ assertEquals("Integer not recognized", 0, jsonObject.optInt("value"), 0);
+ assertEquals("Integer not recognized", 0, jsonObject.getInt("value"), 0);
+ assertEquals("Integer not recognized", 0, jsonObject.optIntegerObject("value"), 0);
+ assertEquals("Number not recognized", 0, jsonObject.getNumber("value").intValue(), 0);
+ assertEquals("Number not recognized", 0, jsonObject.getNumber("value").longValue(), 0);
+ assertEquals("BigDecimal not recognized", 0, BigDecimal.valueOf(-0).compareTo(jsonObject.getBigDecimal("value")));
+ assertEquals("BigInteger not recognized",0, BigInteger.valueOf(0).compareTo(jsonObject.getBigInteger("value")));
+ }
+
+}
diff --git a/src/test/java/org/json/junit/XMLTest.java b/src/test/java/org/json/junit/XMLTest.java
index e940032e0..22d6131cb 100644
--- a/src/test/java/org/json/junit/XMLTest.java
+++ b/src/test/java/org/json/junit/XMLTest.java
@@ -1223,32 +1223,18 @@ public void testIndentSimpleJsonArray(){
@Test
public void testIndentComplicatedJsonObjectWithArrayAndWithConfig(){
- try {
- InputStream jsonStream = null;
- try {
- jsonStream = XMLTest.class.getClassLoader().getResourceAsStream("Issue593.json");
- final JSONObject object = new JSONObject(new JSONTokener(jsonStream));
- String actualString = XML.toString(object, null, XMLParserConfiguration.KEEP_STRINGS,2);
- InputStream xmlStream = null;
- try {
- xmlStream = XMLTest.class.getClassLoader().getResourceAsStream("Issue593.xml");
- int bufferSize = 1024;
- char[] buffer = new char[bufferSize];
- StringBuilder expected = new StringBuilder();
- Reader in = new InputStreamReader(xmlStream, "UTF-8");
- for (int numRead; (numRead = in.read(buffer, 0, buffer.length)) > 0; ) {
- expected.append(buffer, 0, numRead);
- }
- assertEquals(expected.toString(), actualString.replaceAll("\\n|\\r\\n", System.getProperty("line.separator")));
- } finally {
- if (xmlStream != null) {
- xmlStream.close();
- }
- }
- } finally {
- if (jsonStream != null) {
- jsonStream.close();
+ try (InputStream jsonStream = XMLTest.class.getClassLoader().getResourceAsStream("Issue593.json")) {
+ final JSONObject object = new JSONObject(new JSONTokener(jsonStream));
+ String actualString = XML.toString(object, null, XMLParserConfiguration.KEEP_STRINGS, 2);
+ try (InputStream xmlStream = XMLTest.class.getClassLoader().getResourceAsStream("Issue593.xml")) {
+ int bufferSize = 1024;
+ char[] buffer = new char[bufferSize];
+ StringBuilder expected = new StringBuilder();
+ Reader in = new InputStreamReader(xmlStream, "UTF-8");
+ for (int numRead; (numRead = in.read(buffer, 0, buffer.length)) > 0; ) {
+ expected.append(buffer, 0, numRead);
}
+ assertEquals(expected.toString(), actualString);
}
} catch (IOException e) {
fail("file writer error: " +e.getMessage());
diff --git a/src/test/java/org/json/junit/data/GenericBean.java b/src/test/java/org/json/junit/data/GenericBean.java
index da6370d48..dd46b88e6 100644
--- a/src/test/java/org/json/junit/data/GenericBean.java
+++ b/src/test/java/org/json/junit/data/GenericBean.java
@@ -9,7 +9,7 @@
* @param
* generic number value
*/
-public class GenericBean> implements MyBean {
+public class GenericBean implements MyBean {
/**
* @param genericValue
* value to initiate with