mirror of
https://github.com/stleary/JSON-java.git
synced 2025-08-03 03:15:32 -04:00
feat(#871-strictMode): add allowSingleQuote option, add enhancements and simplification
This commit is contained in:
parent
d2cb38dba7
commit
c0918c2428
@ -113,11 +113,7 @@ public class JSONArray implements Iterable<Object> {
|
|||||||
this.myArrayList.add(JSONObject.NULL);
|
this.myArrayList.add(JSONObject.NULL);
|
||||||
} else {
|
} else {
|
||||||
x.back();
|
x.back();
|
||||||
if (jsonParserConfiguration.isStrictMode()) {
|
this.myArrayList.add(x.nextValue(jsonParserConfiguration));
|
||||||
this.myArrayList.add(x.nextValue(true));
|
|
||||||
} else {
|
|
||||||
this.myArrayList.add(x.nextValue());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
switch (x.nextClean()) {
|
switch (x.nextClean()) {
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -225,7 +225,7 @@ public class JSONObject {
|
|||||||
case '}':
|
case '}':
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
key = x.nextSimpleValue(c, jsonParserConfiguration.isStrictMode()).toString();
|
key = x.nextSimpleValue(c, jsonParserConfiguration).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
// The key is followed by ':'.
|
// The key is followed by ':'.
|
||||||
@ -244,7 +244,7 @@ public class JSONObject {
|
|||||||
throw x.syntaxError("Duplicate key \"" + key + "\"");
|
throw x.syntaxError("Duplicate key \"" + key + "\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
Object value = getValue(x, jsonParserConfiguration.isStrictMode());
|
Object value = x.nextValue(jsonParserConfiguration);
|
||||||
// Only add value if non-null
|
// Only add value if non-null
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
this.put(key, value);
|
this.put(key, value);
|
||||||
@ -272,12 +272,6 @@ public class JSONObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object getValue(JSONTokener x, boolean strictMode) {
|
|
||||||
if (strictMode) {
|
|
||||||
return x.nextValue(true);
|
|
||||||
}
|
|
||||||
return x.nextValue();
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* Construct a JSONObject from a Map.
|
* Construct a JSONObject from a Map.
|
||||||
*
|
*
|
||||||
|
@ -25,6 +25,11 @@ public class JSONParserConfiguration extends ParserConfiguration {
|
|||||||
*/
|
*/
|
||||||
private boolean strictMode;
|
private boolean strictMode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows Single Quotes when strictMode is true. Has no effect if strictMode is false.
|
||||||
|
*/
|
||||||
|
private boolean allowSingleQuotes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration with the default values.
|
* Configuration with the default values.
|
||||||
*/
|
*/
|
||||||
@ -92,6 +97,24 @@ public class JSONParserConfiguration extends ParserConfiguration {
|
|||||||
return clone;
|
return clone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows single quotes mode configuration for JSON parser when strictMode is on.
|
||||||
|
* <p>
|
||||||
|
* If this option is set to true when strict Mode is enabled, the parser will allow single quoted fields.
|
||||||
|
* <p>
|
||||||
|
* This option is false by default.
|
||||||
|
*
|
||||||
|
* @param mode a boolean value indicating whether single quotes should be allowed or not
|
||||||
|
* @return a new JSONParserConfiguration instance with the updated strict mode setting
|
||||||
|
*/
|
||||||
|
public JSONParserConfiguration allowSingleQuotes(final boolean mode) {
|
||||||
|
JSONParserConfiguration clone = this.clone();
|
||||||
|
clone.strictMode = this.strictMode;
|
||||||
|
clone.allowSingleQuotes = mode;
|
||||||
|
|
||||||
|
return clone;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The parser's behavior when meeting duplicate keys, controls whether the parser should
|
* The parser's behavior when meeting duplicate keys, controls whether the parser should
|
||||||
* overwrite duplicate keys or not.
|
* overwrite duplicate keys or not.
|
||||||
@ -115,4 +138,14 @@ public class JSONParserConfiguration extends ParserConfiguration {
|
|||||||
public boolean isStrictMode() {
|
public boolean isStrictMode() {
|
||||||
return this.strictMode;
|
return this.strictMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the allow single quotes option.
|
||||||
|
* <p>
|
||||||
|
* Allow Single Quotes, when enabled during strict mode, instructs the parser to allow single quoted JSON fields.
|
||||||
|
* The parser will not throw a JSONException if compliant single quoted fields are found in the JSON structure.
|
||||||
|
*
|
||||||
|
* @return the current allow single quotes setting.
|
||||||
|
*/
|
||||||
|
public boolean isAllowSingleQuotes() {return this.allowSingleQuotes;}
|
||||||
}
|
}
|
||||||
|
@ -412,29 +412,29 @@ public class JSONTokener {
|
|||||||
* @throws JSONException If syntax error.
|
* @throws JSONException If syntax error.
|
||||||
*/
|
*/
|
||||||
public Object nextValue() throws JSONException {
|
public Object nextValue() throws JSONException {
|
||||||
return nextValue(false);
|
return nextValue(new JSONParserConfiguration());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the next value. The value can be a Boolean, Double, Integer, JSONArray, JSONObject, Long, or String, or the
|
* Get the next value. The value can be a Boolean, Double, Integer, JSONArray, JSONObject, Long, or String, or the
|
||||||
* JSONObject.NULL object. The strictMode parameter controls the behavior of the method when parsing the value.
|
* JSONObject.NULL object. The strictMode parameter controls the behavior of the method when parsing the value.
|
||||||
*
|
*
|
||||||
* @param strictMode If true, the method will strictly adhere to the JSON syntax, throwing a JSONException for any
|
* @param jsonParserConfiguration which carries options such as strictMode and allowSingleQuotes, these methods will
|
||||||
* deviations.
|
* strictly adhere to the JSON syntax, throwing a JSONException for any deviations.
|
||||||
* @return An object.
|
* @return An object.
|
||||||
* @throws JSONException If syntax error.
|
* @throws JSONException If syntax error.
|
||||||
*/
|
*/
|
||||||
public Object nextValue(boolean strictMode) throws JSONException {
|
public Object nextValue(JSONParserConfiguration jsonParserConfiguration) throws JSONException {
|
||||||
char c = this.nextClean();
|
char c = this.nextClean();
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case '{':
|
case '{':
|
||||||
this.back();
|
this.back();
|
||||||
return getJsonObject(strictMode);
|
return getJsonObject(jsonParserConfiguration);
|
||||||
case '[':
|
case '[':
|
||||||
this.back();
|
this.back();
|
||||||
return getJsonArray();
|
return getJsonArray();
|
||||||
default:
|
default:
|
||||||
return nextSimpleValue(c, strictMode);
|
return nextSimpleValue(c, jsonParserConfiguration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -442,18 +442,15 @@ public class JSONTokener {
|
|||||||
* This method is used to get a JSONObject from the JSONTokener. The strictMode parameter controls the behavior of
|
* This method is used to get a JSONObject from the JSONTokener. The strictMode parameter controls the behavior of
|
||||||
* the method when parsing the JSONObject.
|
* the method when parsing the JSONObject.
|
||||||
*
|
*
|
||||||
* @param strictMode If true, the method will strictly adhere to the JSON syntax, throwing a JSONException for any
|
* @param jsonParserConfiguration which carries options such as strictMode and allowSingleQuotes, these methods will
|
||||||
* deviations.
|
* strictly adhere to the JSON syntax, throwing a JSONException for any deviations.
|
||||||
|
* deviations.
|
||||||
* @return A JSONObject which is the next value in the JSONTokener.
|
* @return A JSONObject which is the next value in the JSONTokener.
|
||||||
* @throws JSONException If the JSONObject or JSONArray depth is too large to process.
|
* @throws JSONException If the JSONObject or JSONArray depth is too large to process.
|
||||||
*/
|
*/
|
||||||
private JSONObject getJsonObject(boolean strictMode) {
|
private JSONObject getJsonObject(JSONParserConfiguration jsonParserConfiguration) {
|
||||||
try {
|
try {
|
||||||
if (strictMode) {
|
return new JSONObject(this, jsonParserConfiguration);
|
||||||
return new JSONObject(this, new JSONParserConfiguration().withStrictMode(true));
|
|
||||||
}
|
|
||||||
|
|
||||||
return new JSONObject(this);
|
|
||||||
} catch (StackOverflowError e) {
|
} catch (StackOverflowError e) {
|
||||||
throw new JSONException("JSON Array or Object depth too large to process.", e);
|
throw new JSONException("JSON Array or Object depth too large to process.", e);
|
||||||
}
|
}
|
||||||
@ -473,7 +470,14 @@ public class JSONTokener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Object nextSimpleValue(char c, boolean strictMode) {
|
Object nextSimpleValue(char c, JSONParserConfiguration jsonParserConfiguration) {
|
||||||
|
boolean strictMode = jsonParserConfiguration.isStrictMode();
|
||||||
|
boolean allowSingleQuotes = jsonParserConfiguration.isAllowSingleQuotes();
|
||||||
|
|
||||||
|
if(strictMode && !allowSingleQuotes && c == '\''){
|
||||||
|
throw this.syntaxError("Single quote wrap not allowed in strict mode");
|
||||||
|
}
|
||||||
|
|
||||||
if (c == '"' || c == '\'') {
|
if (c == '"' || c == '\'') {
|
||||||
return this.nextString(c, strictMode);
|
return this.nextString(c, strictMode);
|
||||||
}
|
}
|
||||||
|
@ -118,9 +118,9 @@ public class JSONParserConfigurationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenUnbalancedQuotes_testStrictModeTrue_shouldThrowJsonExceptionWtihConcreteErrorDescription() {
|
public void givenUnbalancedQuotes_testStrictModeTrueAndAllowSingleQuotes_shouldThrowJsonExceptionWtihConcreteErrorDescription() {
|
||||||
JSONParserConfiguration jsonParserConfiguration = new JSONParserConfiguration()
|
JSONParserConfiguration jsonParserConfiguration = new JSONParserConfiguration()
|
||||||
.withStrictMode(true);
|
.withStrictMode(true).allowSingleQuotes(true);
|
||||||
|
|
||||||
String testCaseOne = "[\"abc', \"test\"]";
|
String testCaseOne = "[\"abc', \"test\"]";
|
||||||
String testCaseTwo = "['abc\", \"test\"]";
|
String testCaseTwo = "['abc\", \"test\"]";
|
||||||
@ -198,6 +198,7 @@ public class JSONParserConfigurationTest {
|
|||||||
return Arrays.asList(
|
return Arrays.asList(
|
||||||
"[1,2];[3,4]",
|
"[1,2];[3,4]",
|
||||||
"[test]",
|
"[test]",
|
||||||
|
"[{'testSingleQuote': 'testSingleQuote'}]",
|
||||||
"[1, 2,3]:[4,5]",
|
"[1, 2,3]:[4,5]",
|
||||||
"[{test: implied}]",
|
"[{test: implied}]",
|
||||||
"[{\"test\": implied}]",
|
"[{\"test\": implied}]",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user