20
20
* </li>
21
21
* <li>Maximum Nesting depth: default 1000 (see {@link #DEFAULT_MAX_DEPTH})
22
22
* </li>
23
+ * <li>Maximum Document length: default {@code unlimited} (coded as {@code -1},
24
+ * (see {@link #DEFAULT_MAX_DOC_LEN})
25
+ * </li>
23
26
* </ul>
24
27
*
25
28
* @since 2.15
@@ -35,7 +38,13 @@ public class StreamReadConstraints
35
38
public static final int DEFAULT_MAX_DEPTH = 1000 ;
36
39
37
40
/**
38
- * Default setting for maximum number length: see {@link Builder#maxNumberLength(int)} for details.
41
+ * Default setting for maximum document length:
42
+ * see {@link Builder#maxDocumentLength} for details.
43
+ */
44
+ public static final long DEFAULT_MAX_DOC_LEN = -1L ;
45
+
46
+ /**
47
+ * @since 2.16
39
48
*/
40
49
public static final int DEFAULT_MAX_NUM_LEN = 1000 ;
41
50
@@ -64,13 +73,16 @@ public class StreamReadConstraints
64
73
private static final int MAX_BIGINT_SCALE_MAGNITUDE = 100_000 ;
65
74
66
75
protected final int _maxNestingDepth ;
76
+ protected final long _maxDocLen ;
77
+
67
78
protected final int _maxNumLen ;
68
79
protected final int _maxStringLen ;
69
80
protected final int _maxNameLen ;
70
81
71
82
private static StreamReadConstraints DEFAULT =
72
- new StreamReadConstraints (DEFAULT_MAX_DEPTH , DEFAULT_MAX_NUM_LEN ,
73
- DEFAULT_MAX_STRING_LEN , DEFAULT_MAX_NAME_LEN );
83
+ new StreamReadConstraints (DEFAULT_MAX_DEPTH ,
84
+ DEFAULT_MAX_DOC_LEN ,
85
+ DEFAULT_MAX_NUM_LEN , DEFAULT_MAX_STRING_LEN , DEFAULT_MAX_NAME_LEN );
74
86
75
87
/**
76
88
* Override the default StreamReadConstraints. These defaults are only used when {@link JsonFactory}
@@ -91,13 +103,15 @@ public class StreamReadConstraints
91
103
*/
92
104
public static void overrideDefaultStreamReadConstraints (final StreamReadConstraints streamReadConstraints ) {
93
105
if (streamReadConstraints == null ) {
94
- DEFAULT = new StreamReadConstraints (DEFAULT_MAX_DEPTH , DEFAULT_MAX_NUM_LEN , DEFAULT_MAX_STRING_LEN );
106
+ DEFAULT = new StreamReadConstraints (DEFAULT_MAX_DEPTH , DEFAULT_MAX_DOC_LEN ,
107
+ DEFAULT_MAX_NUM_LEN , DEFAULT_MAX_STRING_LEN );
95
108
} else {
96
109
DEFAULT = streamReadConstraints ;
97
110
}
98
111
}
99
112
100
113
public static final class Builder {
114
+ private long maxDocLen ;
101
115
private int maxNestingDepth ;
102
116
private int maxNumLen ;
103
117
private int maxStringLen ;
@@ -120,6 +134,28 @@ public Builder maxNestingDepth(final int maxNestingDepth) {
120
134
return this ;
121
135
}
122
136
137
+ /**
138
+ * Sets the maximum allowed document length (for positive values over 0) or
139
+ * indicate that any length is acceptable ({@code 0} or negative number).
140
+ * The length is in input units of the input source, that is, in
141
+ * {@code byte}s or {@code char}s.
142
+ *
143
+ * @param maxDocLen the maximum allowed document if positive number above 0; otherwise
144
+ * ({@code 0} or negative number) means "unlimited".
145
+ *
146
+ * @return this builder
147
+ *
148
+ * @since 2.16
149
+ */
150
+ public Builder maxDocumentLength (long maxDocLen ) {
151
+ // Negative values and 0 mean "unlimited", mark with -1L
152
+ if (maxDocLen <= 0L ) {
153
+ maxDocLen = -1L ;
154
+ }
155
+ this .maxDocLen = maxDocLen ;
156
+ return this ;
157
+ }
158
+
123
159
/**
124
160
* Sets the maximum number length (in chars or bytes, depending on input context).
125
161
* The default is 1000.
@@ -184,25 +220,30 @@ public Builder maxNameLength(final int maxNameLen) {
184
220
}
185
221
186
222
Builder () {
187
- this (DEFAULT_MAX_DEPTH , DEFAULT_MAX_NUM_LEN , DEFAULT_MAX_STRING_LEN , DEFAULT_MAX_NAME_LEN );
223
+ this (DEFAULT_MAX_DEPTH , DEFAULT_MAX_DOC_LEN ,
224
+ DEFAULT_MAX_NUM_LEN , DEFAULT_MAX_STRING_LEN , DEFAULT_MAX_NAME_LEN );
188
225
}
189
226
190
- Builder (final int maxNestingDepth , final int maxNumLen , final int maxStringLen , final int maxNameLen ) {
227
+ Builder (final int maxNestingDepth , final long maxDocLen ,
228
+ final int maxNumLen , final int maxStringLen , final int maxNameLen ) {
191
229
this .maxNestingDepth = maxNestingDepth ;
230
+ this .maxDocLen = maxDocLen ;
192
231
this .maxNumLen = maxNumLen ;
193
232
this .maxStringLen = maxStringLen ;
194
233
this .maxNameLen = maxNameLen ;
195
234
}
196
235
197
236
Builder (StreamReadConstraints src ) {
198
237
maxNestingDepth = src ._maxNestingDepth ;
238
+ maxDocLen = src ._maxDocLen ;
199
239
maxNumLen = src ._maxNumLen ;
200
240
maxStringLen = src ._maxStringLen ;
201
241
maxNameLen = src ._maxNameLen ;
202
242
}
203
243
204
244
public StreamReadConstraints build () {
205
- return new StreamReadConstraints (maxNestingDepth , maxNumLen , maxStringLen , maxNameLen );
245
+ return new StreamReadConstraints (maxNestingDepth , maxDocLen ,
246
+ maxNumLen , maxStringLen , maxNameLen );
206
247
}
207
248
}
208
249
@@ -213,13 +254,19 @@ public StreamReadConstraints build() {
213
254
*/
214
255
215
256
@ Deprecated // since 2.16
216
- protected StreamReadConstraints (final int maxNestingDepth , final int maxNumLen , final int maxStringLen ) {
217
- this (maxNestingDepth , maxNumLen , maxStringLen , DEFAULT_MAX_NAME_LEN );
257
+ protected StreamReadConstraints (final int maxNestingDepth , final long maxDocLen ,
258
+ final int maxNumLen , final int maxStringLen ) {
259
+ this (maxNestingDepth , DEFAULT_MAX_DOC_LEN ,
260
+ maxNumLen , maxStringLen , DEFAULT_MAX_NAME_LEN );
218
261
}
219
262
220
- protected StreamReadConstraints (final int maxNestingDepth , final int maxNumLen ,
221
- final int maxStringLen , final int maxNameLen ) {
263
+ /**
264
+ * @since 2.16
265
+ */
266
+ protected StreamReadConstraints (final int maxNestingDepth , final long maxDocLen ,
267
+ final int maxNumLen , final int maxStringLen , final int maxNameLen ) {
222
268
_maxNestingDepth = maxNestingDepth ;
269
+ _maxDocLen = maxDocLen ;
223
270
_maxNumLen = maxNumLen ;
224
271
_maxStringLen = maxStringLen ;
225
272
_maxNameLen = maxNameLen ;
@@ -261,6 +308,16 @@ public int getMaxNestingDepth() {
261
308
return _maxNestingDepth ;
262
309
}
263
310
311
+ /**
312
+ * Accessor for maximum document length.
313
+ * see {@link Builder#maxDocumentLength(long)} for details.
314
+ *
315
+ * @return Maximum allowed depth
316
+ */
317
+ public long getMaxDocumentLength () {
318
+ return _maxDocLen ;
319
+ }
320
+
264
321
/**
265
322
* Accessor for maximum length of numbers to decode.
266
323
* see {@link Builder#maxNumberLength(int)} for details.
@@ -318,6 +375,31 @@ public void validateNestingDepth(int depth) throws StreamConstraintsException
318
375
}
319
376
}
320
377
378
+ /**
379
+ * Convenience method that can be used to verify that the
380
+ * document length does not exceed the maximum specified by this
381
+ * constraints object (if any): if it does, a
382
+ * {@link StreamConstraintsException}
383
+ * is thrown.
384
+ *
385
+ * @param len Current length of processed document content
386
+ *
387
+ * @throws StreamConstraintsException If length exceeds maximum
388
+ *
389
+ * @since 2.16
390
+ */
391
+ public void validateDocumentLength (long len ) throws StreamConstraintsException
392
+ {
393
+ if ((len > _maxDocLen )
394
+ // Note: -1L used as marker for "unlimited"
395
+ && (_maxDocLen > 0L )) {
396
+ throw _constructException (
397
+ "Document nesting depth (%d) exceeds the maximum allowed (%d, from %s)" ,
398
+ len , _maxDocLen ,
399
+ _constrainRef ("getMaxDocumentLength" ));
400
+ }
401
+ }
402
+
321
403
/*
322
404
/**********************************************************************
323
405
/* Convenience methods for validation, token lengths
0 commit comments