@@ -25,6 +25,11 @@ public class StreamReadConstraints
25
25
{
26
26
private static final long serialVersionUID = 1L ;
27
27
28
+ /**
29
+ * Default setting for maximum depth: see {@link Builder#maxNestingDepth(int)} for details.
30
+ */
31
+ public static final int DEFAULT_MAX_DEPTH = 1000 ;
32
+
28
33
/**
29
34
* Default setting for maximum number length: see {@link Builder#maxNumberLength(int)} for details.
30
35
*/
@@ -35,16 +40,37 @@ public class StreamReadConstraints
35
40
*/
36
41
public static final int DEFAULT_MAX_STRING_LEN = 1_000_000 ;
37
42
43
+ protected final int _maxNestingDepth ;
38
44
protected final int _maxNumLen ;
39
45
protected final int _maxStringLen ;
40
46
41
47
private static final StreamReadConstraints DEFAULT =
42
- new StreamReadConstraints (DEFAULT_MAX_NUM_LEN , DEFAULT_MAX_STRING_LEN );
48
+ new StreamReadConstraints (DEFAULT_MAX_DEPTH , DEFAULT_MAX_NUM_LEN , DEFAULT_MAX_STRING_LEN );
43
49
44
50
public static final class Builder {
51
+ private int maxNestingDepth ;
45
52
private int maxNumLen ;
46
53
private int maxStringLen ;
47
54
55
+ /**
56
+ * Sets the maximum nesting depth. The depth is a count of objects and arrays that have not
57
+ * been closed, `{` and `[` respectively.
58
+ *
59
+ * @param maxNestingDepth the maximum depth
60
+ *
61
+ * @return this builder
62
+ * @throws IllegalArgumentException if the maxNestingDepth is set to a negative value
63
+ *
64
+ * @since 2.15
65
+ */
66
+ public Builder maxNestingDepth (final int maxNestingDepth ) {
67
+ if (maxNestingDepth < 0 ) {
68
+ throw new IllegalArgumentException ("Cannot set maxNestingDepth to a negative value" );
69
+ }
70
+ this .maxNestingDepth = maxNestingDepth ;
71
+ return this ;
72
+ }
73
+
48
74
/**
49
75
* Sets the maximum number length (in chars or bytes, depending on input context).
50
76
* The default is 1000.
@@ -90,21 +116,23 @@ public Builder maxStringLength(final int maxStringLen) {
90
116
}
91
117
92
118
Builder () {
93
- this (DEFAULT_MAX_NUM_LEN , DEFAULT_MAX_STRING_LEN );
119
+ this (DEFAULT_MAX_DEPTH , DEFAULT_MAX_NUM_LEN , DEFAULT_MAX_STRING_LEN );
94
120
}
95
121
96
- Builder (final int maxNumLen , final int maxStringLen ) {
122
+ Builder (final int maxNestingDepth , final int maxNumLen , final int maxStringLen ) {
123
+ this .maxNestingDepth = maxNestingDepth ;
97
124
this .maxNumLen = maxNumLen ;
98
125
this .maxStringLen = maxStringLen ;
99
126
}
100
127
101
128
Builder (StreamReadConstraints src ) {
129
+ maxNestingDepth = src ._maxNestingDepth ;
102
130
maxNumLen = src ._maxNumLen ;
103
131
maxStringLen = src ._maxStringLen ;
104
132
}
105
133
106
134
public StreamReadConstraints build () {
107
- return new StreamReadConstraints (maxNumLen , maxStringLen );
135
+ return new StreamReadConstraints (maxNestingDepth , maxNumLen , maxStringLen );
108
136
}
109
137
}
110
138
@@ -114,7 +142,8 @@ public StreamReadConstraints build() {
114
142
/**********************************************************************
115
143
*/
116
144
117
- StreamReadConstraints (final int maxNumLen , final int maxStringLen ) {
145
+ StreamReadConstraints (final int maxNestingDepth , final int maxNumLen , final int maxStringLen ) {
146
+ _maxNestingDepth = maxNestingDepth ;
118
147
_maxNumLen = maxNumLen ;
119
148
_maxStringLen = maxStringLen ;
120
149
}
@@ -141,6 +170,16 @@ public Builder rebuild() {
141
170
/**********************************************************************
142
171
*/
143
172
173
+ /**
174
+ * Accessor for maximum depth.
175
+ * see {@link Builder#maxNestingDepth(int)} for details.
176
+ *
177
+ * @return Maximum allowed depth
178
+ */
179
+ public int getMaxNestingDepth () {
180
+ return _maxNestingDepth ;
181
+ }
182
+
144
183
/**
145
184
* Accessor for maximum length of numbers to decode.
146
185
* see {@link Builder#maxNumberLength(int)} for details.
@@ -169,7 +208,7 @@ public int getMaxStringLength() {
169
208
170
209
/**
171
210
* Convenience method that can be used to verify that a floating-point
172
- * number of specified length does not exceed maximum specific by this
211
+ * number of specified length does not exceed maximum specified by this
173
212
* constraints object: if it does, a
174
213
* {@link StreamConstraintsException}
175
214
* is thrown.
@@ -223,4 +262,23 @@ public void validateStringLength(int length) throws StreamConstraintsException
223
262
length , _maxStringLen ));
224
263
}
225
264
}
265
+
266
+ /**
267
+ * Convenience method that can be used to verify that the
268
+ * nesting depth does not exceed the maximum specified by this
269
+ * constraints object: if it does, a
270
+ * {@link StreamConstraintsException}
271
+ * is thrown.
272
+ *
273
+ * @param depth count of unclosed objects and arrays
274
+ *
275
+ * @throws StreamConstraintsException If depth exceeds maximum
276
+ */
277
+ public void validateNestingDepth (int depth ) throws StreamConstraintsException
278
+ {
279
+ if (depth > _maxNestingDepth ) {
280
+ throw new StreamConstraintsException (String .format ("Depth (%d) exceeds the maximum allowed nesting depth (%d)" ,
281
+ depth , _maxNestingDepth ));
282
+ }
283
+ }
226
284
}
0 commit comments