Skip to content

Commit 861b53e

Browse files
committed
Merge branch '2.15'
2 parents 4022bfa + c7e1ec9 commit 861b53e

File tree

2 files changed

+124
-2
lines changed

2 files changed

+124
-2
lines changed

smile/src/main/java/tools/jackson/dataformat/smile/SmileParser.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -520,7 +520,7 @@ public JsonToken nextToken() throws JacksonException
520520
}
521521
return _handleSharedString(((ch & 0x3) << 8) + (_inputBuffer[_inputPtr++] & 0xFF));
522522
case 0x18: // START_ARRAY
523-
_streamReadContext = _streamReadContext.createChildArrayContext(-1, -1);
523+
createChildArrayContext(-1, -1);
524524
return (_currToken = JsonToken.START_ARRAY);
525525
case 0x19: // END_ARRAY
526526
if (!_streamReadContext.inArray()) {
@@ -529,7 +529,7 @@ public JsonToken nextToken() throws JacksonException
529529
_streamReadContext = _streamReadContext.getParent();
530530
return (_currToken = JsonToken.END_ARRAY);
531531
case 0x1A: // START_OBJECT
532-
_streamReadContext = _streamReadContext.createChildObjectContext(-1, -1);
532+
createChildObjectContext(-1, -1);
533533
return (_currToken = JsonToken.START_OBJECT);
534534
case 0x1B: // not used in this mode; would be END_OBJECT
535535
throw _constructReadException("Invalid type marker byte 0xFB in value mode (would be END_OBJECT in key mode)");
@@ -3432,5 +3432,15 @@ private final JsonToken _eofAsNextToken() throws JacksonException {
34323432
close();
34333433
return (_currToken = null);
34343434
}
3435+
3436+
private void createChildArrayContext(final int lineNr, final int colNr) throws JacksonException {
3437+
_streamReadContext = _streamReadContext.createChildArrayContext(lineNr, colNr);
3438+
streamReadConstraints().validateNestingDepth(_streamReadContext.getNestingDepth());
3439+
}
3440+
3441+
private void createChildObjectContext(final int lineNr, final int colNr) throws JacksonException {
3442+
_streamReadContext = _streamReadContext.createChildObjectContext(lineNr, colNr);
3443+
streamReadConstraints().validateNestingDepth(_streamReadContext.getNestingDepth());
3444+
}
34353445
}
34363446

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
package tools.jackson.dataformat.smile.dos;
2+
3+
import java.io.ByteArrayOutputStream;
4+
import java.io.IOException;
5+
6+
import tools.jackson.core.*;
7+
import tools.jackson.core.exc.StreamConstraintsException;
8+
import tools.jackson.dataformat.smile.BaseTestForSmile;
9+
import tools.jackson.dataformat.smile.SmileFactory;
10+
import tools.jackson.dataformat.smile.databind.SmileMapper;
11+
12+
/**
13+
* Unit tests for deeply nested JSON
14+
*/
15+
public class DeepNestingParserTest extends BaseTestForSmile
16+
{
17+
SmileMapper DEFAULT_MAPPER = newSmileMapper();
18+
19+
SmileMapper UNCONSTRAINED_MAPPER;
20+
{
21+
SmileFactory smileFactory = SmileFactory.builder()
22+
.streamReadConstraints(StreamReadConstraints.builder().maxNestingDepth(Integer.MAX_VALUE).build())
23+
.build();
24+
UNCONSTRAINED_MAPPER = new SmileMapper(smileFactory);
25+
}
26+
27+
public void testDeeplyNestedObjects() throws Exception
28+
{
29+
final int depth = 1500;
30+
ByteArrayOutputStream out = new ByteArrayOutputStream();
31+
genDeepDoc(out, depth);
32+
try (JsonParser jp = DEFAULT_MAPPER.createParser(out.toByteArray())) {
33+
JsonToken jt;
34+
while ((jt = jp.nextToken()) != null) {
35+
36+
}
37+
fail("expected StreamConstraintsException");
38+
} catch (StreamConstraintsException e) {
39+
assertEquals("Depth (1001) exceeds the maximum allowed nesting depth (1000)", e.getMessage());
40+
}
41+
}
42+
43+
public void testDeeplyNestedObjectsWithUnconstrainedMapper() throws Exception
44+
{
45+
final int depth = 1500;
46+
ByteArrayOutputStream out = new ByteArrayOutputStream();
47+
genDeepDoc(out, depth);
48+
try (JsonParser jp = UNCONSTRAINED_MAPPER.createParser(out.toByteArray())) {
49+
JsonToken jt;
50+
while ((jt = jp.nextToken()) != null) {
51+
52+
}
53+
}
54+
}
55+
56+
public void testDeeplyNestedArrays() throws Exception
57+
{
58+
final int depth = 750;
59+
ByteArrayOutputStream out = new ByteArrayOutputStream();
60+
genDeepArrayDoc(out, depth);
61+
try (JsonParser jp = DEFAULT_MAPPER.createParser(out.toByteArray())) {
62+
JsonToken jt;
63+
while ((jt = jp.nextToken()) != null) {
64+
65+
}
66+
fail("expected StreamConstraintsException");
67+
} catch (StreamConstraintsException e) {
68+
assertEquals("Depth (1001) exceeds the maximum allowed nesting depth (1000)", e.getMessage());
69+
}
70+
}
71+
72+
public void testDeeplyNestedArraysWithUnconstrainedMapper() throws Exception
73+
{
74+
final int depth = 750;
75+
ByteArrayOutputStream out = new ByteArrayOutputStream();
76+
genDeepArrayDoc(out, depth);
77+
try (JsonParser jp = UNCONSTRAINED_MAPPER.createParser(out.toByteArray())) {
78+
JsonToken jt;
79+
while ((jt = jp.nextToken()) != null) {
80+
81+
}
82+
}
83+
}
84+
85+
private void genDeepDoc(final ByteArrayOutputStream out, final int depth) throws IOException {
86+
try (JsonGenerator gen = _smileGenerator(out, true)) {
87+
for (int i = 0; i < depth; i++) {
88+
gen.writeStartObject();
89+
gen.writeName("a");
90+
}
91+
gen.writeString("val");
92+
for (int i = 0; i < depth; i++) {
93+
gen.writeEndObject();
94+
}
95+
}
96+
}
97+
98+
private void genDeepArrayDoc(final ByteArrayOutputStream out, final int depth) throws IOException {
99+
try (JsonGenerator gen = _smileGenerator(out, true)) {
100+
for (int i = 0; i < depth; i++) {
101+
gen.writeStartObject();
102+
gen.writeName("a");
103+
gen.writeStartArray();
104+
}
105+
gen.writeString("val");
106+
for (int i = 0; i < depth; i++) {
107+
gen.writeEndArray();
108+
gen.writeEndObject();
109+
}
110+
}
111+
}
112+
}

0 commit comments

Comments
 (0)