mirror of
https://github.com/stleary/JSON-java.git
synced 2026-03-20 00:00:50 -04:00
Merge pull request #1037 from OwenSanzas/fix-jsonml-classcast
Fix ClassCastException in JSONML.toJSONArray and toJSONObject
This commit is contained in:
@@ -22,6 +22,33 @@ public class JSONML {
|
|||||||
public JSONML() {
|
public JSONML() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Safely cast parse result to JSONArray with proper type checking.
|
||||||
|
* @param result The result from parse() method
|
||||||
|
* @return JSONArray if result is a JSONArray
|
||||||
|
* @throws JSONException if result is not a JSONArray
|
||||||
|
*/
|
||||||
|
private static JSONArray toJSONArraySafe(Object result) throws JSONException {
|
||||||
|
if (result instanceof JSONArray) {
|
||||||
|
return (JSONArray) result;
|
||||||
|
}
|
||||||
|
throw new JSONException("Expected JSONArray but got " +
|
||||||
|
(result == null ? "null" : result.getClass().getSimpleName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Safely cast parse result to JSONObject with proper type checking.
|
||||||
|
* @param result The result from parse() method
|
||||||
|
* @return JSONObject if result is a JSONObject
|
||||||
|
* @throws JSONException if result is not a JSONObject
|
||||||
|
*/
|
||||||
|
private static JSONObject toJSONObjectSafe(Object result) throws JSONException {
|
||||||
|
if (result instanceof JSONObject) {
|
||||||
|
return (JSONObject) result;
|
||||||
|
}
|
||||||
|
throw new JSONException("Expected JSONObject but got " +
|
||||||
|
(result == null ? "null" : result.getClass().getSimpleName()));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse XML values and store them in a JSONArray.
|
* Parse XML values and store them in a JSONArray.
|
||||||
@@ -276,7 +303,7 @@ public class JSONML {
|
|||||||
* @throws JSONException Thrown on error converting to a JSONArray
|
* @throws JSONException Thrown on error converting to a JSONArray
|
||||||
*/
|
*/
|
||||||
public static JSONArray toJSONArray(String string) throws JSONException {
|
public static JSONArray toJSONArray(String string) throws JSONException {
|
||||||
return (JSONArray)parse(new XMLTokener(string), true, null, JSONMLParserConfiguration.ORIGINAL, 0);
|
return toJSONArraySafe(parse(new XMLTokener(string), true, null, JSONMLParserConfiguration.ORIGINAL, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -298,7 +325,7 @@ public class JSONML {
|
|||||||
* @throws JSONException Thrown on error converting to a JSONArray
|
* @throws JSONException Thrown on error converting to a JSONArray
|
||||||
*/
|
*/
|
||||||
public static JSONArray toJSONArray(String string, boolean keepStrings) throws JSONException {
|
public static JSONArray toJSONArray(String string, boolean keepStrings) throws JSONException {
|
||||||
return (JSONArray)parse(new XMLTokener(string), true, null, keepStrings, 0);
|
return toJSONArraySafe(parse(new XMLTokener(string), true, null, keepStrings, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -323,7 +350,7 @@ public class JSONML {
|
|||||||
* @throws JSONException Thrown on error converting to a JSONArray
|
* @throws JSONException Thrown on error converting to a JSONArray
|
||||||
*/
|
*/
|
||||||
public static JSONArray toJSONArray(String string, JSONMLParserConfiguration config) throws JSONException {
|
public static JSONArray toJSONArray(String string, JSONMLParserConfiguration config) throws JSONException {
|
||||||
return (JSONArray)parse(new XMLTokener(string), true, null, config, 0);
|
return toJSONArraySafe(parse(new XMLTokener(string), true, null, config, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -347,7 +374,7 @@ public class JSONML {
|
|||||||
* @throws JSONException Thrown on error converting to a JSONArray
|
* @throws JSONException Thrown on error converting to a JSONArray
|
||||||
*/
|
*/
|
||||||
public static JSONArray toJSONArray(XMLTokener x, JSONMLParserConfiguration config) throws JSONException {
|
public static JSONArray toJSONArray(XMLTokener x, JSONMLParserConfiguration config) throws JSONException {
|
||||||
return (JSONArray)parse(x, true, null, config, 0);
|
return toJSONArraySafe(parse(x, true, null, config, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -369,7 +396,7 @@ public class JSONML {
|
|||||||
* @throws JSONException Thrown on error converting to a JSONArray
|
* @throws JSONException Thrown on error converting to a JSONArray
|
||||||
*/
|
*/
|
||||||
public static JSONArray toJSONArray(XMLTokener x, boolean keepStrings) throws JSONException {
|
public static JSONArray toJSONArray(XMLTokener x, boolean keepStrings) throws JSONException {
|
||||||
return (JSONArray)parse(x, true, null, keepStrings, 0);
|
return toJSONArraySafe(parse(x, true, null, keepStrings, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -386,7 +413,7 @@ public class JSONML {
|
|||||||
* @throws JSONException Thrown on error converting to a JSONArray
|
* @throws JSONException Thrown on error converting to a JSONArray
|
||||||
*/
|
*/
|
||||||
public static JSONArray toJSONArray(XMLTokener x) throws JSONException {
|
public static JSONArray toJSONArray(XMLTokener x) throws JSONException {
|
||||||
return (JSONArray)parse(x, true, null, false, 0);
|
return toJSONArraySafe(parse(x, true, null, false, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -404,7 +431,7 @@ public class JSONML {
|
|||||||
* @throws JSONException Thrown on error converting to a JSONObject
|
* @throws JSONException Thrown on error converting to a JSONObject
|
||||||
*/
|
*/
|
||||||
public static JSONObject toJSONObject(String string) throws JSONException {
|
public static JSONObject toJSONObject(String string) throws JSONException {
|
||||||
return (JSONObject)parse(new XMLTokener(string), false, null, false, 0);
|
return toJSONObjectSafe(parse(new XMLTokener(string), false, null, false, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -424,7 +451,7 @@ public class JSONML {
|
|||||||
* @throws JSONException Thrown on error converting to a JSONObject
|
* @throws JSONException Thrown on error converting to a JSONObject
|
||||||
*/
|
*/
|
||||||
public static JSONObject toJSONObject(String string, boolean keepStrings) throws JSONException {
|
public static JSONObject toJSONObject(String string, boolean keepStrings) throws JSONException {
|
||||||
return (JSONObject)parse(new XMLTokener(string), false, null, keepStrings, 0);
|
return toJSONObjectSafe(parse(new XMLTokener(string), false, null, keepStrings, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -446,7 +473,7 @@ public class JSONML {
|
|||||||
* @throws JSONException Thrown on error converting to a JSONObject
|
* @throws JSONException Thrown on error converting to a JSONObject
|
||||||
*/
|
*/
|
||||||
public static JSONObject toJSONObject(String string, JSONMLParserConfiguration config) throws JSONException {
|
public static JSONObject toJSONObject(String string, JSONMLParserConfiguration config) throws JSONException {
|
||||||
return (JSONObject)parse(new XMLTokener(string), false, null, config, 0);
|
return toJSONObjectSafe(parse(new XMLTokener(string), false, null, config, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -464,7 +491,7 @@ public class JSONML {
|
|||||||
* @throws JSONException Thrown on error converting to a JSONObject
|
* @throws JSONException Thrown on error converting to a JSONObject
|
||||||
*/
|
*/
|
||||||
public static JSONObject toJSONObject(XMLTokener x) throws JSONException {
|
public static JSONObject toJSONObject(XMLTokener x) throws JSONException {
|
||||||
return (JSONObject)parse(x, false, null, false, 0);
|
return toJSONObjectSafe(parse(x, false, null, false, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -484,7 +511,7 @@ public class JSONML {
|
|||||||
* @throws JSONException Thrown on error converting to a JSONObject
|
* @throws JSONException Thrown on error converting to a JSONObject
|
||||||
*/
|
*/
|
||||||
public static JSONObject toJSONObject(XMLTokener x, boolean keepStrings) throws JSONException {
|
public static JSONObject toJSONObject(XMLTokener x, boolean keepStrings) throws JSONException {
|
||||||
return (JSONObject)parse(x, false, null, keepStrings, 0);
|
return toJSONObjectSafe(parse(x, false, null, keepStrings, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -506,7 +533,7 @@ public class JSONML {
|
|||||||
* @throws JSONException Thrown on error converting to a JSONObject
|
* @throws JSONException Thrown on error converting to a JSONObject
|
||||||
*/
|
*/
|
||||||
public static JSONObject toJSONObject(XMLTokener x, JSONMLParserConfiguration config) throws JSONException {
|
public static JSONObject toJSONObject(XMLTokener x, JSONMLParserConfiguration config) throws JSONException {
|
||||||
return (JSONObject)parse(x, false, null, config, 0);
|
return toJSONObjectSafe(parse(x, false, null, config, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -986,4 +986,70 @@ public class JSONMLTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests that malformed XML causing type mismatch throws JSONException.
|
||||||
|
* Previously threw ClassCastException when parse() returned String instead of JSONArray.
|
||||||
|
* Related to issue #1034
|
||||||
|
*/
|
||||||
|
@Test(expected = JSONException.class)
|
||||||
|
public void testMalformedXMLThrowsJSONExceptionNotClassCast() {
|
||||||
|
// This malformed XML causes parse() to return wrong type
|
||||||
|
byte[] data = {0x3c, 0x0a, 0x2f, (byte)0xff, (byte)0xff, (byte)0xff,
|
||||||
|
(byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,
|
||||||
|
(byte)0xff, 0x3e, 0x42};
|
||||||
|
String xmlStr = new String(data);
|
||||||
|
JSONML.toJSONArray(xmlStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests that type mismatch in toJSONObject throws JSONException.
|
||||||
|
* Validates safe type casting in toJSONObject methods.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testToJSONObjectTypeMismatch() {
|
||||||
|
// Create XML that would cause parse() to return wrong type
|
||||||
|
String xmlStr = "<\n/\u00ff\u00ff\u00ff\u00ff\u00ff\u00ff\u00ff\u00ff>B";
|
||||||
|
try {
|
||||||
|
JSONML.toJSONObject(xmlStr);
|
||||||
|
fail("Expected JSONException for type mismatch");
|
||||||
|
} catch (ClassCastException e) {
|
||||||
|
fail("Should throw JSONException, not ClassCastException");
|
||||||
|
} catch (JSONException e) {
|
||||||
|
// Expected - verify it's about type mismatch
|
||||||
|
assertTrue("Exception message should mention type error",
|
||||||
|
e.getMessage().contains("Expected") || e.getMessage().contains("got"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests that valid XML still works correctly after the fix.
|
||||||
|
* Ensures the type checking doesn't break normal operation.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testValidXMLStillWorks() {
|
||||||
|
String xmlStr = "<root><item>value</item></root>";
|
||||||
|
try {
|
||||||
|
JSONArray jsonArray = JSONML.toJSONArray(xmlStr);
|
||||||
|
assertNotNull("JSONArray should not be null", jsonArray);
|
||||||
|
assertEquals("root", jsonArray.getString(0));
|
||||||
|
} catch (Exception e) {
|
||||||
|
fail("Valid XML should not throw exception: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests that valid XML to JSONObject still works correctly.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testValidXMLToJSONObjectStillWorks() {
|
||||||
|
String xmlStr = "<root attr=\"value\"><item>content</item></root>";
|
||||||
|
try {
|
||||||
|
JSONObject jsonObject = JSONML.toJSONObject(xmlStr);
|
||||||
|
assertNotNull("JSONObject should not be null", jsonObject);
|
||||||
|
assertEquals("root", jsonObject.getString("tagName"));
|
||||||
|
} catch (Exception e) {
|
||||||
|
fail("Valid XML should not throw exception: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user