diff --git a/src/main/java/org/json/JSONTokener.java b/src/main/java/org/json/JSONTokener.java index 0bc6dfb68..b8808bb4f 100644 --- a/src/main/java/org/json/JSONTokener.java +++ b/src/main/java/org/json/JSONTokener.java @@ -299,7 +299,8 @@ public String nextString(char quote) throws JSONException { case 0: case '\n': case '\r': - throw this.syntaxError("Unterminated string"); + throw this.syntaxError("Unterminated string. " + + "Character with int code " + (int) c + " is not allowed within a quoted string."); case '\\': c = this.next(); switch (c) { @@ -319,10 +320,12 @@ public String nextString(char quote) throws JSONException { sb.append('\r'); break; case 'u': + String next = this.next(4); try { - sb.append((char)Integer.parseInt(this.next(4), 16)); + sb.append((char)Integer.parseInt(next, 16)); } catch (NumberFormatException e) { - throw this.syntaxError("Illegal escape.", e); + throw this.syntaxError("Illegal escape. " + + "\\u must be followed by a 4 digit hexadecimal number. \\" + next + " is not valid.", e); } break; case '"': @@ -332,7 +335,7 @@ public String nextString(char quote) throws JSONException { sb.append(c); break; default: - throw this.syntaxError("Illegal escape."); + throw this.syntaxError("Illegal escape. Escape sequence \\" + c + " is not valid."); } break; default: diff --git a/src/test/java/org/json/junit/JSONObjectTest.java b/src/test/java/org/json/junit/JSONObjectTest.java index fac8c5388..a8b25eb73 100644 --- a/src/test/java/org/json/junit/JSONObjectTest.java +++ b/src/test/java/org/json/junit/JSONObjectTest.java @@ -2193,6 +2193,60 @@ public void jsonObjectParseControlCharacters(){ } } + @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. */