-
Notifications
You must be signed in to change notification settings - Fork 382
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add recursion limit #248
add recursion limit #248
Conversation
protobuf/src/stream.rs
Outdated
@@ -31,6 +31,9 @@ use buf_read_iter::BufReadIter; | |||
// `CodedOutputStream` wraps `BufWriter`, it often skips double buffering. | |||
const OUTPUT_STREAM_BUFFER_SIZE: usize = 8 * 1024; | |||
|
|||
// Default recursion level limit. | |||
const DEFAULT_RECURSION_LIMIT: isize = 100; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
100 is just copied from C++ implementation. If you think it's too small, please let me know.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the explanation. Could you please paste the explanation into the source comments?
protobuf/src/stream.rs
Outdated
} | ||
|
||
/// Set the recursion limit. | ||
pub fn set_recursion_limit(&mut self, limit: isize) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Parameter should be u32
probably
- to avoid misunderstanding (negative value is meaningless)
- should be platform-independent
protobuf/src/stream.rs
Outdated
@@ -121,24 +124,54 @@ pub mod wire_format { | |||
|
|||
pub struct CodedInputStream<'a> { | |||
source: BufReadIter<'a>, | |||
recursion_budget: isize, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it should be i32
to make it platform-independent.
protobuf/src/stream.rs
Outdated
} | ||
|
||
// Only for internal tracing | ||
#[doc(hidden)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AFAIU this function can be pub(crate)
instead of public+hidden.
protobuf/src/stream.rs
Outdated
#[inline] | ||
pub fn incr_recursion(&mut self) -> ProtobufResult<()> { | ||
self.recursion_budget -= 1; | ||
if self.recursion_budget < 0 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like there's a bug here: if we hit recursion_limit
, we've lost the budget. Should probably be:
if self.recursion_budget <= 0 { return error; }
self.recursion_budget -= 1;
Ok(())
assert_eq!(test3, t); | ||
|
||
is = CodedInputStream::from_bytes(&bytes); | ||
is.set_recursion_limit(0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally this should be tested with recursion level = 3 or something like that, so that read with 2 is OK and read with 3 returns error to really check that code didn't mess with signs or something like that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for patch! It's important missing part of the implementation.
I've added a couple of suggestions, would be mind addressing them?
Thank you! |
Provide a way to configure recursion limit so invalid messages or deeply nested messages won't lead to stack overflow, which has no way to recover.