Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package jettison for openSUSE:Factory checked in at 2022-12-15 19:24:57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/jettison (Old) and /work/SRC/openSUSE:Factory/.jettison.new.1835 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "jettison" Thu Dec 15 19:24:57 2022 rev:5 rq:1042912 version:1.5.3 Changes: -------- --- /work/SRC/openSUSE:Factory/jettison/jettison.changes 2022-10-06 07:42:07.192676055 +0200 +++ /work/SRC/openSUSE:Factory/.jettison.new.1835/jettison.changes 2022-12-15 19:25:11.156049729 +0100 @@ -1,0 +2,14 @@ +Wed Dec 14 12:11:51 UTC 2022 - Fridrich Strba <[email protected]> + +- Upgrade to version 1.5.3 + * Fixes: + + Backslash escaping. Throw syntax exception on invalid json + sooner + + Adding another test for backslashes + + Introducing new static methods to set the recursion depth + limit + + Incorrect recursion depth check in JSONTokener + + Fixing StackOverflow error (bsc#1206400, CVE-2022-45685, + bsc#1206401, CVE-2022-45693) + +------------------------------------------------------------------- Old: ---- jettison-1.5.1.tar.gz New: ---- jettison-1.5.3.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ jettison.spec ++++++ --- /var/tmp/diff_new_pack.eWz7CJ/_old 2022-12-15 19:25:13.964065705 +0100 +++ /var/tmp/diff_new_pack.eWz7CJ/_new 2022-12-15 19:25:13.968065728 +0100 @@ -17,7 +17,7 @@ Name: jettison -Version: 1.5.1 +Version: 1.5.3 Release: 0 Summary: A JSON StAX implementation License: Apache-2.0 ++++++ jettison-1.5.1.tar.gz -> jettison-1.5.3.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jettison-jettison-1.5.1/pom.xml new/jettison-jettison-1.5.3/pom.xml --- old/jettison-jettison-1.5.1/pom.xml 2022-09-22 18:38:33.000000000 +0200 +++ new/jettison-jettison-1.5.3/pom.xml 2022-12-07 00:20:44.000000000 +0100 @@ -2,7 +2,7 @@ <modelVersion>4.0.0</modelVersion> <groupId>org.codehaus.jettison</groupId> <artifactId>jettison</artifactId> - <version>1.5.1</version> + <version>1.5.3</version> <packaging>bundle</packaging> <name>Jettison</name> <description>A StAX implementation for JSON.</description> @@ -23,7 +23,7 @@ <dependency> <groupId>com.fasterxml.woodstox</groupId> <artifactId>woodstox-core</artifactId> - <version>6.2.8</version> + <version>6.4.0</version> <scope>test</scope> </dependency> </dependencies> @@ -31,7 +31,7 @@ <connection>scm:git:http://github.com/jettison-json/jettison.git</connection> <developerConnection>scm:git:https://github.com/jettison-json/jettison.git</developerConnection> <url>https://github.com/jettison-json/jettison</url> - <tag>jettison-1.5.1</tag> + <tag>jettison-1.5.3</tag> </scm> <distributionManagement> <snapshotRepository> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jettison-jettison-1.5.1/src/main/java/org/codehaus/jettison/json/JSONArray.java new/jettison-jettison-1.5.3/src/main/java/org/codehaus/jettison/json/JSONArray.java --- old/jettison-jettison-1.5.1/src/main/java/org/codehaus/jettison/json/JSONArray.java 2022-09-22 18:38:33.000000000 +0200 +++ new/jettison-jettison-1.5.3/src/main/java/org/codehaus/jettison/json/JSONArray.java 2022-12-07 00:20:44.000000000 +0100 @@ -179,8 +179,9 @@ /** * Construct a JSONArray from a Collection. * @param collection A Collection. + * @throws JSONException If there is a syntax error. */ - public JSONArray(Collection collection) { + public JSONArray(Collection collection) throws JSONException { this.myArrayList = (collection == null) ? new ArrayList() : new ArrayList(collection); @@ -580,8 +581,9 @@ * JSONArray which is produced from a Collection. * @param value A Collection value. * @return this. + * @throws JSONException If there is a syntax error. */ - public JSONArray put(Collection value) { + public JSONArray put(Collection value) throws JSONException { put(new JSONArray(value)); return this; } @@ -631,8 +633,9 @@ * JSONObject which is produced from a Map. * @param value A Map value. * @return this. + * @throws JSONException If there is a syntax error. */ - public JSONArray put(Map value) { + public JSONArray put(Map value) throws JSONException { put(new JSONObject(value)); return this; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jettison-jettison-1.5.1/src/main/java/org/codehaus/jettison/json/JSONObject.java new/jettison-jettison-1.5.3/src/main/java/org/codehaus/jettison/json/JSONObject.java --- old/jettison-jettison-1.5.1/src/main/java/org/codehaus/jettison/json/JSONObject.java 2022-09-22 18:38:33.000000000 +0200 +++ new/jettison-jettison-1.5.3/src/main/java/org/codehaus/jettison/json/JSONObject.java 2022-12-07 00:20:44.000000000 +0100 @@ -85,6 +85,13 @@ public class JSONObject implements Serializable { /** + * The default recursion depth limit to prevent stack overflow issues on deeply nested structures. + */ + final static int DEFAULT_RECURSION_DEPTH_LIMIT = 500; + + static int RECURSION_DEPTH_LIMIT = DEFAULT_RECURSION_DEPTH_LIMIT; + + /** * JSONObject.NULL is equivalent to the value that JavaScript calls null, * whilst Java's null is equivalent to the value that JavaScript calls * undefined. @@ -213,6 +220,8 @@ throw x.syntaxError("A JSONObject text must end with '}'"); case '}': return; + case '{': + throw x.syntaxError("Expected a key"); default: x.back(); key = x.nextValue().toString(); @@ -257,8 +266,17 @@ * Construct a JSONObject from a Map. * @param map A map object that can be used to initialize the contents of * the JSONObject. + * @throws JSONException If there is a syntax error. */ - public JSONObject(Map map) { + public JSONObject(Map map) throws JSONException { + this(map, 0); + } + + private JSONObject(Map map, int recursionDepth) throws JSONException { + + if (recursionDepth > RECURSION_DEPTH_LIMIT) { + throw new JSONException("JSONObject has reached recursion depth limit of " + RECURSION_DEPTH_LIMIT); + } this.myHashMap = (map == null) ? new LinkedHashMap<Object,Object>() : new LinkedHashMap<Object,Object>(map); @@ -268,8 +286,8 @@ if (v instanceof Collection) { myHashMap.put(entry.getKey(), new JSONArray((Collection) v)); } - if (v instanceof Map) { - myHashMap.put(entry.getKey(), new JSONObject((Map) v)); + if (v instanceof Map && v != map) { + myHashMap.put(entry.getKey(), new JSONObject((Map) v, recursionDepth + 1)); } } } @@ -1025,9 +1043,10 @@ c = string.charAt(i); switch (c) { case '\\': + sb.append("\\\\"); + break; case '"': - sb.append('\\'); - sb.append(c); + sb.append("\\\""); break; case '/': if (escapeForwardSlashAlways || i > 0 && string.charAt(i - 1) == '<') { @@ -1319,6 +1338,43 @@ return quote(value.toString(), escapeForwardSlash); } + /** + * Set the new recursion depth limit to prevent stack overflow issues on deeply nested structures. The default + * value is 500 + * @param newRecursionDepthLimit the new recursion depth limit to set + */ + public static void setGlobalRecursionDepthLimit(int newRecursionDepthLimit) { + RECURSION_DEPTH_LIMIT = newRecursionDepthLimit; + } + + /** + * Set the new recursion depth limit to prevent stack overflow issues on deeply nested structures. The default + * value is 500 + * @param newRecursionDepthLimit the new recursion depth limit to set + */ + @Deprecated + public void setRecursionDepthLimit(int newRecursionDepthLimit) { + RECURSION_DEPTH_LIMIT = newRecursionDepthLimit; + } + + /** + * Get the new recursion depth limit to prevent stack overflow issues on deeply nested structures. The default + * value is 500 + * @return the recursion depth limit + */ + public static int getGlobalRecursionDepthLimit() { + return RECURSION_DEPTH_LIMIT; + } + + /** + * Get the new recursion depth limit to prevent stack overflow issues on deeply nested structures. The default + * value is 500 + * @return the recursion depth limit + */ + @Deprecated + public int getRecursionDepthLimit() { + return RECURSION_DEPTH_LIMIT; + } /** * Write the contents of the JSONObject as JSON text to a writer. @@ -1396,4 +1452,5 @@ public Map toMap() { return Collections.unmodifiableMap(myHashMap); } + } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jettison-jettison-1.5.1/src/main/java/org/codehaus/jettison/json/JSONTokener.java new/jettison-jettison-1.5.3/src/main/java/org/codehaus/jettison/json/JSONTokener.java --- old/jettison-jettison-1.5.1/src/main/java/org/codehaus/jettison/json/JSONTokener.java 2022-09-22 18:38:33.000000000 +0200 +++ new/jettison-jettison-1.5.3/src/main/java/org/codehaus/jettison/json/JSONTokener.java 2022-12-07 00:20:44.000000000 +0100 @@ -44,7 +44,9 @@ private int threshold = -1; - + + private int recursionDepth; + /** * Construct a JSONTokener from a string. * @@ -54,7 +56,7 @@ this.myIndex = 0; this.mySource = s.trim(); } - + /** * Construct a JSONTokener from a string. * @@ -423,11 +425,24 @@ } protected JSONObject newJSONObject() throws JSONException { - return new JSONObject(this); + checkRecursionDepth(); + JSONObject object = new JSONObject(this); + recursionDepth--; + return object; } - + protected JSONArray newJSONArray() throws JSONException { - return new JSONArray(this); + checkRecursionDepth(); + JSONArray array = new JSONArray(this); + recursionDepth--; + return array; + } + + private void checkRecursionDepth() throws JSONException { + recursionDepth++; + if (recursionDepth > JSONObject.RECURSION_DEPTH_LIMIT) { + throw new JSONException("JSONTokener has reached recursion depth limit of " + JSONObject.RECURSION_DEPTH_LIMIT); + } } /** diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jettison-jettison-1.5.1/src/test/java/org/codehaus/jettison/json/JSONArrayTest.java new/jettison-jettison-1.5.3/src/test/java/org/codehaus/jettison/json/JSONArrayTest.java --- old/jettison-jettison-1.5.1/src/test/java/org/codehaus/jettison/json/JSONArrayTest.java 2022-09-22 18:38:33.000000000 +0200 +++ new/jettison-jettison-1.5.3/src/test/java/org/codehaus/jettison/json/JSONArrayTest.java 2022-12-07 00:20:44.000000000 +0100 @@ -63,4 +63,10 @@ // expected } } + + public void testIssue52() throws JSONException { + JSONObject.setGlobalRecursionDepthLimit(10); + new JSONArray("[{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {a:10}]"); + } + } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jettison-jettison-1.5.1/src/test/java/org/codehaus/jettison/json/JSONObjectTest.java new/jettison-jettison-1.5.3/src/test/java/org/codehaus/jettison/json/JSONObjectTest.java --- old/jettison-jettison-1.5.1/src/test/java/org/codehaus/jettison/json/JSONObjectTest.java 2022-09-22 18:38:33.000000000 +0200 +++ new/jettison-jettison-1.5.3/src/test/java/org/codehaus/jettison/json/JSONObjectTest.java 2022-12-07 00:20:44.000000000 +0100 @@ -2,7 +2,13 @@ import junit.framework.TestCase; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + public class JSONObjectTest extends TestCase { + public void testEquals() throws Exception { JSONObject aJsonObj = new JSONObject("{\"x\":\"y\"}"); JSONObject bJsonObj = new JSONObject("{\"x\":\"y\"}"); @@ -81,7 +87,11 @@ public void testSlashEscapingTurnedOnByDefault() throws Exception { JSONObject obj = new JSONObject(); obj.put("key", "http://example.com/foo"); - assertEquals(obj.toString(), "{\"key\":\"http:\\/\\/example.com\\/foo\"}"); + assertEquals("{\"key\":\"http:\\/\\/example.com\\/foo\"}", obj.toString()); + + obj = new JSONObject(); + obj.put("key", "\\\\"); + assertEquals("{\"key\":\"\\\\\\\\\"}", obj.toString()); } public void testForwardSlashEscapingModifiedfBySetter() throws Exception { @@ -148,4 +158,57 @@ } } + // https://github.com/jettison-json/jettison/issues/52 + public void testIssue52() throws Exception { + Map<String,Object> map = new HashMap<>(); + map.put("t",map); + new JSONObject(map); + } + + // https://github.com/jettison-json/jettison/issues/52 + public void testIssue52Recursive() throws Exception { + try { + Map<String, Object> map = new HashMap<>(); + Map<String, Object> map2 = new HashMap<>(); + map.put("t", map2); + map2.put("t", map); + new JSONObject(map); + fail("Failure expected"); + } catch (JSONException e) { + assertTrue(e.getMessage().contains("JSONObject has reached recursion depth limit")); + // expected + } + } + + // https://github.com/jettison-json/jettison/issues/45 + public void testFuzzerTestCase() throws Exception, JSONException { + try { + new JSONObject("{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{\"G\":[30018084,1,6,32768,1,1,6,1,1]}:[3,1,6,32768,1,1,6,1,1]}:[3,1,6,32768,1,1,6,1,1]}:[3,1,6,32768,1,1,6,1,1]}:[3,1,6,32768,1,1,6,1,1]}:[3,1,6,32768,1,1,6,1,1]}:[3,1,6,32768,1,1,6,1,1]}:[3,1,6,38,1,1,6,1,1]}:[3,1,6,32768,1,1,6,1,1]}:[3,1,6,32768,1,1,6,1,1]}:[3,1,6,32768,1,1,6,1,1]}:[3,1,6,32768,1,1,6,1,1]}:[3,1,6,32768,1,1,6,1,1]}:[3,1,6,32768,1,1,6,1,0]}:[3,1,6,32768,1,1,6,1,1]}:[3,1,6,32768,1,340282366920938463463374607431768211458,6,1,1]}:[32768,1,1,6,1,0]}:[3,1,6,32768,1,1,6,1,1]}:[3,1,6,32768,1,340282366920938463463374607431768211458,6,1,1]}:[3,1,6,32768,1,1,6,1,1]}:[3,1,6,32768,9â68,1,127,1,1]}:[3,1,6,32768,1,1,6,1,1]}:[3,1,6,32768,1,1,6,1,1]}:[3,1,6,32768,1,1,6,1,1]}:[3,1,6,32768,1,1,6,1,1]}:[3,1,6,32768,1,1,6,1,1]}:[3,1,6,32768,1,1,6,1,9223372036854775807]}:[3,1,6,32768,1,1,6,1,1]}:[3,1,10,32768,1,1,6,1,1]}"); + fail("Failure expected"); + } catch (JSONException ex) { + // expected + assertTrue(ex.getMessage().contains("Expected a key")); + } + } + + public void testFuzzerTestCase2() throws Exception { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < 100000; i++) { + sb.append("{\"key\":"); + } + try { + new JSONObject(sb.toString()); + fail("Failure expected"); + } catch (JSONException e) { + assertTrue(e.getMessage().contains("JSONTokener has reached recursion depth limit")); + // expected + } + } + + public void testIssue58() throws JSONException { + Map<String, Object> map = new HashMap<>(); + map.put("request", "{\"exclude\":[\".\",\"?\",\"+\",\"*\",\"|\",\"{\",\"}\",\"[\",\"]\",\"(\",\")\",\"\\\"\",\"\\\\\",\"#\",\"@\",\"&\",\"<\",\">\",\"~\"]}"); + JSONObject jsonObject = new JSONObject(map); + JSONObject jsonObject1 = new JSONObject(jsonObject.toString()); + } }
