Skip to content

Commit b9f81f3

Browse files
authored
The maximum depth for the JSON parser has been set to 10000
1 parent 24b1b04 commit b9f81f3

File tree

3 files changed

+40
-10
lines changed

3 files changed

+40
-10
lines changed

src/main/java/com/github/underscore/Json.java

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@
3232

3333
@SuppressWarnings({"java:S3740", "java:S3776"})
3434
public final class Json {
35+
36+
private static final int PARSE_MAX_DEPTH = 10_000;
37+
3538
private Json() {}
3639

3740
private static final String NULL = "null";
@@ -459,25 +462,30 @@ public static class JsonParser {
459462
private int current;
460463
private StringBuilder captureBuffer;
461464
private int captureStart;
465+
private final int maxDepth;
462466

463-
public JsonParser(String string) {
467+
public JsonParser(String string, int maxDepth) {
464468
this.json = string;
469+
this.maxDepth = maxDepth;
465470
line = 1;
466471
captureStart = -1;
467472
}
468473

469474
public Object parse() {
470475
read();
471476
skipWhiteSpace();
472-
final Object result = readValue();
477+
final Object result = readValue(0);
473478
skipWhiteSpace();
474479
if (!isEndOfText()) {
475480
throw error("Unexpected character");
476481
}
477482
return result;
478483
}
479484

480-
private Object readValue() {
485+
private Object readValue(int depth) {
486+
if (depth > maxDepth) {
487+
throw error("Maximum depth exceeded");
488+
}
481489
switch (current) {
482490
case 'n':
483491
return readNull();
@@ -488,9 +496,9 @@ private Object readValue() {
488496
case '"':
489497
return readString();
490498
case '[':
491-
return readArray();
499+
return readArray(depth + 1);
492500
case '{':
493-
return readObject();
501+
return readObject(depth + 1);
494502
case '-':
495503
case '0':
496504
case '1':
@@ -508,7 +516,7 @@ private Object readValue() {
508516
}
509517
}
510518

511-
private List<Object> readArray() {
519+
private List<Object> readArray(int depth) {
512520
read();
513521
List<Object> array = new ArrayList<>();
514522
skipWhiteSpace();
@@ -517,7 +525,7 @@ private List<Object> readArray() {
517525
}
518526
do {
519527
skipWhiteSpace();
520-
array.add(readValue());
528+
array.add(readValue(depth));
521529
skipWhiteSpace();
522530
} while (readChar(','));
523531
if (!readChar(']')) {
@@ -526,7 +534,7 @@ private List<Object> readArray() {
526534
return array;
527535
}
528536

529-
private Map<String, Object> readObject() {
537+
private Map<String, Object> readObject(int depth) {
530538
read();
531539
Map<String, Object> object = new LinkedHashMap<>();
532540
skipWhiteSpace();
@@ -541,7 +549,7 @@ private Map<String, Object> readObject() {
541549
throw expected("':'");
542550
}
543551
skipWhiteSpace();
544-
object.put(name, readValue());
552+
object.put(name, readValue(depth));
545553
skipWhiteSpace();
546554
} while (readChar(','));
547555
if (!readChar('}')) {
@@ -834,7 +842,11 @@ public static String toJson(Map map) {
834842
}
835843

836844
public static Object fromJson(String string) {
837-
return new JsonParser(string).parse();
845+
return fromJson(string, PARSE_MAX_DEPTH);
846+
}
847+
848+
public static Object fromJson(String string, int maxDepth) {
849+
return new JsonParser(string, maxDepth).parse();
838850
}
839851

840852
public static String formatJson(String json, JsonStringBuilder.Step identStep) {

src/main/java/com/github/underscore/U.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2601,6 +2601,11 @@ public static Map<String, Object> fromJsonMap(final String string) {
26012601
return getStringObjectMap(object);
26022602
}
26032603

2604+
public static Map<String, Object> fromJsonMap(final String string, final int maxDepth) {
2605+
final Object object = Json.fromJson(string, maxDepth);
2606+
return getStringObjectMap(object);
2607+
}
2608+
26042609
@SuppressWarnings("unchecked")
26052610
private static Map<String, Object> getStringObjectMap(Object object) {
26062611
final Map<String, Object> result;

src/test/java/com/github/underscore/StringTest.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3503,6 +3503,7 @@ void fromJsonMap() {
35033503
assertEquals("{value=[]}", U.fromJsonMap(stringJson).toString());
35043504
String stringJson2 = "{}";
35053505
assertEquals("{}", U.fromJsonMap(stringJson2).toString());
3506+
assertEquals("{}", U.fromJsonMap(stringJson2, 100).toString());
35063507
}
35073508

35083509
@Test
@@ -3517,6 +3518,18 @@ void fromJsonStackoverflowObject() throws IOException {
35173518
}
35183519
}
35193520

3521+
@Test
3522+
void fromJsonParseException() throws IOException {
3523+
String stringJson =
3524+
new String(
3525+
Files.readAllBytes(Paths.get("src/test/resources/wellFormedObject.json")));
3526+
try {
3527+
U.fromJsonMap(stringJson, 1000);
3528+
} catch (Throwable throwable) {
3529+
assertTrue(throwable instanceof Json.ParseException);
3530+
}
3531+
}
3532+
35203533
@Test
35213534
void fromJsonStackoverflowArray() throws IOException {
35223535
String stringJson =

0 commit comments

Comments
 (0)