@@ -94,6 +94,7 @@ impl<Iter> de::Deserializer for Deserializer<Iter>
94
94
struct DeserializerImpl < R : Read > {
95
95
read : R ,
96
96
str_buf : Vec < u8 > ,
97
+ remaining_depth : u8 ,
97
98
}
98
99
99
100
macro_rules! overflow {
@@ -107,6 +108,7 @@ impl<R: Read> DeserializerImpl<R> {
107
108
DeserializerImpl {
108
109
read : read,
109
110
str_buf : Vec :: with_capacity ( 128 ) ,
111
+ remaining_depth : 128 ,
110
112
}
111
113
}
112
114
@@ -205,12 +207,30 @@ impl<R: Read> DeserializerImpl<R> {
205
207
visitor. visit_str ( s)
206
208
}
207
209
b'[' => {
210
+ self . remaining_depth -= 1 ;
211
+ if self . remaining_depth == 0 {
212
+ return Err ( self . peek_error ( stack_overflow ( ) ) ) ;
213
+ }
214
+
208
215
self . eat_char ( ) ;
209
- visitor. visit_seq ( SeqVisitor :: new ( self ) )
216
+ let ret = visitor. visit_seq ( SeqVisitor :: new ( self ) ) ;
217
+
218
+ self . remaining_depth += 1 ;
219
+
220
+ ret
210
221
}
211
222
b'{' => {
223
+ self . remaining_depth -= 1 ;
224
+ if self . remaining_depth == 0 {
225
+ return Err ( self . peek_error ( stack_overflow ( ) ) ) ;
226
+ }
227
+
212
228
self . eat_char ( ) ;
213
- visitor. visit_map ( MapVisitor :: new ( self ) )
229
+ let ret = visitor. visit_map ( MapVisitor :: new ( self ) ) ;
230
+
231
+ self . remaining_depth += 1 ;
232
+
233
+ ret
214
234
}
215
235
_ => Err ( self . peek_error ( ErrorCode :: ExpectedSomeValue ) ) ,
216
236
} ;
@@ -523,6 +543,10 @@ impl<R: Read> DeserializerImpl<R> {
523
543
}
524
544
}
525
545
546
+ fn stack_overflow ( ) -> ErrorCode {
547
+ ErrorCode :: Custom ( "recursion limit exceeded" . into ( ) )
548
+ }
549
+
526
550
static POW10 : [ f64 ; 309 ] =
527
551
[ 1e000 , 1e001 , 1e002 , 1e003 , 1e004 , 1e005 , 1e006 , 1e007 , 1e008 , 1e009 ,
528
552
1e010 , 1e011 , 1e012 , 1e013 , 1e014 , 1e015 , 1e016 , 1e017 , 1e018 , 1e019 ,
@@ -610,12 +634,15 @@ impl<R: Read> de::Deserializer for DeserializerImpl<R> {
610
634
611
635
match try!( self . peek_or_null ( ) ) {
612
636
b'{' => {
637
+ self . remaining_depth -= 1 ;
638
+ if self . remaining_depth == 0 {
639
+ return Err ( self . peek_error ( stack_overflow ( ) ) ) ;
640
+ }
641
+
613
642
self . eat_char ( ) ;
614
- try!( self . parse_whitespace ( ) ) ;
643
+ let value = try!( visitor . visit ( VariantVisitor :: new ( self ) ) ) ;
615
644
616
- let value = {
617
- try!( visitor. visit ( VariantVisitor :: new ( self ) ) )
618
- } ;
645
+ self . remaining_depth += 1 ;
619
646
620
647
try!( self . parse_whitespace ( ) ) ;
621
648
0 commit comments