diff --git a/src/main/java/org/json/JSONTokener.java b/src/main/java/org/json/JSONTokener.java index b825ee2..4d13f60 100644 --- a/src/main/java/org/json/JSONTokener.java +++ b/src/main/java/org/json/JSONTokener.java @@ -297,45 +297,48 @@ public class JSONTokener { for (;;) { c = this.next(); switch (c) { - case 0: - case '\n': - case '\r': - throw this.syntaxError("Unterminated 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': - try { - sb.append((char) Integer.parseInt(this.next(4), 16)); - } catch (NumberFormatException e) { - throw this.syntaxError("Illegal escape.", e); - } - break; - case '"': - case '\'': - case '\\': - case '/': - sb.append(c); - break; - default: - throw this.syntaxError("Illegal escape."); + 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."); + } + break; default: if (strictMode && c == '\"' && quote != c) { throw this.syntaxError(String.format( diff --git a/src/test/java/org/json/junit/JSONObjectTest.java b/src/test/java/org/json/junit/JSONObjectTest.java index fac8c53..a8b25eb 100644 --- a/src/test/java/org/json/junit/JSONObjectTest.java +++ b/src/test/java/org/json/junit/JSONObjectTest.java @@ -2193,6 +2193,60 @@ public class JSONObjectTest { } } + @Test + public void jsonObjectParseControlCharacterEOFAssertExceptionMessage(){ + char c = '\0'; + final String source = "{\"key\":\"" + c + "\"}"; + try { + JSONObject jo = new JSONObject(source); + fail("JSONException should be thrown"); + } catch (JSONException ex) { + assertEquals("Unterminated string. " + "Character with int code 0" + + " is not allowed within a quoted string. at 8 [character 9 line 1]", ex.getMessage()); + } + } + + @Test + public void jsonObjectParseControlCharacterNewLineAssertExceptionMessage(){ + char[] chars = {'\n', '\r'}; + for( char c : chars) { + final String source = "{\"key\":\"" + c + "\"}"; + try { + JSONObject jo = new JSONObject(source); + fail("JSONException should be thrown"); + } catch (JSONException ex) { + assertEquals("Unterminated string. " + "Character with int code " + (int) c + + " is not allowed within a quoted string. at 9 [character 0 line 2]", ex.getMessage()); + } + } + } + + @Test + public void jsonObjectParseUTF8EncodingAssertExceptionMessage(){ + String c = "\\u123x"; + final String source = "{\"key\":\"" + c + "\"}"; + try { + JSONObject jo = new JSONObject(source); + fail("JSONException should be thrown"); + } catch (JSONException ex) { + assertEquals("Illegal escape. \\u must be followed by a 4 digit hexadecimal number. " + + "\\123x is not valid. at 14 [character 15 line 1]", ex.getMessage()); + } + } + + @Test + public void jsonObjectParseIllegalEscapeAssertExceptionMessage(){ + String c = "\\x"; + final String source = "{\"key\":\"" + c + "\"}"; + try { + JSONObject jo = new JSONObject(source); + fail("JSONException should be thrown"); + } catch (JSONException ex) { + assertEquals("Illegal escape. Escape sequence " + c + " is not valid." + + " at 10 [character 11 line 1]", ex.getMessage()); + } + } + /** * Explore how JSONObject handles parsing errors. */ diff --git a/src/test/java/org/json/junit/JSONParserConfigurationTest.java b/src/test/java/org/json/junit/JSONParserConfigurationTest.java index 1ce289e..a1838a4 100644 --- a/src/test/java/org/json/junit/JSONParserConfigurationTest.java +++ b/src/test/java/org/json/junit/JSONParserConfigurationTest.java @@ -164,7 +164,7 @@ public class JSONParserConfigurationTest { () -> new JSONArray(testCaseTwo, jsonParserConfiguration)); assertEquals("Expected a ',' or ']' at 10 [character 11 line 1]", jeOne.getMessage()); - assertEquals("Unterminated string at 15 [character 16 line 1]", jeTwo.getMessage()); + assertEquals("Unterminated string. Character with int code 0 is not allowed within a quoted string. at 15 [character 16 line 1]", jeTwo.getMessage()); }