@@ -41,6 +41,7 @@ public class WellKnownText {
41
41
public static final String RPAREN = ")" ;
42
42
public static final String COMMA = "," ;
43
43
public static final String NAN = "NaN" ;
44
+ public static final int MAX_NESTED_DEPTH = 1000 ;
44
45
45
46
private static final String NUMBER = "<NUMBER>" ;
46
47
private static final String EOF = "END-OF-STREAM" ;
@@ -233,7 +234,7 @@ public static Geometry fromWKT(GeometryValidator validator, boolean coerce, Stri
233
234
tokenizer .whitespaceChars ('\r' , '\r' );
234
235
tokenizer .whitespaceChars ('\n' , '\n' );
235
236
tokenizer .commentChar ('#' );
236
- Geometry geometry = parseGeometry (tokenizer , coerce );
237
+ Geometry geometry = parseGeometry (tokenizer , coerce , 0 );
237
238
validator .validate (geometry );
238
239
return geometry ;
239
240
} finally {
@@ -244,7 +245,7 @@ public static Geometry fromWKT(GeometryValidator validator, boolean coerce, Stri
244
245
/**
245
246
* parse geometry from the stream tokenizer
246
247
*/
247
- private static Geometry parseGeometry (StreamTokenizer stream , boolean coerce ) throws IOException , ParseException {
248
+ private static Geometry parseGeometry (StreamTokenizer stream , boolean coerce , int depth ) throws IOException , ParseException {
248
249
final String type = nextWord (stream ).toLowerCase (Locale .ROOT );
249
250
switch (type ) {
250
251
case "point" :
@@ -262,22 +263,25 @@ private static Geometry parseGeometry(StreamTokenizer stream, boolean coerce) th
262
263
case "bbox" :
263
264
return parseBBox (stream );
264
265
case "geometrycollection" :
265
- return parseGeometryCollection (stream , coerce );
266
+ return parseGeometryCollection (stream , coerce , depth + 1 );
266
267
case "circle" : // Not part of the standard, but we need it for internal serialization
267
268
return parseCircle (stream );
268
269
}
269
270
throw new IllegalArgumentException ("Unknown geometry type: " + type );
270
271
}
271
272
272
- private static GeometryCollection <Geometry > parseGeometryCollection (StreamTokenizer stream , boolean coerce ) throws IOException ,
273
- ParseException {
273
+ private static GeometryCollection <Geometry > parseGeometryCollection (StreamTokenizer stream , boolean coerce , int depth )
274
+ throws IOException , ParseException {
274
275
if (nextEmptyOrOpen (stream ).equals (EMPTY )) {
275
276
return GeometryCollection .EMPTY ;
276
277
}
278
+ if (depth > MAX_NESTED_DEPTH ) {
279
+ throw new ParseException ("maximum nested depth of " + MAX_NESTED_DEPTH + " exceeded" , stream .lineno ());
280
+ }
277
281
List <Geometry > shapes = new ArrayList <>();
278
- shapes .add (parseGeometry (stream , coerce ));
282
+ shapes .add (parseGeometry (stream , coerce , depth ));
279
283
while (nextCloserOrComma (stream ).equals (COMMA )) {
280
- shapes .add (parseGeometry (stream , coerce ));
284
+ shapes .add (parseGeometry (stream , coerce , depth ));
281
285
}
282
286
return new GeometryCollection <>(shapes );
283
287
}
0 commit comments