Skip to content

Commit 04091d3

Browse files
committed
apply recursion limit when skipping fields
Fixes #267
1 parent 221ebbf commit 04091d3

File tree

4 files changed

+26
-15
lines changed

4 files changed

+26
-15
lines changed

prost-derive/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ fn try_message(input: TokenStream) -> Result<TokenStream, Error> {
194194
#struct_name
195195
match tag {
196196
#(#merge)*
197-
_ => ::prost::encoding::skip_field(wire_type, tag, buf),
197+
_ => ::prost::encoding::skip_field(wire_type, tag, buf, ctx),
198198
}
199199
}
200200

src/encoding.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -381,10 +381,11 @@ where
381381
Ok(())
382382
}
383383

384-
pub fn skip_field<B>(wire_type: WireType, tag: u32, buf: &mut B) -> Result<(), DecodeError>
384+
pub fn skip_field<B>(wire_type: WireType, tag: u32, buf: &mut B, ctx: DecodeContext) -> Result<(), DecodeError>
385385
where
386386
B: Buf,
387387
{
388+
ctx.limit_reached()?;
388389
let len = match wire_type {
389390
WireType::Varint => decode_varint(buf).map(|_| 0)?,
390391
WireType::ThirtyTwoBit => 4,
@@ -399,7 +400,7 @@ where
399400
}
400401
break 0;
401402
}
402-
_ => skip_field(inner_wire_type, inner_tag, buf)?,
403+
_ => skip_field(inner_wire_type, inner_tag, buf, ctx.enter_recursion())?,
403404
}
404405
},
405406
WireType::EndGroup => return Err(DecodeError::new("unexpected end group tag")),
@@ -1219,7 +1220,7 @@ macro_rules! map {
12191220
match tag {
12201221
1 => key_merge(wire_type, key, buf, ctx),
12211222
2 => val_merge(wire_type, val, buf, ctx),
1222-
_ => skip_field(wire_type, tag, buf),
1223+
_ => skip_field(wire_type, tag, buf, ctx),
12231224
}
12241225
},
12251226
)?;

src/types.rs

+11-11
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ impl Message for bool {
3838
if tag == 1 {
3939
bool::merge(wire_type, self, buf, ctx)
4040
} else {
41-
skip_field(wire_type, tag, buf)
41+
skip_field(wire_type, tag, buf, ctx)
4242
}
4343
}
4444
fn encoded_len(&self) -> usize {
@@ -76,7 +76,7 @@ impl Message for u32 {
7676
if tag == 1 {
7777
uint32::merge(wire_type, self, buf, ctx)
7878
} else {
79-
skip_field(wire_type, tag, buf)
79+
skip_field(wire_type, tag, buf, ctx)
8080
}
8181
}
8282
fn encoded_len(&self) -> usize {
@@ -114,7 +114,7 @@ impl Message for u64 {
114114
if tag == 1 {
115115
uint64::merge(wire_type, self, buf, ctx)
116116
} else {
117-
skip_field(wire_type, tag, buf)
117+
skip_field(wire_type, tag, buf, ctx)
118118
}
119119
}
120120
fn encoded_len(&self) -> usize {
@@ -152,7 +152,7 @@ impl Message for i32 {
152152
if tag == 1 {
153153
int32::merge(wire_type, self, buf, ctx)
154154
} else {
155-
skip_field(wire_type, tag, buf)
155+
skip_field(wire_type, tag, buf, ctx)
156156
}
157157
}
158158
fn encoded_len(&self) -> usize {
@@ -190,7 +190,7 @@ impl Message for i64 {
190190
if tag == 1 {
191191
int64::merge(wire_type, self, buf, ctx)
192192
} else {
193-
skip_field(wire_type, tag, buf)
193+
skip_field(wire_type, tag, buf, ctx)
194194
}
195195
}
196196
fn encoded_len(&self) -> usize {
@@ -228,7 +228,7 @@ impl Message for f32 {
228228
if tag == 1 {
229229
float::merge(wire_type, self, buf, ctx)
230230
} else {
231-
skip_field(wire_type, tag, buf)
231+
skip_field(wire_type, tag, buf, ctx)
232232
}
233233
}
234234
fn encoded_len(&self) -> usize {
@@ -266,7 +266,7 @@ impl Message for f64 {
266266
if tag == 1 {
267267
double::merge(wire_type, self, buf, ctx)
268268
} else {
269-
skip_field(wire_type, tag, buf)
269+
skip_field(wire_type, tag, buf, ctx)
270270
}
271271
}
272272
fn encoded_len(&self) -> usize {
@@ -304,7 +304,7 @@ impl Message for String {
304304
if tag == 1 {
305305
string::merge(wire_type, self, buf, ctx)
306306
} else {
307-
skip_field(wire_type, tag, buf)
307+
skip_field(wire_type, tag, buf, ctx)
308308
}
309309
}
310310
fn encoded_len(&self) -> usize {
@@ -342,7 +342,7 @@ impl Message for Vec<u8> {
342342
if tag == 1 {
343343
bytes::merge(wire_type, self, buf, ctx)
344344
} else {
345-
skip_field(wire_type, tag, buf)
345+
skip_field(wire_type, tag, buf, ctx)
346346
}
347347
}
348348
fn encoded_len(&self) -> usize {
@@ -369,12 +369,12 @@ impl Message for () {
369369
tag: u32,
370370
wire_type: WireType,
371371
buf: &mut B,
372-
_ctx: DecodeContext,
372+
ctx: DecodeContext,
373373
) -> Result<(), DecodeError>
374374
where
375375
B: Buf,
376376
{
377-
skip_field(wire_type, tag, buf)
377+
skip_field(wire_type, tag, buf, ctx)
378378
}
379379
fn encoded_len(&self) -> usize {
380380
0

tests/src/lib.rs

+10
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,16 @@ mod tests {
462462
};
463463
}
464464

465+
#[test]
466+
fn test_267_regression() {
467+
// Checks that skip_field will error appropriately when given a big stack of StartGroup
468+
// tags.
469+
//
470+
// https://github.com/danburkert/prost/issues/267
471+
let buf = vec![b'C'; 1 << 20];
472+
<() as Message>::decode(&buf[..]).err().unwrap();
473+
}
474+
465475
#[test]
466476
fn test_default_enum() {
467477
let msg = default_enum_value::Test::default();

0 commit comments

Comments
 (0)