From ab1b9a345988b9d01b20654ead2d0c2b7e4240cf Mon Sep 17 00:00:00 2001 From: Sean Leary Date: Sun, 3 Nov 2024 09:49:23 -0600 Subject: [PATCH] Revert "Merge pull request #888 from rikkarth/fix/887" This reverts commit 14f71274f79ac50afb316845539f4195facc33ee, reversing changes made to 054786e300d0fc38f0cf7fc0f2db4d9b39cb6443. --- src/main/java/org/json/JSONArray.java | 119 ++++------- src/main/java/org/json/JSONTokener.java | 194 ++++++++---------- src/test/java/org/json/junit/CDLTest.java | 18 +- .../java/org/json/junit/JSONArrayTest.java | 17 +- src/test/java/org/json/junit/JSONMLTest.java | 34 +-- .../org/json/junit/JSONObjectNumberTest.java | 28 +-- .../java/org/json/junit/JSONObjectTest.java | 42 ++-- .../junit/JSONParserConfigurationTest.java | 105 +--------- .../org/json/junit/XMLConfigurationTest.java | 7 +- src/test/java/org/json/junit/XMLTest.java | 10 +- ...rayExpectedTestCaseForToJsonArrayTest.json | 91 -------- .../resources/XmlTestCaseTestToJsonArray.xml | 27 --- 12 files changed, 189 insertions(+), 503 deletions(-) delete mode 100644 src/test/resources/JSONArrayExpectedTestCaseForToJsonArrayTest.json delete mode 100644 src/test/resources/XmlTestCaseTestToJsonArray.xml diff --git a/src/main/java/org/json/JSONArray.java b/src/main/java/org/json/JSONArray.java index 3823598..ded271e 100644 --- a/src/main/java/org/json/JSONArray.java +++ b/src/main/java/org/json/JSONArray.java @@ -96,83 +96,53 @@ public class JSONArray implements Iterable { */ public JSONArray(JSONTokener x, JSONParserConfiguration jsonParserConfiguration) throws JSONException { this(); - char nextChar = x.nextClean(); - - // check first character, if not '[' throw JSONException - if (nextChar != '[') { + if (x.nextClean() != '[') { throw x.syntaxError("A JSONArray text must start with '['"); } - parseTokener(x, jsonParserConfiguration); // runs recursively - - } - - private void parseTokener(JSONTokener x, JSONParserConfiguration jsonParserConfiguration) { - boolean strictMode = jsonParserConfiguration.isStrictMode(); - - char cursor = x.nextClean(); - - switch (cursor) { - case 0: - throwErrorIfEoF(x); - break; - case ',': - cursor = x.nextClean(); - - throwErrorIfEoF(x); - - if(strictMode && cursor == ']'){ - throw x.syntaxError(getInvalidCharErrorMsg(cursor)); - } - - if (cursor == ']') { - break; - } - - x.back(); - - parseTokener(x, jsonParserConfiguration); - break; - case ']': - if (strictMode) { - cursor = x.nextClean(); - boolean isEoF = x.end(); - - if (isEoF) { - break; - } - - if (x.getArrayLevel() == 0) { - throw x.syntaxError(getInvalidCharErrorMsg(cursor)); - } - - x.back(); - } - break; - default: - x.back(); - boolean currentCharIsQuote = x.getPrevious() == '"'; - boolean quoteIsNotNextToValidChar = x.getPreviousChar() != ',' && x.getPreviousChar() != '['; - - if (strictMode && currentCharIsQuote && quoteIsNotNextToValidChar) { - throw x.syntaxError(getInvalidCharErrorMsg(cursor)); - } - - this.myArrayList.add(x.nextValue(jsonParserConfiguration)); - parseTokener(x, jsonParserConfiguration); + char nextChar = x.nextClean(); + if (nextChar == 0) { + // array is unclosed. No ']' found, instead EOF + throw x.syntaxError("Expected a ',' or ']'"); } - } + if (nextChar != ']') { + x.back(); + for (;;) { + if (x.nextClean() == ',') { + x.back(); + this.myArrayList.add(JSONObject.NULL); + } else { + x.back(); + this.myArrayList.add(x.nextValue(jsonParserConfiguration)); + } + switch (x.nextClean()) { + case 0: + // array is unclosed. No ']' found, instead EOF + throw x.syntaxError("Expected a ',' or ']'"); + case ',': + nextChar = x.nextClean(); + if (nextChar == 0) { + // array is unclosed. No ']' found, instead EOF + throw x.syntaxError("Expected a ',' or ']'"); + } + if (nextChar == ']') { + return; + } + x.back(); + break; + case ']': + if (jsonParserConfiguration.isStrictMode()) { + nextChar = x.nextClean(); + if (nextChar != 0) { + throw x.syntaxError("invalid character found after end of array: " + nextChar); + } + } - /** - * Throws JSONException if JSONTokener has reached end of file, usually when array is unclosed. No ']' found, - * instead EoF. - * - * @param x the JSONTokener being evaluated. - * @throws JSONException if JSONTokener has reached end of file. - */ - private void throwErrorIfEoF(JSONTokener x) { - if (x.end()) { - throw x.syntaxError(String.format("Expected a ',' or ']' but instead found '%s'", x.getPrevious())); + return; + default: + throw x.syntaxError("Expected a ',' or ']'"); + } + } } } @@ -1962,7 +1932,6 @@ public class JSONArray implements Iterable { private void addAll(Object array, boolean wrap, int recursionDepth) { addAll(array, wrap, recursionDepth, new JSONParserConfiguration()); } - /** * Add an array's elements to the JSONArray. *` @@ -2009,6 +1978,7 @@ public class JSONArray implements Iterable { "JSONArray initial value should be a string or collection or array."); } } + /** * Create a new JSONException in a common format for incorrect conversions. * @param idx index of the item @@ -2037,7 +2007,4 @@ public class JSONArray implements Iterable { , cause); } - private static String getInvalidCharErrorMsg(char cursor) { - return String.format("invalid character '%s' found after end of array", cursor); - } } diff --git a/src/main/java/org/json/JSONTokener.java b/src/main/java/org/json/JSONTokener.java index 63effc5..46937e1 100644 --- a/src/main/java/org/json/JSONTokener.java +++ b/src/main/java/org/json/JSONTokener.java @@ -2,8 +2,6 @@ package org.json; import java.io.*; import java.nio.charset.Charset; -import java.util.ArrayList; -import java.util.List; /* Public Domain. @@ -33,8 +31,6 @@ public class JSONTokener { private boolean usePrevious; /** the number of characters read in the previous line. */ private long characterPreviousLine; - private final List smallCharMemory; - private int arrayLevel = 0; /** @@ -53,7 +49,6 @@ public class JSONTokener { this.character = 1; this.characterPreviousLine = 0; this.line = 1; - this.smallCharMemory = new ArrayList(2); } @@ -191,46 +186,6 @@ public class JSONTokener { return this.previous; } - private void insertCharacterInCharMemory(Character c) { - boolean foundSameCharRef = checkForEqualCharRefInMicroCharMemory(c); - if(foundSameCharRef){ - return; - } - - if(smallCharMemory.size() < 2){ - smallCharMemory.add(c); - return; - } - - smallCharMemory.set(0, smallCharMemory.get(1)); - smallCharMemory.remove(1); - smallCharMemory.add(c); - } - - private boolean checkForEqualCharRefInMicroCharMemory(Character c) { - boolean isNotEmpty = !smallCharMemory.isEmpty(); - if (isNotEmpty) { - Character lastChar = smallCharMemory.get(smallCharMemory.size() - 1); - return c.compareTo(lastChar) == 0; - } - - // list is empty so there's no equal characters - return false; - } - - /** - * Retrieves the previous char from memory. - * - * @return previous char stored in memory. - */ - public char getPreviousChar() { - return smallCharMemory.get(0); - } - - public int getArrayLevel(){ - return this.arrayLevel; - } - /** * Get the last character read from the input or '\0' if nothing has been read yet. * @return the last character read from the input. @@ -308,6 +263,7 @@ public class JSONTokener { return new String(chars); } + /** * Get the next char in the string, skipping whitespace. * @throws JSONException Thrown if there is an error reading the source string. @@ -317,7 +273,6 @@ public class JSONTokener { for (;;) { char c = this.next(); if (c == 0 || c > ' ') { - insertCharacterInCharMemory(c); return c; } } @@ -325,66 +280,77 @@ public class JSONTokener { /** - * Return the characters up to the next close quote character. Backslash processing is done. The formal JSON format - * does not allow strings in single quotes, but an implementation is allowed to accept them. - * + * Return the characters up to the next close quote character. + * Backslash processing is done. The formal JSON format does not + * allow strings in single quotes, but an implementation is allowed to + * accept them. + * If strictMode is true, this implementation will not accept unbalanced quotes (e.g will not accept "test'). * @param quote The quoting character, either * " (double quote) or * ' (single quote). + * @param strictMode If true, this implementation will not accept unbalanced quotes (e.g will not accept "test'). * @return A String. * @throws JSONException Unterminated string or unbalanced quotes if strictMode == true. */ - public String nextString(char quote) throws JSONException { + public String nextString(char quote, boolean strictMode) throws JSONException { char c; StringBuilder sb = new StringBuilder(); for (;;) { c = this.next(); switch (c) { - case 0: - case '\n': - case '\r': - throw this.syntaxError("Unterminated string. " + + case 0: + case '\n': + case '\r': + throw this.syntaxError("Unterminated string. " + "Character with int code " + (int) c + " is not allowed within a quoted string."); - case '\\': - c = this.next(); - switch (c) { - case 'b': - sb.append('\b'); - break; - case 't': - sb.append('\t'); - break; - case 'n': - sb.append('\n'); - break; - case 'f': - sb.append('\f'); - break; - case 'r': - sb.append('\r'); - break; - case 'u': - String next = this.next(4); - try { - sb.append((char) Integer.parseInt(next, 16)); - } catch (NumberFormatException e) { - throw this.syntaxError("Illegal escape. " + - "\\u must be followed by a 4 digit hexadecimal number. \\" + next - + " is not valid.", - e); - } - break; - case '"': - case '\'': - case '\\': - case '/': - sb.append(c); - break; - default: - throw this.syntaxError("Illegal escape. Escape sequence \\" + c + " is not valid."); + case '\\': + c = this.next(); + switch (c) { + case 'b': + sb.append('\b'); + break; + case 't': + sb.append('\t'); + break; + case 'n': + sb.append('\n'); + break; + case 'f': + sb.append('\f'); + break; + case 'r': + sb.append('\r'); + break; + case 'u': + String next = this.next(4); + try { + sb.append((char)Integer.parseInt(next, 16)); + } catch (NumberFormatException e) { + throw this.syntaxError("Illegal escape. " + + "\\u must be followed by a 4 digit hexadecimal number. \\" + next + " is not valid.", e); } break; + case '"': + case '\'': + case '\\': + case '/': + sb.append(c); + break; default: + throw this.syntaxError("Illegal escape. Escape sequence \\" + c + " is not valid."); + } + break; + default: + if (strictMode && c == '\"' && quote != c) { + throw this.syntaxError(String.format( + "Field contains unbalanced quotes. Starts with %s but ends with double quote.", quote)); + } + + if (strictMode && c == '\'' && quote != c) { + throw this.syntaxError(String.format( + "Field contains unbalanced quotes. Starts with %s but ends with single quote.", quote)); + } + if (c == quote) { return sb.toString(); } @@ -393,6 +359,7 @@ public class JSONTokener { } } + /** * Get the text up but not including the specified character or the * end of line, whichever comes first. @@ -474,8 +441,7 @@ public class JSONTokener { case '[': this.back(); try { - this.arrayLevel++; - return new JSONArray(this, jsonParserConfiguration); + return new JSONArray(this); } catch (StackOverflowError e) { throw new JSONException("JSON Array or Object depth too large to process.", e); } @@ -516,24 +482,15 @@ public class JSONTokener { } } - /** - * Get the next simple value from the JSON input. Simple values include strings (wrapped in single or double - * quotes), numbers, booleans, and null. This method is called when the next character is not '{' or '['. - * - * @param c The starting character. - * @param jsonParserConfiguration The configuration object containing parsing options. - * @return The parsed simple value. - * @throws JSONException If there is a syntax error or the value does not adhere to the configuration rules. - */ Object nextSimpleValue(char c, JSONParserConfiguration jsonParserConfiguration) { boolean strictMode = jsonParserConfiguration.isStrictMode(); - if (strictMode && c == '\'') { + if(strictMode && c == '\''){ throw this.syntaxError("Single quote wrap not allowed in strict mode"); } if (c == '"' || c == '\'') { - return this.nextString(c); + return this.nextString(c, strictMode); } return parsedUnquotedText(c, strictMode); @@ -560,21 +517,34 @@ public class JSONTokener { String string = sb.toString().trim(); + if (strictMode) { + boolean isBooleanOrNumeric = checkIfValueIsBooleanOrNumeric(string); + + if (isBooleanOrNumeric) { + return string; + } + + throw new JSONException(String.format("Value is not surrounded by quotes: %s", string)); + } + if (string.isEmpty()) { throw this.syntaxError("Missing value"); } - - Object stringToValue = JSONObject.stringToValue(string); - - return strictMode ? getValidNumberBooleanOrNullFromObject(stringToValue) : stringToValue; + return JSONObject.stringToValue(string); } - private Object getValidNumberBooleanOrNullFromObject(Object value) { - if (value instanceof Number || value instanceof Boolean || value.equals(JSONObject.NULL)) { - return value; + private boolean checkIfValueIsBooleanOrNumeric(Object valueToValidate) { + String stringToValidate = valueToValidate.toString(); + if (stringToValidate.equals("true") || stringToValidate.equals("false")) { + return true; } - throw this.syntaxError(String.format("Value '%s' is not surrounded by quotes", value)); + try { + Double.parseDouble(stringToValidate); + return true; + } catch (NumberFormatException e) { + return false; + } } /** diff --git a/src/test/java/org/json/junit/CDLTest.java b/src/test/java/org/json/junit/CDLTest.java index 511218e..cc3da29 100644 --- a/src/test/java/org/json/junit/CDLTest.java +++ b/src/test/java/org/json/junit/CDLTest.java @@ -29,7 +29,8 @@ public class CDLTest { "1, 2, 3, 4\t, 5, 6, 7\n" + "true, false, true, true, false, false, false\n" + "0.23, 57.42, 5e27, -234.879, 2.34e5, 0.0, 9e-3\n" + - "\"va\tl1\", \"v\bal2\", \"val3\", \"val\f4\", \"val5\", \"va'l6\", val7\n"; + "\"va\tl1\", \"v\bal2\", \"val3\", \"val\f4\", \"val5\", va'l6, val7\n"; + /** * CDL.toJSONArray() adds all values as strings, with no filtering or @@ -37,12 +38,11 @@ public class CDLTest { * values all must be quoted in the cases where the JSONObject parsing * might normally convert the value into a non-string. */ - private static final String EXPECTED_LINES = - "[{\"Col 1\":\"val1\", \"Col 2\":\"val2\", \"Col 3\":\"val3\", \"Col 4\":\"val4\", \"Col 5\":\"val5\", \"Col 6\":\"val6\", \"Col 7\":\"val7\"}, " + - "{\"Col 1\":\"1\", \"Col 2\":\"2\", \"Col 3\":\"3\", \"Col 4\":\"4\", \"Col 5\":\"5\", \"Col 6\":\"6\", \"Col 7\":\"7\"}, " + - "{\"Col 1\":\"true\", \"Col 2\":\"false\", \"Col 3\":\"true\", \"Col 4\":\"true\", \"Col 5\":\"false\", \"Col 6\":\"false\", \"Col 7\":\"false\"}, " + - "{\"Col 1\":\"0.23\", \"Col 2\":\"57.42\", \"Col 3\":\"5e27\", \"Col 4\":\"-234.879\", \"Col 5\":\"2.34e5\", \"Col 6\":\"0.0\", \"Col 7\":\"9e-3\"}, " + - "{\"Col 1\":\"va\tl1\", \"Col 2\":\"v\bal2\", \"Col 3\":\"val3\", \"Col 4\":\"val\f4\", \"Col 5\":\"val5\", \"Col 6\":\"va'l6\", \"Col 7\":\"val7\"}]"; + private static final String EXPECTED_LINES = "[{Col 1:val1, Col 2:val2, Col 3:val3, Col 4:val4, Col 5:val5, Col 6:val6, Col 7:val7}, " + + "{Col 1:\"1\", Col 2:\"2\", Col 3:\"3\", Col 4:\"4\", Col 5:\"5\", Col 6:\"6\", Col 7:\"7\"}, " + + "{Col 1:\"true\", Col 2:\"false\", Col 3:\"true\", Col 4:\"true\", Col 5:\"false\", Col 6:\"false\", Col 7:\"false\"}, " + + "{Col 1:\"0.23\", Col 2:\"57.42\", Col 3:\"5e27\", Col 4:\"-234.879\", Col 5:\"2.34e5\", Col 6:\"0.0\", Col 7:\"9e-3\"}, " + + "{Col 1:\"va\tl1\", Col 2:\"v\bal2\", Col 3:val3, Col 4:\"val\f4\", Col 5:val5, Col 6:va'l6, Col 7:val7}]"; /** * Attempts to create a JSONArray from a null string. @@ -283,11 +283,11 @@ public class CDLTest { */ @Test public void jsonArrayToJSONArray() { - String nameArrayStr = "[\"Col1\", \"Col2\"]"; + String nameArrayStr = "[Col1, Col2]"; String values = "V1, V2"; JSONArray nameJSONArray = new JSONArray(nameArrayStr); JSONArray jsonArray = CDL.toJSONArray(nameJSONArray, values); - JSONArray expectedJsonArray = new JSONArray("[{\"Col1\":\"V1\",\"Col2\":\"V2\"}]"); + JSONArray expectedJsonArray = new JSONArray("[{Col1:V1,Col2:V2}]"); Util.compareActualVsExpectedJsonArrays(jsonArray, expectedJsonArray); } diff --git a/src/test/java/org/json/junit/JSONArrayTest.java b/src/test/java/org/json/junit/JSONArrayTest.java index 485d43e..fcaa8ce 100644 --- a/src/test/java/org/json/junit/JSONArrayTest.java +++ b/src/test/java/org/json/junit/JSONArrayTest.java @@ -142,7 +142,7 @@ public class JSONArrayTest { assertNull("Should throw an exception", new JSONArray("[")); } catch (JSONException e) { assertEquals("Expected an exception message", - "Expected a ',' or ']' but instead found '[' at 1 [character 2 line 1]", + "Expected a ',' or ']' at 1 [character 2 line 1]", e.getMessage()); } } @@ -157,7 +157,7 @@ public class JSONArrayTest { assertNull("Should throw an exception", new JSONArray("[\"test\"")); } catch (JSONException e) { assertEquals("Expected an exception message", - "Expected a ',' or ']' but instead found '\"' at 7 [character 8 line 1]", + "Expected a ',' or ']' at 7 [character 8 line 1]", e.getMessage()); } } @@ -172,7 +172,7 @@ public class JSONArrayTest { assertNull("Should throw an exception", new JSONArray("[\"test\",")); } catch (JSONException e) { assertEquals("Expected an exception message", - "Expected a ',' or ']' but instead found ',' at 8 [character 9 line 1]", + "Expected a ',' or ']' at 8 [character 9 line 1]", e.getMessage()); } } @@ -469,8 +469,7 @@ public class JSONArrayTest { * to the spec. However, after being parsed, toString() should emit strictly * conforming JSON text. */ - // TODO: This test will only run in non-strictMode. TBD later. - @Ignore + @Test public void unquotedText() { String str = "[value1, something!, (parens), foo@bar.com, 23, 23+45]"; JSONArray jsonArray = new JSONArray(str); @@ -686,8 +685,8 @@ public class JSONArrayTest { String jsonArrayStr = "["+ - "\"hello\","+ - "\"world\""+ + "hello,"+ + "world"+ "]"; // 2 jsonArray.put(new JSONArray(jsonArrayStr)); @@ -764,8 +763,8 @@ public class JSONArrayTest { String jsonArrayStr = "["+ - "\"hello\","+ - "\"world\""+ + "hello,"+ + "world"+ "]"; // 2 jsonArray.put(2, new JSONArray(jsonArrayStr)); diff --git a/src/test/java/org/json/junit/JSONMLTest.java b/src/test/java/org/json/junit/JSONMLTest.java index d356840..154af64 100644 --- a/src/test/java/org/json/junit/JSONMLTest.java +++ b/src/test/java/org/json/junit/JSONMLTest.java @@ -6,11 +6,6 @@ Public Domain. import static org.junit.Assert.*; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.stream.Collectors; -import java.util.stream.Stream; import org.json.*; import org.junit.Test; @@ -653,10 +648,14 @@ public class JSONMLTest { // create a JSON array from the original string and make sure it // looks as expected JSONArray jsonArray = JSONML.toJSONArray(xmlStr); + JSONArray expectedJsonArray = new JSONArray(expectedJSONArrayStr); + Util.compareActualVsExpectedJsonArrays(jsonArray,expectedJsonArray); // restore the XML, then make another JSONArray and make sure it // looks as expected String jsonArrayXmlToStr = JSONML.toString(jsonArray); + JSONArray finalJsonArray = JSONML.toJSONArray(jsonArrayXmlToStr); + Util.compareActualVsExpectedJsonArrays(finalJsonArray, expectedJsonArray); // lastly, confirm the restored JSONObject XML and JSONArray XML look // reasonably similar @@ -665,31 +664,6 @@ public class JSONMLTest { Util.compareActualVsExpectedJsonObjects(jsonObjectFromObject, jsonObjectFromArray); } - @Test - public void givenXmlStr_testToJSONArray_shouldEqualExpectedArray() throws IOException { - try (Stream jsonLines = Files.lines( - Paths.get("src/test/resources/JSONArrayExpectedTestCaseForToJsonArrayTest.json")); - Stream xmlLines = Files.lines(Paths.get("src/test/resources/XmlTestCaseTestToJsonArray.xml"))) { - - String xmlStr = xmlLines.collect(Collectors.joining()); - String expectedJSONArrayStr = jsonLines.collect(Collectors.joining()); - - JSONArray jsonArray = JSONML.toJSONArray(xmlStr); - JSONArray expectedJsonArray = new JSONArray(expectedJSONArrayStr); - - assertEquals(expectedJsonArray.toString(), jsonArray.toString()); - //TODO Util.compareActualVsExpectedJsonArrays can be replaced with above assertEquals(expectedJsonArray.toString(), jsonArray.toString()) - Util.compareActualVsExpectedJsonArrays(jsonArray, expectedJsonArray); - - String jsonArrayXmlToStr = JSONML.toString(jsonArray); - - JSONArray finalJsonArray = JSONML.toJSONArray(jsonArrayXmlToStr); - - //TODO Util.compareActualVsExpectedJsonArrays can be replaced with assertEquals(expectedJsonArray.toString(), finalJsonArray.toString()) - Util.compareActualVsExpectedJsonArrays(finalJsonArray, expectedJsonArray); - } - } - /** * Convert an XML document which contains embedded comments into * a JSONArray. Use JSONML.toString() to turn it into a string, then diff --git a/src/test/java/org/json/junit/JSONObjectNumberTest.java b/src/test/java/org/json/junit/JSONObjectNumberTest.java index 739de83..43173a2 100644 --- a/src/test/java/org/json/junit/JSONObjectNumberTest.java +++ b/src/test/java/org/json/junit/JSONObjectNumberTest.java @@ -23,22 +23,22 @@ public class JSONObjectNumberTest { @Parameters(name = "{index}: {0}") public static Collection data() { return Arrays.asList(new Object[][]{ - {"{\"value\":50}", 1}, - {"{\"value\":50.0}", 1}, - {"{\"value\":5e1}", 1}, - {"{\"value\":5E1}", 1}, - {"{\"value\":5e1}", 1}, - {"{\"value\":\"50\"}", 1}, - {"{\"value\":-50}", -1}, - {"{\"value\":-50.0}", -1}, - {"{\"value\":-5e1}", -1}, - {"{\"value\":-5E1}", -1}, - {"{\"value\":-5e1}", -1}, - {"{\"value\":\"-50\"}", -1} + {"{value:50}", 1}, + {"{value:50.0}", 1}, + {"{value:5e1}", 1}, + {"{value:5E1}", 1}, + {"{value:5e1}", 1}, + {"{value:'50'}", 1}, + {"{value:-50}", -1}, + {"{value:-50.0}", -1}, + {"{value:-5e1}", -1}, + {"{value:-5E1}", -1}, + {"{value:-5e1}", -1}, + {"{value:'-50'}", -1} // JSON does not support octal or hex numbers; // see https://stackoverflow.com/a/52671839/6323312 - // "{\"value\":062}", // octal 50 - // "{\"value\":0x32}" // hex 50 + // "{value:062}", // octal 50 + // "{value:0x32}" // hex 50 }); } diff --git a/src/test/java/org/json/junit/JSONObjectTest.java b/src/test/java/org/json/junit/JSONObjectTest.java index d32a2db..fbad313 100644 --- a/src/test/java/org/json/junit/JSONObjectTest.java +++ b/src/test/java/org/json/junit/JSONObjectTest.java @@ -216,8 +216,7 @@ public class JSONObjectTest { * to the spec. However, after being parsed, toString() should emit strictly * conforming JSON text. */ - // TODO: This test will only run in non-strictMode. TBD later. - @Ignore + @Test public void unquotedText() { String str = "{key1:value1, key2:42, 1.2 : 3.4, -7e5 : something!}"; JSONObject jsonObject = new JSONObject(str); @@ -1068,8 +1067,7 @@ public class JSONObjectTest { /** * This test documents how JSON-Java handles invalid numeric input. */ - // TODO: to be restored after strictMode parsing is fixed - @Ignore + @Test public void jsonInvalidNumberValues() { // Number-notations supported by Java and invalid as JSON String str = @@ -2262,7 +2260,7 @@ public class JSONObjectTest { * Explore how JSONObject handles parsing errors. */ @SuppressWarnings({"boxing", "unused"}) - @Ignore + @Test public void jsonObjectParsingErrors() { try { // does not start with '{' @@ -2324,7 +2322,7 @@ public class JSONObjectTest { assertNull("Expected an exception",new JSONObject(str)); } catch (JSONException e) { assertEquals("Expecting an exception message", - "Value 'foo' is not surrounded by quotes at 4 [character 5] line 1]", + "Expected a ':' after a key at 5 [character 6 line 1]", e.getMessage()); } try { @@ -3817,33 +3815,27 @@ public class JSONObjectTest { // Behavior documented in #826 JSONObject parsing 0-led numeric strings as ints // After reverting the code, personId is stored as a string, and the behavior is as expected - String personId = "\"0123\""; - JSONObject j1 = new JSONObject("{\"personId\": " + personId + "}"); + String personId = "0123"; + JSONObject j1 = new JSONObject("{personId: " + personId + "}"); assertEquals(j1.getString("personId"), "0123"); // Also #826. Here is input with missing quotes. Because of the leading zero, it should not be parsed as a number. // This example was mentioned in the same ticket // After reverting the code, personId is stored as a string, and the behavior is as expected - - // TODO: the next two tests fail due to an ambiguity in parsing the value. - // non-StrictMode - it is a valid non-numeric value - // strictMode - Since it is non-numeric, quotes are required. - // This test should be extracted to its own unit test. The result should depend on the strictMode setting. - // For now it s commented out -// JSONObject j2 = new JSONObject("{\"personId\":0123}"); -// assertEquals(j2.getString("personId"), "0123"); + JSONObject j2 = new JSONObject("{\"personId\":0123}"); + assertEquals(j2.getString("personId"), "0123"); // Behavior uncovered while working on the code // All of the values are stored as strings except for hex4, which is stored as a number. This is probably incorrect -// JSONObject j3 = new JSONObject("{ " + -// "\"hex1\": \"010e4\", \"hex2\": \"00f0\", \"hex3\": \"0011\", " + -// "\"hex4\": 00e0, \"hex5\": 00f0, \"hex6\": 0011 }"); -// assertEquals(j3.getString("hex1"), "010e4"); -// assertEquals(j3.getString("hex2"), "00f0"); -// assertEquals(j3.getString("hex3"), "0011"); -// assertEquals(j3.getLong("hex4"), 0, .1); -// assertEquals(j3.getString("hex5"), "00f0"); -// assertEquals(j3.getString("hex6"), "0011"); + JSONObject j3 = new JSONObject("{ " + + "\"hex1\": \"010e4\", \"hex2\": \"00f0\", \"hex3\": \"0011\", " + + "\"hex4\": 00e0, \"hex5\": 00f0, \"hex6\": 0011 }"); + assertEquals(j3.getString("hex1"), "010e4"); + assertEquals(j3.getString("hex2"), "00f0"); + assertEquals(j3.getString("hex3"), "0011"); + assertEquals(j3.getLong("hex4"), 0, .1); + assertEquals(j3.getString("hex5"), "00f0"); + assertEquals(j3.getString("hex6"), "0011"); } /** diff --git a/src/test/java/org/json/junit/JSONParserConfigurationTest.java b/src/test/java/org/json/junit/JSONParserConfigurationTest.java index 427aad4..a1838a4 100644 --- a/src/test/java/org/json/junit/JSONParserConfigurationTest.java +++ b/src/test/java/org/json/junit/JSONParserConfigurationTest.java @@ -46,85 +46,6 @@ public class JSONParserConfigurationTest { () -> new JSONArray(testCase, jsonParserConfiguration))); } - @Test - public void givenEmptyArray_testStrictModeTrue_shouldNotThrowJsonException() { - JSONParserConfiguration jsonParserConfiguration = new JSONParserConfiguration() - .withStrictMode(true); - - String testCase = "[]"; - - JSONArray jsonArray = new JSONArray(testCase, jsonParserConfiguration); - - assertEquals(testCase, jsonArray.toString()); - } - - @Test - public void givenValidDoubleArray_testStrictModeTrue_shouldNotThrowJsonException() { - JSONParserConfiguration jsonParserConfiguration = new JSONParserConfiguration() - .withStrictMode(true); - - String testCase = "[[\"c\"], [10.2], [true, false, true]]"; - - JSONArray jsonArray = new JSONArray(testCase, jsonParserConfiguration); - JSONArray arrayShouldContainStringAt0 = jsonArray.getJSONArray(0); - JSONArray arrayShouldContainNumberAt0 = jsonArray.getJSONArray(1); - JSONArray arrayShouldContainBooleanAt0 = jsonArray.getJSONArray(2); - - assertTrue(arrayShouldContainStringAt0.get(0) instanceof String); - assertTrue(arrayShouldContainNumberAt0.get(0) instanceof Number); - assertTrue(arrayShouldContainBooleanAt0.get(0) instanceof Boolean); - } - - @Test - public void givenValidEmptyArrayInsideArray_testStrictModeTrue_shouldNotThrowJsonException(){ - JSONParserConfiguration jsonParserConfiguration = new JSONParserConfiguration() - .withStrictMode(true); - - String testCase = "[[]]"; - - JSONArray jsonArray = new JSONArray(testCase, jsonParserConfiguration); - - assertEquals(testCase, jsonArray.toString()); - } - - @Test - public void givenValidEmptyArrayInsideArray_testStrictModeFalse_shouldNotThrowJsonException(){ - JSONParserConfiguration jsonParserConfiguration = new JSONParserConfiguration() - .withStrictMode(false); - - String testCase = "[[]]"; - - JSONArray jsonArray = new JSONArray(testCase, jsonParserConfiguration); - - assertEquals(testCase, jsonArray.toString()); - } - - @Test - public void givenInvalidString_testStrictModeTrue_shouldThrowJsonException() { - JSONParserConfiguration jsonParserConfiguration = new JSONParserConfiguration() - .withStrictMode(true); - - String testCase = "[badString]"; - - JSONException je = assertThrows(JSONException.class, () -> new JSONArray(testCase, jsonParserConfiguration)); - - assertEquals("Value 'badString' is not surrounded by quotes at 10 [character 11 line 1]", je.getMessage()); - } - - @Test - public void allowNullInStrictMode() { - String expected = "[null]"; - JSONArray jsonArray = new JSONArray(expected, new JSONParserConfiguration().withStrictMode(true)); - assertEquals(expected, jsonArray.toString()); - } - - @Test - public void shouldHandleNumericArray() { - String expected = "[10]"; - JSONArray jsonArray = new JSONArray(expected, new JSONParserConfiguration().withStrictMode(true)); - assertEquals(expected, jsonArray.toString()); - } - @Test public void givenCompliantJSONArrayFile_testStrictModeTrue_shouldNotThrowAnyException() throws IOException { try (Stream lines = Files.lines(Paths.get("src/test/resources/compliantJsonArray.json"))) { @@ -157,7 +78,7 @@ public class JSONParserConfigurationTest { JSONException je = assertThrows("expected non-compliant array but got instead: " + testCase, JSONException.class, () -> new JSONArray(testCase, jsonParserConfiguration)); - assertEquals("invalid character ';' found after end of array at 6 [character 7 line 1]", je.getMessage()); + assertEquals("invalid character found after end of array: ; at 6 [character 7 line 1]", je.getMessage()); } @Test @@ -170,7 +91,7 @@ public class JSONParserConfigurationTest { JSONException je = assertThrows("expected non-compliant array but got instead: " + testCase, JSONException.class, () -> new JSONArray(testCase, jsonParserConfiguration)); - assertEquals("invalid character ';' found after end of array at 10 [character 11 line 1]", je.getMessage()); + assertEquals("invalid character found after end of array: ; at 10 [character 11 line 1]", je.getMessage()); } @Test @@ -183,7 +104,7 @@ public class JSONParserConfigurationTest { JSONException je = assertThrows("expected non-compliant array but got instead: " + testCase, JSONException.class, () -> new JSONArray(testCase, jsonParserConfiguration)); - assertEquals("Value 'implied' is not surrounded by quotes at 17 [character 18 line 1]", je.getMessage()); + assertEquals("Value is not surrounded by quotes: implied", je.getMessage()); } @Test @@ -216,7 +137,7 @@ public class JSONParserConfigurationTest { () -> new JSONArray(testCaseFour, jsonParserConfiguration)); assertEquals( - "Value 'test' is not surrounded by quotes at 13 [character 14 line 1]", + "Field contains unbalanced quotes. Starts with \" but ends with single quote. at 6 [character 7 line 1]", jeOne.getMessage()); assertEquals( "Single quote wrap not allowed in strict mode at 2 [character 3 line 1]", @@ -242,7 +163,7 @@ public class JSONParserConfigurationTest { JSONException jeTwo = assertThrows(JSONException.class, () -> new JSONArray(testCaseTwo, jsonParserConfiguration)); - assertEquals("Unterminated string. Character with int code 0 is not allowed within a quoted string. at 15 [character 16 line 1]", jeOne.getMessage()); + assertEquals("Expected a ',' or ']' at 10 [character 11 line 1]", jeOne.getMessage()); assertEquals("Unterminated string. Character with int code 0 is not allowed within a quoted string. at 15 [character 16 line 1]", jeTwo.getMessage()); } @@ -256,7 +177,7 @@ public class JSONParserConfigurationTest { JSONException je = assertThrows("expected non-compliant array but got instead: " + testCase, JSONException.class, () -> new JSONArray(testCase, jsonParserConfiguration)); - assertEquals("Value 'test' is not surrounded by quotes at 6 [character 7 line 1]", je.getMessage()); + assertEquals(String.format("Value is not surrounded by quotes: %s", "test"), je.getMessage()); } @Test @@ -287,20 +208,6 @@ public class JSONParserConfigurationTest { */ private List getNonCompliantJSONList() { return Arrays.asList( - "[1],", - "[1,]", - "[[1]\"sa\",[2]]a", - "[1],\"dsa\": \"test\"", - "[[a]]", - "[]asdf", - "[]]", - "[]}", - "[][", - "[]{", - "[],", - "[]:", - "[],[", - "[],{", "[1,2];[3,4]", "[test]", "[{'testSingleQuote': 'testSingleQuote'}]", diff --git a/src/test/java/org/json/junit/XMLConfigurationTest.java b/src/test/java/org/json/junit/XMLConfigurationTest.java index 92a109a..e9714af 100755 --- a/src/test/java/org/json/junit/XMLConfigurationTest.java +++ b/src/test/java/org/json/junit/XMLConfigurationTest.java @@ -268,14 +268,11 @@ public class XMLConfigurationTest { " \n"+ ""; - // TODO: This test failed in strictMode due to -23x.45 not being surrounded by quotes - // It should probably be split into two tests, one of which does not run in strictMode. - // TBD. String expectedStr = "{\"addresses\":{\"address\":{\"street\":\"[CDATA[Baker street 5]\","+ - "\"name\":\"Joe Tester\",\"NothingHere\":\"\",\"TrueValue\":true,\n"+ + "\"name\":\"Joe Tester\",\"NothingHere\":\"\",TrueValue:true,\n"+ "\"FalseValue\":false,\"NullValue\":null,\"PositiveValue\":42,\n"+ - "\"NegativeValue\":-23,\"DoubleValue\":-23.45,\"Nan\":\"-23x.45\",\n"+ + "\"NegativeValue\":-23,\"DoubleValue\":-23.45,\"Nan\":-23x.45,\n"+ "\"ArrayOfNum\":\"1, 2, 3, 4.1, 5.2\"\n"+ "},\"xsi:noNamespaceSchemaLocation\":"+ "\"test.xsd\",\"xmlns:xsi\":\"http://www.w3.org/2001/"+ diff --git a/src/test/java/org/json/junit/XMLTest.java b/src/test/java/org/json/junit/XMLTest.java index be47864..3b26b22 100644 --- a/src/test/java/org/json/junit/XMLTest.java +++ b/src/test/java/org/json/junit/XMLTest.java @@ -265,13 +265,11 @@ public class XMLTest { " \n"+ ""; - // TODO: fails in strict mode because -23x.45 was not surrounded by quotes. - // Should be split into a strictMode test, and a similar non-strictMode test String expectedStr = "{\"addresses\":{\"address\":{\"street\":\"[CDATA[Baker street 5]\","+ - "\"name\":\"Joe Tester\",\"NothingHere\":\"\",\"TrueValue\":true,\n"+ + "\"name\":\"Joe Tester\",\"NothingHere\":\"\",TrueValue:true,\n"+ "\"FalseValue\":false,\"NullValue\":null,\"PositiveValue\":42,\n"+ - "\"NegativeValue\":-23,\"DoubleValue\":-23.45,\"Nan\":\"-23x.45\",\n"+ + "\"NegativeValue\":-23,\"DoubleValue\":-23.45,\"Nan\":-23x.45,\n"+ "\"ArrayOfNum\":\"1, 2, 3, 4.1, 5.2\"\n"+ "},\"xsi:noNamespaceSchemaLocation\":"+ "\"test.xsd\",\"xmlns:xsi\":\"http://www.w3.org/2001/"+ @@ -1182,7 +1180,7 @@ public class XMLTest { @Test public void shouldCreateExplicitEndTagWithEmptyValueWhenConfigured(){ - String jsonString = "{\"outer\":{\"innerOne\":\"\", \"innerTwo\":\"two\"}}"; + String jsonString = "{outer:{innerOne:\"\", innerTwo:\"two\"}}"; JSONObject jsonObject = new JSONObject(jsonString); String expectedXmlString = "two"; String xmlForm = XML.toString(jsonObject,"encloser", new XMLParserConfiguration().withCloseEmptyTag(true)); @@ -1193,7 +1191,7 @@ public class XMLTest { @Test public void shouldNotCreateExplicitEndTagWithEmptyValueWhenNotConfigured(){ - String jsonString = "{\"outer\":{\"innerOne\":\"\", \"innerTwo\":\"two\"}}"; + String jsonString = "{outer:{innerOne:\"\", innerTwo:\"two\"}}"; JSONObject jsonObject = new JSONObject(jsonString); String expectedXmlString = "two"; String xmlForm = XML.toString(jsonObject,"encloser", new XMLParserConfiguration().withCloseEmptyTag(false)); diff --git a/src/test/resources/JSONArrayExpectedTestCaseForToJsonArrayTest.json b/src/test/resources/JSONArrayExpectedTestCaseForToJsonArrayTest.json deleted file mode 100644 index 6ce0864..0000000 --- a/src/test/resources/JSONArrayExpectedTestCaseForToJsonArrayTest.json +++ /dev/null @@ -1,91 +0,0 @@ -[ - "addresses", - { - "xsi:noNamespaceSchemaLocation": "test.xsd", - "xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance" - }, - [ - "address", - { - "addrType": "my address" - }, - [ - "name", - { - "nameType": "my name" - }, - "Joe Tester" - ], - [ - "street", - "Baker street 5" - ], - [ - "NothingHere", - { - "except": "an attribute" - } - ], - [ - "TrueValue", - true - ], - [ - "FalseValue", - false - ], - [ - "NullValue", - null - ], - [ - "PositiveValue", - 42 - ], - [ - "NegativeValue", - -23 - ], - [ - "DoubleValue", - -23.45 - ], - [ - "Nan", - "-23x.45" - ], - [ - "ArrayOfNum", - [ - "value", - 1 - ], - [ - "value", - 2 - ], - [ - "value", - [ - "subValue", - { - "svAttr": "svValue" - }, - "abc" - ] - ], - [ - "value", - 3 - ], - [ - "value", - 4.1 - ], - [ - "value", - 5.2 - ] - ] - ] -] diff --git a/src/test/resources/XmlTestCaseTestToJsonArray.xml b/src/test/resources/XmlTestCaseTestToJsonArray.xml deleted file mode 100644 index dfcf9d9..0000000 --- a/src/test/resources/XmlTestCaseTestToJsonArray.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - -
- Joe Tester - - - true - false - null - 42 - -23 - -23.45 - -23x.45 - - 1 - 2 - - abc - - 3 - 4.1 - 5.2 - -
-
\ No newline at end of file