Skip to content

Commit

Permalink
Merge pull request #26 from nucleussoftwareopen/hjson-3.0
Browse files Browse the repository at this point in the history
Fixing vulnerability CVE-2023-34620 in hjson library by adding the implementation of maximum depth while parsing input JSON or Hjson.
  • Loading branch information
trobro authored Aug 12, 2023
2 parents f7489df + 91bef05 commit 4c387d8
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 13 deletions.
28 changes: 22 additions & 6 deletions src/main/org/hjson/HjsonParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class HjsonParser {
private StringBuilder captureBuffer, peek;
private boolean capture;
private boolean legacyRoot;
private static final int MAX_DEPTH=1000;

private IHjsonDsfProvider[] dsfProviders;

Expand Down Expand Up @@ -111,14 +112,25 @@ JsonValue checkTrailing(JsonValue v) throws ParseException, IOException {
return v;
}

private JsonValue readValue() throws IOException {
private JsonValue readValue() throws IOException, ParseException {
return readValue(0);
}

private JsonValue readValue(int depth) throws IOException, ParseException {
/* The following has been refrenced for the resolution of the vulnerability:
https://github.com/FasterXML/jackson-databind/commit/fcfc4998ec23f0b1f7f8a9521c2b317b6c25892b
*/
if(depth>MAX_DEPTH) {
throw error("The passed json has exhausted the depth supported of "+MAX_DEPTH+".");
}
switch(current) {
case '\'':
case '"': return readString();
case '[': return readArray();
case '{': return readObject(false);
case '[': return readArray(depth + 1);
case '{': return readObject(false, depth + 1);
default: return readTfnns();
}

}

private JsonValue readTfnns() throws IOException {
Expand Down Expand Up @@ -161,7 +173,7 @@ private JsonValue readTfnns() throws IOException {
}
}

private JsonArray readArray() throws IOException {
private JsonArray readArray(int depth) throws IOException {
read();
JsonArray array=new JsonArray();
skipWhiteSpace();
Expand All @@ -170,7 +182,7 @@ private JsonArray readArray() throws IOException {
}
while (true) {
skipWhiteSpace();
array.add(readValue());
array.add(readValue(depth));
skipWhiteSpace();
if (readIf(',')) skipWhiteSpace(); // , is optional
if (readIf(']')) break;
Expand All @@ -180,6 +192,10 @@ private JsonArray readArray() throws IOException {
}

private JsonObject readObject(boolean objectWithoutBraces) throws IOException {
return this.readObject(objectWithoutBraces, 0);
}

private JsonObject readObject(boolean objectWithoutBraces, int depth) throws IOException, ParseException {
if (!objectWithoutBraces) read();
JsonObject object=new JsonObject();
skipWhiteSpace();
Expand All @@ -196,7 +212,7 @@ private JsonObject readObject(boolean objectWithoutBraces) throws IOException {
throw expected("':'");
}
skipWhiteSpace();
object.add(name, readValue());
object.add(name, readValue(depth));
skipWhiteSpace();
if (readIf(',')) skipWhiteSpace(); // , is optional
}
Expand Down
26 changes: 19 additions & 7 deletions src/main/org/hjson/JsonParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class JsonParser {
private int current;
private StringBuilder captureBuffer;
private int captureStart;
private static final int MAX_DEPTH=1000;

/*
* | bufferOffset
Expand Down Expand Up @@ -77,7 +78,18 @@ JsonValue parse() throws IOException {
return result;
}

private JsonValue readValue() throws IOException {
private JsonValue readValue() throws IOException{
return readValue(0);
}


private JsonValue readValue(int depth) throws IOException {
/* The following has been refrenced for the resolution of the vulnerability:
https://github.com/FasterXML/jackson-databind/commit/fcfc4998ec23f0b1f7f8a9521c2b317b6c25892b
*/
if(depth>MAX_DEPTH) {
throw error("The passed json has exhausted the maximum supported depth of "+MAX_DEPTH+".");
}
switch(current) {
case 'n':
return readNull();
Expand All @@ -88,9 +100,9 @@ private JsonValue readValue() throws IOException {
case '"':
return readString();
case '[':
return readArray();
return readArray(depth + 1);
case '{':
return readObject();
return readObject(depth + 1);
case '-':
case '0':
case '1':
Expand All @@ -108,7 +120,7 @@ private JsonValue readValue() throws IOException {
}
}

private JsonArray readArray() throws IOException {
private JsonArray readArray(int depth) throws IOException {
read();
JsonArray array=new JsonArray();
skipWhiteSpace();
Expand All @@ -117,7 +129,7 @@ private JsonArray readArray() throws IOException {
}
do {
skipWhiteSpace();
array.add(readValue());
array.add(readValue(depth));
skipWhiteSpace();
} while (readIf(','));
if (!readIf(']')) {
Expand All @@ -126,7 +138,7 @@ private JsonArray readArray() throws IOException {
return array;
}

private JsonObject readObject() throws IOException {
private JsonObject readObject(int depth) throws IOException {
read();
JsonObject object=new JsonObject();
skipWhiteSpace();
Expand All @@ -141,7 +153,7 @@ private JsonObject readObject() throws IOException {
throw expected("':'");
}
skipWhiteSpace();
object.add(name, readValue());
object.add(name, readValue(depth));
skipWhiteSpace();
} while (readIf(','));
if (!readIf('}')) {
Expand Down

0 comments on commit 4c387d8

Please sign in to comment.