Skip to content

Commit 4022bfa

Browse files
committed
Merge branch '2.15'
2 parents 419aa54 + 71fa3a8 commit 4022bfa

File tree

4 files changed

+127
-5
lines changed

4 files changed

+127
-5
lines changed

cbor/src/main/java/tools/jackson/dataformat/cbor/CBORParser.java

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -696,7 +696,7 @@ public JsonToken nextToken() throws JacksonException
696696
if (!_tagValues.isEmpty()) {
697697
return _handleTaggedArray(_tagValues, len);
698698
}
699-
_streamReadContext = _streamReadContext.createChildArrayContext(len);
699+
createChildArrayContext(len);
700700
}
701701
return (_currToken = JsonToken.START_ARRAY);
702702

@@ -705,7 +705,7 @@ public JsonToken nextToken() throws JacksonException
705705
_currToken = JsonToken.START_OBJECT;
706706
{
707707
int len = _decodeExplicitLength(lowBits);
708-
_streamReadContext = _streamReadContext.createChildObjectContext(len);
708+
createChildObjectContext(len);
709709
}
710710
return _currToken;
711711

@@ -893,7 +893,7 @@ protected JsonToken _handleTaggedArray(TagList tags, int len) throws JacksonExce
893893
// For simplicity, let's create matching array context -- in perfect
894894
// world that wouldn't be necessarily, but in this one there are
895895
// some constraints that make it necessary
896-
_streamReadContext = _streamReadContext.createChildArrayContext(len);
896+
createChildArrayContext(len);
897897

898898
// BigDecimal is the only thing we know for sure
899899
if (!tags.contains(CBORConstants.TAG_DECIMAL_FRACTION)) {
@@ -1796,15 +1796,15 @@ public String nextTextValue() throws JacksonException
17961796
_currToken = JsonToken.START_ARRAY;
17971797
{
17981798
int len = _decodeExplicitLength(lowBits);
1799-
_streamReadContext = _streamReadContext.createChildArrayContext(len);
1799+
createChildArrayContext(len);
18001800
}
18011801
return null;
18021802

18031803
case 5: // Object
18041804
_currToken = JsonToken.START_OBJECT;
18051805
{
18061806
int len = _decodeExplicitLength(lowBits);
1807-
_streamReadContext = _streamReadContext.createChildObjectContext(len);
1807+
createChildObjectContext(len);
18081808
}
18091809
return null;
18101810

@@ -4147,4 +4147,14 @@ private final BigInteger _bigNegative(long l) {
41474147
BigInteger unsignedBase = _bigPositive(l);
41484148
return unsignedBase.negate().subtract(BigInteger.ONE);
41494149
}
4150+
4151+
private void createChildArrayContext(final int len) throws JacksonException {
4152+
_streamReadContext = _streamReadContext.createChildArrayContext(len);
4153+
streamReadConstraints().validateNestingDepth(_streamReadContext.getNestingDepth());
4154+
}
4155+
4156+
private void createChildObjectContext(final int len) throws JacksonException {
4157+
_streamReadContext = _streamReadContext.createChildObjectContext(len);
4158+
streamReadConstraints().validateNestingDepth(_streamReadContext.getNestingDepth());
4159+
}
41504160
}

cbor/src/main/java/tools/jackson/dataformat/cbor/CBORReadContext.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ public CBORReadContext(CBORReadContext parent, DupDetector dups,
5757
_type = type;
5858
_expEntryCount = expEntryCount;
5959
_index = -1;
60+
_nestingDepth = parent == null ? 0 : parent._nestingDepth + 1;
6061
}
6162

6263
protected void reset(int type, int expEntryCount)

cbor/src/test/java/tools/jackson/dataformat/cbor/CBORTestBase.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ public abstract class CBORTestBase
5959
protected CBORParser cborParser(ByteArrayOutputStream bytes) {
6060
return cborParser(bytes.toByteArray());
6161
}
62+
protected CBORParser cborParser(CBORFactory cborFactory, ByteArrayOutputStream bytes) throws IOException {
63+
return cborParser(cborFactory, bytes.toByteArray());
64+
}
6265

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

0 commit comments

Comments
 (0)