Support custom recursion limits at build time - #785
seanlinsley wants to merge 1 commit into
Conversation
b2bb84c to
9a50224
Compare
|
thoughts @LucioFranco @nrc @danburkert? |
| // See `encoding::DecodeContext` for more info. | ||
| // 100 is the default recursion limit in the C++ implementation. | ||
| #[cfg(not(feature = "no-recursion-limit"))] | ||
| const RECURSION_LIMIT: u32 = 100; |
There was a problem hiding this comment.
Since it sounds like this will never change, I opted to inline it everywhere it's used. That allows documentation to say explicitly that the default recursion limit is 100 instead of requiring that users look up this constant.
There was a problem hiding this comment.
I actually kinda like having this as a constant. I wonder if we could just make a constants module that contains just this one. And we can then have all the deep dive docs on the recursion implementation there and then we just need to link to there from the lib doc page. I feel like that would make it easier to maintain down the line and centralize it a bit.
There was a problem hiding this comment.
🤷 I'm not sure if a constants module adds much. If you still feel a constant is necessary, I'd lean towards simply adding back the constant here in lib.rs
There was a problem hiding this comment.
I like it to be a constant as well. It makes it explicit in the code. But I do like it to be in the documentation as well.
|
Here's a downstream PR using this feature: pganalyze/pg_query.rs#17 Note that to prevent a stack overflow from the recursion, I had to increase the stack size in a separate thread. I wonder if that should be documented here. |
LucioFranco
left a comment
There was a problem hiding this comment.
Overall LGTM! Some small suggestions and we can get this merged. Thanks for the patience I went on vacation in between :)
|
@LucioFranco this should be ready for re-review |
|
@LucioFranco ping. happy to make any other changes if needed |
LucioFranco
left a comment
There was a problem hiding this comment.
Sorry for the super long delay on the review here and thank you for the ping (I generally don't mind them if you're waiting for a review). I left a few comments that I would like to see changed but they are pretty minor and I think once those are good we are good to merge. Thank you for pushing through on this!
| // See `encoding::DecodeContext` for more info. | ||
| // 100 is the default recursion limit in the C++ implementation. | ||
| #[cfg(not(feature = "no-recursion-limit"))] | ||
| const RECURSION_LIMIT: u32 = 100; |
There was a problem hiding this comment.
I actually kinda like having this as a constant. I wonder if we could just make a constants module that contains just this one. And we can then have all the deep dive docs on the recursion implementation there and then we just need to link to there from the lib doc page. I feel like that would make it easier to maintain down the line and centralize it a bit.
08caf43 to
7fc6689
Compare
caspermeijn
left a comment
There was a problem hiding this comment.
Thank you for coming back to this after two years. I see why this is useful and this is a smart solution.
I am a bit concerned whether this could be a breaking change. I would like to see some prove that it is not.
| #(#clear;)* | ||
| } | ||
|
|
||
| fn recursion_limit() -> u32 { |
There was a problem hiding this comment.
Is this a breaking change for messages with a field named recursion_limit?
I think for enum fields, an accessor is created. However, this function is in a trait, so not directly accessible.
I would like to see a test case for that.
There was a problem hiding this comment.
I'm not sure I follow: how could this possibly affect a field named recursion_limit? This is implemented on the Message trait, not on the struct itself.
There was a problem hiding this comment.
Sorry for another long delay. Well, if a .proto file has a enum field named recursion_limit, it will generate a function named recursion_limit() on the struct. I would like to see a test that proved that the struct function can still be called.
There was a problem hiding this comment.
This is tested in tests/src/recursion_limit_field.rs
| /// or it can be disabled entirely using the `no-recursion-limit` feature. | ||
| #[cfg(not(feature = "no-recursion-limit"))] | ||
| recurse_count: u32, | ||
| #[doc(hidden)] |
There was a problem hiding this comment.
Why is this marked as doc hidden?
There was a problem hiding this comment.
@LucioFranco previously suggested that it should be doc(hidden) because the field was changed to public. I assume a previous version of this PR needed it to be public but it seems like it's no longer needed. I'll revert this field back to private.
There was a problem hiding this comment.
Yes, private is better. My experience is that pub and doc(hidden) makes a sort of secret public API. That will be used by someone.
caspermeijn
left a comment
There was a problem hiding this comment.
Thank you for your contribution and patience. The code needs a rebase with master.
| /// or it can be disabled entirely using the `no-recursion-limit` feature. | ||
| #[cfg(not(feature = "no-recursion-limit"))] | ||
| recurse_count: u32, | ||
| #[doc(hidden)] |
There was a problem hiding this comment.
Yes, private is better. My experience is that pub and doc(hidden) makes a sort of secret public API. That will be used by someone.
| // See `encoding::DecodeContext` for more info. | ||
| // 100 is the default recursion limit in the C++ implementation. | ||
| #[cfg(not(feature = "no-recursion-limit"))] | ||
| const RECURSION_LIMIT: u32 = 100; |
There was a problem hiding this comment.
I like it to be a constant as well. It makes it explicit in the code. But I do like it to be in the documentation as well.
| .iter() | ||
| .any(|a| a.path().is_ident("prost") && a.parse_args::<skip_debug>().is_ok()); | ||
|
|
||
| let mut recursion_limit: u32 = 100; |
There was a problem hiding this comment.
I think the default should not be named here. If the attribute is not set, then no code should be generated. Which automatically chooses the default implementation of the trait. This makes sure that prost-derive doesn't have to know about the default value,
86b9439 to
caf2b36
Compare
caf2b36 to
85a5c52
Compare
|
@caspermeijn all review comments should be addressed |
This PR allows users to set a custom recursion limit for specific protobuf structures at build time: