Skip to content

add flag to drop the limit of json depth #156

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 9, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,13 @@ public class JSONParser {
* @since 2.4
*/
public final static int BIG_DIGIT_UNRESTRICTED = 2048;

/**
* If limit the max depth of json size
*
* @since 2.5
*/
public static final int FINITE_JSON_DEPTH = 4096;


/**
Expand Down Expand Up @@ -132,7 +139,7 @@ public class JSONParser {
/*
* internal fields
*/
private int mode;
private final int mode;

private JSONParserInputStream pBinStream;
private JSONParserByteArray pBytes;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ abstract class JSONParserBase {
protected final boolean useIntegerStorage;
protected final boolean reject127;
protected final boolean unrestictBigDigit;
protected final boolean finiteJsonDepth;

public JSONParserBase(int permissiveMode) {
this.acceptNaN = (permissiveMode & JSONParser.ACCEPT_NAN) > 0;
Expand All @@ -107,6 +108,7 @@ public JSONParserBase(int permissiveMode) {
this.checkTaillingSpace = (permissiveMode & JSONParser.ACCEPT_TAILLING_SPACE) == 0;
this.reject127 = (permissiveMode & JSONParser.REJECT_127_CHAR) > 0;
this.unrestictBigDigit = (permissiveMode & JSONParser.BIG_DIGIT_UNRESTRICTED) > 0;
this.finiteJsonDepth = (permissiveMode & JSONParser.FINITE_JSON_DEPTH) > 0;
}

public void checkControleChar() throws ParseException {
Expand Down Expand Up @@ -296,7 +298,7 @@ protected Number parseNumber(String s) throws ParseException {
protected <T> T readArray(JsonReaderI<T> mapper) throws ParseException, IOException {
if (c != '[')
throw new RuntimeException("Internal Error");
if (++this.depth > MAX_DEPTH) {
if (finiteJsonDepth && ++this.depth > MAX_DEPTH) {
throw new ParseException(pos, ERROR_UNEXPECTED_JSON_DEPTH, c);
}
Object current = mapper.createArray();
Expand Down Expand Up @@ -553,7 +555,7 @@ protected <T> T readObject(JsonReaderI<T> mapper) throws ParseException, IOExcep
//
if (c != '{')
throw new RuntimeException("Internal Error");
if (++this.depth > MAX_DEPTH) {
if (finiteJsonDepth && ++this.depth > MAX_DEPTH) {
throw new ParseException(pos, ERROR_UNEXPECTED_JSON_DEPTH, c);
}
Object current = mapper.createObject();
Expand Down
26 changes: 24 additions & 2 deletions json-smart/src/test/java/net/minidev/json/test/TestOverflow.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

import net.minidev.json.JSONArray;
import net.minidev.json.JSONValue;
import net.minidev.json.parser.JSONParser;
import net.minidev.json.parser.ParseException;

import static net.minidev.json.parser.JSONParser.DEFAULT_PERMISSIVE_MODE;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;

import org.junit.jupiter.api.Test;

Expand All @@ -28,7 +30,27 @@ public void stressTest() throws Exception {
assertEquals(e.getErrorType(), ParseException.ERROR_UNEXPECTED_JSON_DEPTH);
return;
}
assertTrue(false);
fail();
}

@Test
public void shouldNotFailWhenInfiniteJsonDepth() throws Exception {
int size = 500;
StringBuilder sb = new StringBuilder(10 + size*4);
for (int i=0; i < size; i++) {
sb.append("{a:");
}
sb.append("true");
for (int i=0; i < size; i++) {
sb.append("}");
}
String s = sb.toString();
try {
JSONParser parser = new JSONParser(DEFAULT_PERMISSIVE_MODE & ~JSONParser.FINITE_JSON_DEPTH);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why FINITE_JSON_DEPTH could not benefit of an import static wherever DEFAULT_PERMISSIVE_MODE can.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DEFAULT_PERMISSIVE_MODE & ~FINITE_JSON_DEPTH ?
should be:
DEFAULT_PERMISSIVE_MODE | FINITE_JSON_DEPTH ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not remember this code, but I think that the default parser value is 0
...
So the issue is that the flag should be call UNLIMITED_JSON_DEPTH and do the opposite.
The limit is enabled by default for now, and can be disabled in some rare cases.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to the fixed version should be: DEFAULT_PERMISSIVE_MODE | UNLIMITED_JSON_DEPTH

parser.parse(s, JSONValue.defaultReader.DEFAULT);
} catch (ParseException e) {
fail();
}
}

@Test
Expand Down