Skip to content

Commit 1f0729c

Browse files
Sean LearySean Leary
authored andcommitted
restore-jsonparserconfiguration: strict mode initial attempt. Still missing all JSONObject test cases and strict mode sanity check. Might be able to simplify implementation a bit more
1 parent 80b2672 commit 1f0729c

File tree

5 files changed

+679
-6
lines changed

5 files changed

+679
-6
lines changed

src/main/java/org/json/JSONArray.java

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ public class JSONArray implements Iterable<Object> {
6767
*/
6868
private final ArrayList<Object> myArrayList;
6969

70+
private JSONTokener jsonTokener;
71+
72+
private JSONParserConfiguration jsonParserConfiguration;
73+
7074
/**
7175
* Construct an empty JSONArray.
7276
*/
@@ -95,6 +99,15 @@ public JSONArray(JSONTokener x) throws JSONException {
9599
*/
96100
public JSONArray(JSONTokener x, JSONParserConfiguration jsonParserConfiguration) throws JSONException {
97101
this();
102+
103+
if (this.jsonParserConfiguration == null) {
104+
this.jsonParserConfiguration = jsonParserConfiguration;
105+
}
106+
if (this.jsonTokener == null) {
107+
this.jsonTokener = x;
108+
this.jsonTokener.setJsonParserConfiguration(this.jsonParserConfiguration);
109+
}
110+
98111
if (x.nextClean() != '[') {
99112
throw x.syntaxError("A JSONArray text must start with '['");
100113
}
@@ -125,6 +138,9 @@ public JSONArray(JSONTokener x, JSONParserConfiguration jsonParserConfiguration)
125138
throw x.syntaxError("Expected a ',' or ']'");
126139
}
127140
if (nextChar == ']') {
141+
if (jsonParserConfiguration.isStrictMode()) {
142+
throw x.syntaxError("Expected another array element");
143+
}
128144
return;
129145
}
130146
x.back();
@@ -136,7 +152,6 @@ public JSONArray(JSONTokener x, JSONParserConfiguration jsonParserConfiguration)
136152
}
137153
}
138154
}
139-
140155
}
141156

142157
/**
@@ -151,6 +166,13 @@ public JSONArray(JSONTokener x, JSONParserConfiguration jsonParserConfiguration)
151166
*/
152167
public JSONArray(String source) throws JSONException {
153168
this(source, new JSONParserConfiguration());
169+
if (this.jsonParserConfiguration.isStrictMode()) {
170+
char c = jsonTokener.nextClean();
171+
if (c != 0) {
172+
throw jsonTokener.syntaxError(String.format("invalid character '%s' found after end of array", c));
173+
174+
}
175+
}
154176
}
155177

156178
/**
@@ -166,6 +188,13 @@ public JSONArray(String source) throws JSONException {
166188
*/
167189
public JSONArray(String source, JSONParserConfiguration jsonParserConfiguration) throws JSONException {
168190
this(new JSONTokener(source), jsonParserConfiguration);
191+
if (this.jsonParserConfiguration.isStrictMode()) {
192+
char c = jsonTokener.nextClean();
193+
if (c != 0) {
194+
throw jsonTokener.syntaxError(String.format("invalid character '%s' found after end of array", c));
195+
196+
}
197+
}
169198
}
170199

171200
/**

src/main/java/org/json/JSONObject.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,10 @@ public Class<? extends Map> getMapType() {
152152
*/
153153
public static final Object NULL = new Null();
154154

155+
private JSONTokener jsonTokener;
156+
157+
private JSONParserConfiguration jsonParserConfiguration;
158+
155159
/**
156160
* Construct an empty JSONObject.
157161
*/
@@ -211,6 +215,15 @@ public JSONObject(JSONTokener x) throws JSONException {
211215
*/
212216
public JSONObject(JSONTokener x, JSONParserConfiguration jsonParserConfiguration) throws JSONException {
213217
this();
218+
219+
if (this.jsonParserConfiguration == null) {
220+
this.jsonParserConfiguration = jsonParserConfiguration;
221+
}
222+
if (this.jsonTokener == null) {
223+
this.jsonTokener = x;
224+
this.jsonTokener.setJsonParserConfiguration(this.jsonParserConfiguration);
225+
}
226+
214227
char c;
215228
String key;
216229

@@ -433,6 +446,10 @@ public JSONObject(Object object, String ... names) {
433446
*/
434447
public JSONObject(String source) throws JSONException {
435448
this(source, new JSONParserConfiguration());
449+
if (this.jsonParserConfiguration.isStrictMode() &&
450+
this.jsonTokener.nextClean() != 0) {
451+
throw new JSONException("Unparsed characters found at end of input text");
452+
}
436453
}
437454

438455
/**

src/main/java/org/json/JSONTokener.java

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ public class JSONTokener {
3232
/** the number of characters read in the previous line. */
3333
private long characterPreviousLine;
3434

35+
private JSONParserConfiguration jsonParserConfiguration;
3536

3637
/**
3738
* Construct a JSONTokener from a Reader. The caller must close the Reader.
@@ -70,6 +71,21 @@ public JSONTokener(String s) {
7071
this(new StringReader(s));
7172
}
7273

74+
/**
75+
* Getter
76+
* @return jsonParserConfiguration
77+
*/
78+
public JSONParserConfiguration getJsonParserConfiguration() {
79+
return jsonParserConfiguration;
80+
}
81+
82+
/**
83+
* Setter
84+
* @param jsonParserConfiguration new value for jsonParserConfiguration
85+
*/
86+
public void setJsonParserConfiguration(JSONParserConfiguration jsonParserConfiguration) {
87+
this.jsonParserConfiguration = jsonParserConfiguration;
88+
}
7389

7490
/**
7591
* Back up one character. This provides a sort of lookahead capability,
@@ -409,14 +425,14 @@ public Object nextValue() throws JSONException {
409425
case '{':
410426
this.back();
411427
try {
412-
return new JSONObject(this);
428+
return new JSONObject(this, jsonParserConfiguration);
413429
} catch (StackOverflowError e) {
414430
throw new JSONException("JSON Array or Object depth too large to process.", e);
415431
}
416432
case '[':
417433
this.back();
418434
try {
419-
return new JSONArray(this);
435+
return new JSONArray(this, jsonParserConfiguration);
420436
} catch (StackOverflowError e) {
421437
throw new JSONException("JSON Array or Object depth too large to process.", e);
422438
}
@@ -427,6 +443,11 @@ public Object nextValue() throws JSONException {
427443
Object nextSimpleValue(char c) {
428444
String string;
429445

446+
if (jsonParserConfiguration != null &&
447+
jsonParserConfiguration.isStrictMode() &&
448+
c == '\'') {
449+
throw this.syntaxError("Single quote wrap not allowed in strict mode");
450+
}
430451
switch (c) {
431452
case '"':
432453
case '\'':
@@ -455,7 +476,13 @@ Object nextSimpleValue(char c) {
455476
if ("".equals(string)) {
456477
throw this.syntaxError("Missing value");
457478
}
458-
return JSONObject.stringToValue(string);
479+
Object obj = JSONObject.stringToValue(string);
480+
if (jsonParserConfiguration != null &&
481+
jsonParserConfiguration.isStrictMode() &&
482+
obj instanceof String) {
483+
throw this.syntaxError(String.format("Value '%s' is not surrounded by quotes", obj));
484+
}
485+
return obj;
459486
}
460487

461488

0 commit comments

Comments
 (0)