Skip to content

Commit

Permalink
Merge pull request #888 from rikkarth/fix/887
Browse files Browse the repository at this point in the history
fix(#887): complete strictMode for JSONArray
  • Loading branch information
stleary authored May 21, 2024
2 parents 054786e + a8ab79e commit 14f7127
Show file tree
Hide file tree
Showing 12 changed files with 502 additions and 188 deletions.
117 changes: 75 additions & 42 deletions src/main/java/org/json/JSONArray.java
Original file line number Diff line number Diff line change
Expand Up @@ -96,53 +96,83 @@ public JSONArray(JSONTokener x) throws JSONException {
*/
public JSONArray(JSONTokener x, JSONParserConfiguration jsonParserConfiguration) throws JSONException {
this();
if (x.nextClean() != '[') {
char nextChar = x.nextClean();

// check first character, if not '[' throw JSONException
if (nextChar != '[') {
throw x.syntaxError("A JSONArray text must start with '['");
}

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));
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));
}
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();

if (cursor == ']') {
break;
}

x.back();

parseTokener(x, jsonParserConfiguration);
break;
case ']':
if (strictMode) {
cursor = x.nextClean();
boolean isEoF = x.end();

if (isEoF) {
break;
case ']':
if (jsonParserConfiguration.isStrictMode()) {
nextChar = x.nextClean();
if (nextChar != 0) {
throw x.syntaxError("invalid character found after end of array: " + nextChar);
}
}

return;
default:
throw x.syntaxError("Expected a ',' or ']'");
}

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);
}
}

/**
* 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()));
}
}

Expand Down Expand Up @@ -1932,6 +1962,7 @@ private void addAll(Object array, boolean wrap) throws JSONException {
private void addAll(Object array, boolean wrap, int recursionDepth) {
addAll(array, wrap, recursionDepth, new JSONParserConfiguration());
}

/**
* Add an array's elements to the JSONArray.
*`
Expand Down Expand Up @@ -1978,7 +2009,6 @@ private void addAll(Object array, boolean wrap, int recursionDepth, JSONParserCo
"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
Expand Down Expand Up @@ -2007,4 +2037,7 @@ private static JSONException wrongValueFormatException(
, cause);
}

private static String getInvalidCharErrorMsg(char cursor) {
return String.format("invalid character '%s' found after end of array", cursor);
}
}
Loading

0 comments on commit 14f7127

Please sign in to comment.