47
47
*/
48
48
class JsonValueWriter {
49
49
50
+ private static final int DEFAULT_MAX_NESTING_DEPTH = 500 ;
51
+
50
52
private final Appendable out ;
51
53
54
+ private final int maxNestingDepth ;
55
+
52
56
private MemberPath path = MemberPath .ROOT ;
53
57
54
58
private final Deque <JsonWriterFiltersAndProcessors > filtersAndProcessors = new ArrayDeque <>();
@@ -60,7 +64,18 @@ class JsonValueWriter {
60
64
* @param out the {@link Appendable} used to receive the JSON output
61
65
*/
62
66
JsonValueWriter (Appendable out ) {
67
+ this (out , DEFAULT_MAX_NESTING_DEPTH );
68
+ }
69
+
70
+ /**
71
+ * Create a new {@link JsonValueWriter} instance.
72
+ * @param out the {@link Appendable} used to receive the JSON output
73
+ * @param maxNestingDepth the maximum allowed nesting depth for JSON objects and
74
+ * arrays
75
+ */
76
+ JsonValueWriter (Appendable out , int maxNestingDepth ) {
63
77
this .out = out ;
78
+ this .maxNestingDepth = maxNestingDepth ;
64
79
}
65
80
66
81
void pushProcessors (JsonWriterFiltersAndProcessors jsonProcessors ) {
@@ -115,10 +130,7 @@ else if (value instanceof WritableJson writableJson) {
115
130
throw new UncheckedIOException (ex );
116
131
}
117
132
}
118
- else if (value instanceof Path p ) {
119
- writeString (p .toString ());
120
- }
121
- else if (value instanceof Iterable <?> iterable ) {
133
+ else if (value instanceof Iterable <?> iterable && canWriteAsArray (iterable )) {
122
134
writeArray (iterable ::forEach );
123
135
}
124
136
else if (ObjectUtils .isArray (value )) {
@@ -135,6 +147,10 @@ else if (value instanceof Number || value instanceof Boolean) {
135
147
}
136
148
}
137
149
150
+ private <V > boolean canWriteAsArray (Iterable <?> iterable ) {
151
+ return !(iterable instanceof Path );
152
+ }
153
+
138
154
/**
139
155
* Start a new {@link Series} (JSON object or array).
140
156
* @param series the series to start
@@ -144,6 +160,10 @@ else if (value instanceof Number || value instanceof Boolean) {
144
160
*/
145
161
void start (Series series ) {
146
162
if (series != null ) {
163
+ int nestingDepth = this .activeSeries .size ();
164
+ Assert .state (nestingDepth <= this .maxNestingDepth ,
165
+ () -> "JSON nesting depth (%s) exceeds maximum depth of %s (current path: %s)"
166
+ .formatted (nestingDepth , this .maxNestingDepth , this .path ));
147
167
this .activeSeries .push (new ActiveSeries (series ));
148
168
append (series .openChar );
149
169
}
0 commit comments