diff --git a/src/main/java/org/json/JSONMLParserConfiguration.java b/src/main/java/org/json/JSONMLParserConfiguration.java
index b7162bf..b2514ab 100644
--- a/src/main/java/org/json/JSONMLParserConfiguration.java
+++ b/src/main/java/org/json/JSONMLParserConfiguration.java
@@ -7,17 +7,12 @@ Public Domain.
* Configuration object for the XML to JSONML parser. The configuration is immutable.
*/
@SuppressWarnings({""})
-public class JSONMLParserConfiguration {
- /**
- * Used to indicate there's no defined limit to the maximum nesting depth when parsing a XML
- * document to JSONML.
- */
- public static final int UNDEFINED_MAXIMUM_NESTING_DEPTH = -1;
+public class JSONMLParserConfiguration extends ParserConfiguration {
/**
- * The default maximum nesting depth when parsing a XML document to JSONML.
+ * We can override the default maximum nesting depth if needed.
*/
- public static final int DEFAULT_MAXIMUM_NESTING_DEPTH = 512;
+ public static final int DEFAULT_MAXIMUM_NESTING_DEPTH = ParserConfiguration.DEFAULT_MAXIMUM_NESTING_DEPTH;
/** Original Configuration of the XML to JSONML Parser. */
public static final JSONMLParserConfiguration ORIGINAL
@@ -26,22 +21,12 @@ public class JSONMLParserConfiguration {
public static final JSONMLParserConfiguration KEEP_STRINGS
= new JSONMLParserConfiguration().withKeepStrings(true);
- /**
- * When parsing the XML into JSONML, specifies if values should be kept as strings (true
), or if
- * they should try to be guessed into JSON values (numeric, boolean, string)
- */
- private boolean keepStrings;
-
- /**
- * The maximum nesting depth when parsing a XML document to JSONML.
- */
- private int maxNestingDepth = DEFAULT_MAXIMUM_NESTING_DEPTH;
-
/**
* Default parser configuration. Does not keep strings (tries to implicitly convert values).
*/
public JSONMLParserConfiguration() {
- this.keepStrings = false;
+ super();
+ this.maxNestingDepth = DEFAULT_MAXIMUM_NESTING_DEPTH;
}
/**
@@ -50,9 +35,8 @@ public class JSONMLParserConfiguration {
* false
to try and convert XML string values into a JSON value.
* @param maxNestingDepth int
to limit the nesting depth
*/
- private JSONMLParserConfiguration(final boolean keepStrings, final int maxNestingDepth) {
- this.keepStrings = keepStrings;
- this.maxNestingDepth = maxNestingDepth;
+ protected JSONMLParserConfiguration(final boolean keepStrings, final int maxNestingDepth) {
+ super(keepStrings, maxNestingDepth);
}
/**
@@ -71,58 +55,13 @@ public class JSONMLParserConfiguration {
);
}
- /**
- * When parsing the XML into JSONML, specifies if values should be kept as strings (true
), or if
- * they should try to be guessed into JSON values (numeric, boolean, string)
- *
- * @return The keepStrings
configuration value.
- */
- public boolean isKeepStrings() {
- return this.keepStrings;
- }
-
- /**
- * When parsing the XML into JSONML, specifies if values should be kept as strings (true
), or if
- * they should try to be guessed into JSON values (numeric, boolean, string)
- *
- * @param newVal
- * new value to use for the keepStrings
configuration option.
- *
- * @return The existing configuration will not be modified. A new configuration is returned.
- */
+ @Override
public JSONMLParserConfiguration withKeepStrings(final boolean newVal) {
- JSONMLParserConfiguration newConfig = this.clone();
- newConfig.keepStrings = newVal;
- return newConfig;
+ return super.withKeepStrings(newVal);
}
- /**
- * The maximum nesting depth that the parser will descend before throwing an exception
- * when parsing the XML into JSONML.
- * @return the maximum nesting depth set for this configuration
- */
- public int getMaxNestingDepth() {
- return maxNestingDepth;
- }
-
- /**
- * Defines the maximum nesting depth that the parser will descend before throwing an exception
- * when parsing the XML into JSONML. The default max nesting depth is 512, which means the parser
- * will throw a JsonException if the maximum depth is reached.
- * Using any negative value as a parameter is equivalent to setting no limit to the nesting depth,
- * which means the parses will go as deep as the maximum call stack size allows.
- * @param maxNestingDepth the maximum nesting depth allowed to the XML parser
- * @return The existing configuration will not be modified. A new configuration is returned.
- */
+ @Override
public JSONMLParserConfiguration withMaxNestingDepth(int maxNestingDepth) {
- JSONMLParserConfiguration newConfig = this.clone();
-
- if (maxNestingDepth > UNDEFINED_MAXIMUM_NESTING_DEPTH) {
- newConfig.maxNestingDepth = maxNestingDepth;
- } else {
- newConfig.maxNestingDepth = UNDEFINED_MAXIMUM_NESTING_DEPTH;
- }
-
- return newConfig;
+ return super.withMaxNestingDepth(maxNestingDepth);
}
}
diff --git a/src/main/java/org/json/ParserConfiguration.java b/src/main/java/org/json/ParserConfiguration.java
new file mode 100644
index 0000000..519e209
--- /dev/null
+++ b/src/main/java/org/json/ParserConfiguration.java
@@ -0,0 +1,112 @@
+package org.json;
+/*
+Public Domain.
+*/
+
+/**
+ * Configuration base object for parsers. The configuration is immutable.
+ */
+@SuppressWarnings({""})
+public class ParserConfiguration {
+ /**
+ * Used to indicate there's no defined limit to the maximum nesting depth when parsing a document.
+ */
+ public static final int UNDEFINED_MAXIMUM_NESTING_DEPTH = -1;
+
+ /**
+ * The default maximum nesting depth when parsing a document.
+ */
+ public static final int DEFAULT_MAXIMUM_NESTING_DEPTH = 512;
+
+ /**
+ * Specifies if values should be kept as strings (true
), or if
+ * they should try to be guessed into JSON values (numeric, boolean, string)
+ */
+ protected boolean keepStrings;
+
+ /**
+ * The maximum nesting depth when parsing a document.
+ */
+ protected int maxNestingDepth;
+
+ public ParserConfiguration() {
+ this.keepStrings = false;
+ this.maxNestingDepth = DEFAULT_MAXIMUM_NESTING_DEPTH;
+ }
+
+ protected ParserConfiguration(final boolean keepStrings, final int maxNestingDepth) {
+ this.keepStrings = keepStrings;
+ this.maxNestingDepth = maxNestingDepth;
+ }
+
+ /**
+ * Provides a new instance of the same configuration.
+ */
+ @Override
+ protected ParserConfiguration clone() {
+ // future modifications to this method should always ensure a "deep"
+ // clone in the case of collections. i.e. if a Map is added as a configuration
+ // item, a new map instance should be created and if possible each value in the
+ // map should be cloned as well. If the values of the map are known to also
+ // be immutable, then a shallow clone of the map is acceptable.
+ return new ParserConfiguration(
+ this.keepStrings,
+ this.maxNestingDepth
+ );
+ }
+
+ /**
+ * When parsing the XML into JSONML, specifies if values should be kept as strings (true
), or if
+ * they should try to be guessed into JSON values (numeric, boolean, string)
+ *
+ * @return The keepStrings
configuration value.
+ */
+ public boolean isKeepStrings() {
+ return this.keepStrings;
+ }
+
+ /**
+ * When parsing the XML into JSONML, specifies if values should be kept as strings (true
), or if
+ * they should try to be guessed into JSON values (numeric, boolean, string)
+ *
+ * @param newVal
+ * new value to use for the keepStrings
configuration option.
+ *
+ * @return The existing configuration will not be modified. A new configuration is returned.
+ */
+ public T withKeepStrings(final boolean newVal) {
+ T newConfig = (T)this.clone();
+ newConfig.keepStrings = newVal;
+ return newConfig;
+ }
+
+ /**
+ * The maximum nesting depth that the parser will descend before throwing an exception
+ * when parsing the XML into JSONML.
+ * @return the maximum nesting depth set for this configuration
+ */
+ public int getMaxNestingDepth() {
+ return maxNestingDepth;
+ }
+
+ /**
+ * Defines the maximum nesting depth that the parser will descend before throwing an exception
+ * when parsing the XML into JSONML. The default max nesting depth is 512, which means the parser
+ * will throw a JsonException if the maximum depth is reached.
+ * Using any negative value as a parameter is equivalent to setting no limit to the nesting depth,
+ * which means the parses will go as deep as the maximum call stack size allows.
+ * @param maxNestingDepth the maximum nesting depth allowed to the XML parser
+ * @return The existing configuration will not be modified. A new configuration is returned.
+ */
+ public T withMaxNestingDepth(int maxNestingDepth) {
+ T newConfig = (T)this.clone();
+
+ if (maxNestingDepth > UNDEFINED_MAXIMUM_NESTING_DEPTH) {
+ newConfig.maxNestingDepth = maxNestingDepth;
+ } else {
+ newConfig.maxNestingDepth = UNDEFINED_MAXIMUM_NESTING_DEPTH;
+ }
+
+ return newConfig;
+ }
+}
diff --git a/src/main/java/org/json/XMLParserConfiguration.java b/src/main/java/org/json/XMLParserConfiguration.java
index 103023e..566146d 100644
--- a/src/main/java/org/json/XMLParserConfiguration.java
+++ b/src/main/java/org/json/XMLParserConfiguration.java
@@ -15,17 +15,12 @@ import java.util.Set;
* @author AylwardJ
*/
@SuppressWarnings({""})
-public class XMLParserConfiguration {
- /**
- * Used to indicate there's no defined limit to the maximum nesting depth when parsing a XML
- * document to JSON.
- */
- public static final int UNDEFINED_MAXIMUM_NESTING_DEPTH = -1;
+public class XMLParserConfiguration extends ParserConfiguration {
/**
* The default maximum nesting depth when parsing a XML document to JSON.
*/
- public static final int DEFAULT_MAXIMUM_NESTING_DEPTH = 512;
+// public static final int DEFAULT_MAXIMUM_NESTING_DEPTH = 512; // We could override
/** Original Configuration of the XML Parser. */
public static final XMLParserConfiguration ORIGINAL
@@ -34,12 +29,6 @@ public class XMLParserConfiguration {
public static final XMLParserConfiguration KEEP_STRINGS
= new XMLParserConfiguration().withKeepStrings(true);
- /**
- * When parsing the XML into JSON, specifies if values should be kept as strings (true
), or if
- * they should try to be guessed into JSON values (numeric, boolean, string)
- */
- private boolean keepStrings;
-
/**
* The name of the key in a JSON Object that indicates a CDATA section. Historically this has
* been the value "content" but can be changed. Use null
to indicate no CDATA
@@ -65,17 +54,12 @@ public class XMLParserConfiguration {
*/
private Set forceList;
- /**
- * The maximum nesting depth when parsing a XML document to JSON.
- */
- private int maxNestingDepth = DEFAULT_MAXIMUM_NESTING_DEPTH;
-
/**
* Default parser configuration. Does not keep strings (tries to implicitly convert
* values), and the CDATA Tag Name is "content".
*/
public XMLParserConfiguration () {
- this.keepStrings = false;
+ super();
this.cDataTagName = "content";
this.convertNilAttributeToNull = false;
this.xsiTypeMap = Collections.emptyMap();
@@ -122,7 +106,7 @@ public class XMLParserConfiguration {
*/
@Deprecated
public XMLParserConfiguration (final boolean keepStrings, final String cDataTagName) {
- this.keepStrings = keepStrings;
+ super(keepStrings, DEFAULT_MAXIMUM_NESTING_DEPTH);
this.cDataTagName = cDataTagName;
this.convertNilAttributeToNull = false;
}
@@ -141,7 +125,7 @@ public class XMLParserConfiguration {
*/
@Deprecated
public XMLParserConfiguration (final boolean keepStrings, final String cDataTagName, final boolean convertNilAttributeToNull) {
- this.keepStrings = keepStrings;
+ super(keepStrings, DEFAULT_MAXIMUM_NESTING_DEPTH);
this.cDataTagName = cDataTagName;
this.convertNilAttributeToNull = convertNilAttributeToNull;
}
@@ -162,12 +146,11 @@ public class XMLParserConfiguration {
private XMLParserConfiguration (final boolean keepStrings, final String cDataTagName,
final boolean convertNilAttributeToNull, final Map> xsiTypeMap, final Set forceList,
final int maxNestingDepth) {
- this.keepStrings = keepStrings;
+ super(keepStrings, maxNestingDepth);
this.cDataTagName = cDataTagName;
this.convertNilAttributeToNull = convertNilAttributeToNull;
this.xsiTypeMap = Collections.unmodifiableMap(xsiTypeMap);
this.forceList = Collections.unmodifiableSet(forceList);
- this.maxNestingDepth = maxNestingDepth;
}
/**
@@ -190,16 +173,6 @@ public class XMLParserConfiguration {
);
}
- /**
- * When parsing the XML into JSON, specifies if values should be kept as strings (true
), or if
- * they should try to be guessed into JSON values (numeric, boolean, string)
- *
- * @return The keepStrings
configuration value.
- */
- public boolean isKeepStrings() {
- return this.keepStrings;
- }
-
/**
* When parsing the XML into JSON, specifies if values should be kept as strings (true
), or if
* they should try to be guessed into JSON values (numeric, boolean, string)
@@ -209,10 +182,9 @@ public class XMLParserConfiguration {
*
* @return The existing configuration will not be modified. A new configuration is returned.
*/
+ @Override
public XMLParserConfiguration withKeepStrings(final boolean newVal) {
- XMLParserConfiguration newConfig = this.clone();
- newConfig.keepStrings = newVal;
- return newConfig;
+ return super.withKeepStrings(newVal);
}
/**
@@ -318,15 +290,6 @@ public class XMLParserConfiguration {
return newConfig;
}
- /**
- * The maximum nesting depth that the parser will descend before throwing an exception
- * when parsing the XML into JSON.
- * @return the maximum nesting depth set for this configuration
- */
- public int getMaxNestingDepth() {
- return maxNestingDepth;
- }
-
/**
* Defines the maximum nesting depth that the parser will descend before throwing an exception
* when parsing the XML into JSON. The default max nesting depth is 512, which means the parser
@@ -336,15 +299,8 @@ public class XMLParserConfiguration {
* @param maxNestingDepth the maximum nesting depth allowed to the XML parser
* @return The existing configuration will not be modified. A new configuration is returned.
*/
+ @Override
public XMLParserConfiguration withMaxNestingDepth(int maxNestingDepth) {
- XMLParserConfiguration newConfig = this.clone();
-
- if (maxNestingDepth > UNDEFINED_MAXIMUM_NESTING_DEPTH) {
- newConfig.maxNestingDepth = maxNestingDepth;
- } else {
- newConfig.maxNestingDepth = UNDEFINED_MAXIMUM_NESTING_DEPTH;
- }
-
- return newConfig;
+ return super.withMaxNestingDepth(maxNestingDepth);
}
}
diff --git a/src/test/java/org/json/junit/JSONMLTest.java b/src/test/java/org/json/junit/JSONMLTest.java
index 1514ddd..35c0af2 100644
--- a/src/test/java/org/json/junit/JSONMLTest.java
+++ b/src/test/java/org/json/junit/JSONMLTest.java
@@ -895,7 +895,36 @@ public class JSONMLTest {
}
+ @Test
+ public void testToJSONObjectMaxDefaultNestingDepthIsRespected() {
+ final String wayTooLongMalformedXML = new String(new char[6000]).replace("\0", "");
+ try {
+ JSONML.toJSONObject(wayTooLongMalformedXML, JSONMLParserConfiguration.ORIGINAL);
+
+ fail("Expecting a JSONException");
+ } catch (JSONException e) {
+ assertTrue("Wrong throwable thrown: not expecting message <" + e.getMessage() + ">",
+ e.getMessage().startsWith("Maximum nesting depth of " + JSONMLParserConfiguration.DEFAULT_MAXIMUM_NESTING_DEPTH));
+ }
+ }
+
+ @Test
+ public void testToJSONObjectUnlimitedNestingDepthIsPossible() {
+ int actualDepth = JSONMLParserConfiguration.DEFAULT_MAXIMUM_NESTING_DEPTH +10;
+ final String deeperThanDefaultMax = new String(new char[actualDepth]).replace("\0", "") +
+ "value" +
+ new String(new char[actualDepth]).replace("\0", "");
+
+ try {
+ JSONML.toJSONObject(deeperThanDefaultMax, JSONMLParserConfiguration.ORIGINAL
+ .withMaxNestingDepth(JSONMLParserConfiguration.UNDEFINED_MAXIMUM_NESTING_DEPTH));
+ } catch (JSONException e) {
+ e.printStackTrace();
+ fail("XML document should be parsed beyond the default maximum depth if maxNestingDepth " +
+ "parameter is set to -1 in JSONMLParserConfiguration");
+ }
+ }
@Test