-
Notifications
You must be signed in to change notification settings - Fork 703
[types] limit nesting of types via state #529
Conversation
This is an alternative version of what move-language#528 and the previous for limitation of nesting provides. This approach installs custom serializers at the recursion points of the `TypeTag` enum. Those serializer use a thread local to track the nesting of the type tag, both for serialization and deserialization. The usage of a thread local is safe and a common technique to provide extra state for implementations which miss it (e.g. serde). A given thread has a single execution stack and this will always count the depth counter consistently up and down. Because Rust has no exceptions are other exit points, this cannot be corrupted. Possibly, thread locals may cause inefficiency. However, we expect TypeTags to be small (a few constructors, limited nestings). The technique used for type tags can be generalized for any other recursive type if needed. Eventually, we hope serde will support per-type nesting, and possibly we should talk with the author if we can add it ourselves. This uses and passes the tests from move-language#528.
|
I'll just leave a note: The use of thread local storage is difficult to evaluate for me. And of course I wish (as I am sure we all do) that it was easy to pass a custom value on the stack, basically what the visitor pattern allows but without the insanity of the visitor pattern. Anyway, enough of wishful thinking... With nesting being a global property, a TLS seems fine, not sure that will always be true and that is one place where it could be difficult. |
Cherry picked from move-language#529. This is an alternative version of what move-language#528 and the previous for limitation of nesting provides, having a significant lower footprint. This approach installs custom serializers at the recursion points of the `TypeTag` enum. Those serializer use a thread local to track the nesting of the type tag, both for serialization and deserialization. The usage of a thread local is safe and a common technique to provide extra state for implementations which miss it (e.g. serde). A given thread has a single execution stack and this will always count the depth counter consistently up and down. Because Rust has no exceptions are other exit points, this cannot be corrupted. Possibly, thread locals may cause inefficiency. However, we expect TypeTags to be small (a few constructors, limited nestings). The technique used for type tags can be generalized for any other recursive type if needed. Eventually, we hope serde will support per-type nesting, and possibly we should talk with the author if we can add it ourselves. This uses and passes the tests from move-language#528.
Cherry picked from move-language#529. This is an alternative version of what move-language#528 and the previous for limitation of nesting provides, having a significant lower footprint. This approach installs custom serializers at the recursion points of the `TypeTag` enum. Those serializer use a thread local to track the nesting of the type tag, both for serialization and deserialization. The usage of a thread local is safe and a common technique to provide extra state for implementations which miss it (e.g. serde). A given thread has a single execution stack and this will always count the depth counter consistently up and down. Because Rust has no exceptions are other exit points, this cannot be corrupted. Possibly, thread locals may cause inefficiency. However, we expect TypeTags to be small (a few constructors, limited nestings). The technique used for type tags can be generalized for any other recursive type if needed. Eventually, we hope serde will support per-type nesting, and possibly we should talk with the author if we can add it ourselves. This uses and passes the tests from move-language#528.
Cherry picked from move-language#529. This is an alternative version of what move-language#528 and the previous for limitation of nesting provides, having a significant lower footprint. This approach installs custom serializers at the recursion points of the `TypeTag` enum. Those serializer use a thread local to track the nesting of the type tag, both for serialization and deserialization. The usage of a thread local is safe and a common technique to provide extra state for implementations which miss it (e.g. serde). A given thread has a single execution stack and this will always count the depth counter consistently up and down. Because Rust has no exceptions are other exit points, this cannot be corrupted. Possibly, thread locals may cause inefficiency. However, we expect TypeTags to be small (a few constructors, limited nestings). The technique used for type tags can be generalized for any other recursive type if needed. Eventually, we hope serde will support per-type nesting, and possibly we should talk with the author if we can add it ourselves. This uses and passes the tests from move-language#528.
Cherry picked from move-language#529. This is an alternative version of what move-language#528 and the previous for limitation of nesting provides, having a significant lower footprint. This approach installs custom serializers at the recursion points of the `TypeTag` enum. Those serializer use a thread local to track the nesting of the type tag, both for serialization and deserialization. The usage of a thread local is safe and a common technique to provide extra state for implementations which miss it (e.g. serde). A given thread has a single execution stack and this will always count the depth counter consistently up and down. Because Rust has no exceptions are other exit points, this cannot be corrupted. Possibly, thread locals may cause inefficiency. However, we expect TypeTags to be small (a few constructors, limited nestings). The technique used for type tags can be generalized for any other recursive type if needed. Eventually, we hope serde will support per-type nesting, and possibly we should talk with the author if we can add it ourselves. This uses and passes the tests from move-language#528.
Cherry picked from #529. This is an alternative version of what #528 and the previous for limitation of nesting provides, having a significant lower footprint. This approach installs custom serializers at the recursion points of the `TypeTag` enum. Those serializer use a thread local to track the nesting of the type tag, both for serialization and deserialization. The usage of a thread local is safe and a common technique to provide extra state for implementations which miss it (e.g. serde). A given thread has a single execution stack and this will always count the depth counter consistently up and down. Because Rust has no exceptions are other exit points, this cannot be corrupted. Possibly, thread locals may cause inefficiency. However, we expect TypeTags to be small (a few constructors, limited nestings). The technique used for type tags can be generalized for any other recursive type if needed. Eventually, we hope serde will support per-type nesting, and possibly we should talk with the author if we can add it ourselves. This uses and passes the tests from #528.
|
This solution seems reasonable to me. Couple of questions about the motivation: I'm assuming that this exists to prevent stack overflows when serializing or deserializing
? (I'm guessing all of the above, but wanted to know which I am wrong about + which surfaces I might be overlooking). Also, if it's just (1) (or if we want to prevent runtime failures in the case of (1)), we could think about enforcing this in the file format or verifier. |
This is not just about stackoverflows. We can discuss offline. Closing this one, as we have landed this now (with some mods) in aptos branch. Will send another cherrypick PR later. |
Cherry picked from move-language#529. This is an alternative version of what move-language#528 and the previous for limitation of nesting provides, having a significant lower footprint. This approach installs custom serializers at the recursion points of the `TypeTag` enum. Those serializer use a thread local to track the nesting of the type tag, both for serialization and deserialization. The usage of a thread local is safe and a common technique to provide extra state for implementations which miss it (e.g. serde). A given thread has a single execution stack and this will always count the depth counter consistently up and down. Because Rust has no exceptions are other exit points, this cannot be corrupted. Possibly, thread locals may cause inefficiency. However, we expect TypeTags to be small (a few constructors, limited nestings). The technique used for type tags can be generalized for any other recursive type if needed. Eventually, we hope serde will support per-type nesting, and possibly we should talk with the author if we can add it ourselves. This uses and passes the tests from move-language#528.
Cherry picked from move-language#529. This is an alternative version of what move-language#528 and the previous for limitation of nesting provides, having a significant lower footprint. This approach installs custom serializers at the recursion points of the `TypeTag` enum. Those serializer use a thread local to track the nesting of the type tag, both for serialization and deserialization. The usage of a thread local is safe and a common technique to provide extra state for implementations which miss it (e.g. serde). A given thread has a single execution stack and this will always count the depth counter consistently up and down. Because Rust has no exceptions are other exit points, this cannot be corrupted. Possibly, thread locals may cause inefficiency. However, we expect TypeTags to be small (a few constructors, limited nestings). The technique used for type tags can be generalized for any other recursive type if needed. Eventually, we hope serde will support per-type nesting, and possibly we should talk with the author if we can add it ourselves. This uses and passes the tests from move-language#528.
* [types] make type tag nesting limited There's limited value and a lot of wasted resources by leaving this limited to serde's limits. Recursion is dangerous. * [types] limit nesting of types via state (#532) Cherry picked from #529. This is an alternative version of what #528 and the previous for limitation of nesting provides, having a significant lower footprint. This approach installs custom serializers at the recursion points of the `TypeTag` enum. Those serializer use a thread local to track the nesting of the type tag, both for serialization and deserialization. The usage of a thread local is safe and a common technique to provide extra state for implementations which miss it (e.g. serde). A given thread has a single execution stack and this will always count the depth counter consistently up and down. Because Rust has no exceptions are other exit points, this cannot be corrupted. Possibly, thread locals may cause inefficiency. However, we expect TypeTags to be small (a few constructors, limited nestings). The technique used for type tags can be generalized for any other recursive type if needed. Eventually, we hope serde will support per-type nesting, and possibly we should talk with the author if we can add it ourselves. This uses and passes the tests from #528. * [types] limit parsing of nested TypeTag There's limited value and a lot of wasted resources by leaving this limited to serde's limits. Recursion is dangerous. Co-authored-by: David Wolinsky <isaac.wolinsky@gmail.com>
* [types] make type tag nesting limited There's limited value and a lot of wasted resources by leaving this limited to serde's limits. Recursion is dangerous. * [types] limit nesting of types via state (move-language#532) Cherry picked from move-language#529. This is an alternative version of what move-language#528 and the previous for limitation of nesting provides, having a significant lower footprint. This approach installs custom serializers at the recursion points of the `TypeTag` enum. Those serializer use a thread local to track the nesting of the type tag, both for serialization and deserialization. The usage of a thread local is safe and a common technique to provide extra state for implementations which miss it (e.g. serde). A given thread has a single execution stack and this will always count the depth counter consistently up and down. Because Rust has no exceptions are other exit points, this cannot be corrupted. Possibly, thread locals may cause inefficiency. However, we expect TypeTags to be small (a few constructors, limited nestings). The technique used for type tags can be generalized for any other recursive type if needed. Eventually, we hope serde will support per-type nesting, and possibly we should talk with the author if we can add it ourselves. This uses and passes the tests from move-language#528. * [types] limit parsing of nested TypeTag There's limited value and a lot of wasted resources by leaving this limited to serde's limits. Recursion is dangerous. Co-authored-by: David Wolinsky <isaac.wolinsky@gmail.com>
* [types] make type tag nesting limited There's limited value and a lot of wasted resources by leaving this limited to serde's limits. Recursion is dangerous. * [types] limit nesting of types via state (move-language#532) Cherry picked from move-language#529. This is an alternative version of what move-language#528 and the previous for limitation of nesting provides, having a significant lower footprint. This approach installs custom serializers at the recursion points of the `TypeTag` enum. Those serializer use a thread local to track the nesting of the type tag, both for serialization and deserialization. The usage of a thread local is safe and a common technique to provide extra state for implementations which miss it (e.g. serde). A given thread has a single execution stack and this will always count the depth counter consistently up and down. Because Rust has no exceptions are other exit points, this cannot be corrupted. Possibly, thread locals may cause inefficiency. However, we expect TypeTags to be small (a few constructors, limited nestings). The technique used for type tags can be generalized for any other recursive type if needed. Eventually, we hope serde will support per-type nesting, and possibly we should talk with the author if we can add it ourselves. This uses and passes the tests from move-language#528. * [types] limit parsing of nested TypeTag There's limited value and a lot of wasted resources by leaving this limited to serde's limits. Recursion is dangerous. Co-authored-by: David Wolinsky <isaac.wolinsky@gmail.com>
* [types] make type tag nesting limited There's limited value and a lot of wasted resources by leaving this limited to serde's limits. Recursion is dangerous. * [types] limit nesting of types via state (#532) Cherry picked from #529. This is an alternative version of what #528 and the previous for limitation of nesting provides, having a significant lower footprint. This approach installs custom serializers at the recursion points of the `TypeTag` enum. Those serializer use a thread local to track the nesting of the type tag, both for serialization and deserialization. The usage of a thread local is safe and a common technique to provide extra state for implementations which miss it (e.g. serde). A given thread has a single execution stack and this will always count the depth counter consistently up and down. Because Rust has no exceptions are other exit points, this cannot be corrupted. Possibly, thread locals may cause inefficiency. However, we expect TypeTags to be small (a few constructors, limited nestings). The technique used for type tags can be generalized for any other recursive type if needed. Eventually, we hope serde will support per-type nesting, and possibly we should talk with the author if we can add it ourselves. This uses and passes the tests from #528. * [types] limit parsing of nested TypeTag There's limited value and a lot of wasted resources by leaving this limited to serde's limits. Recursion is dangerous. Co-authored-by: David Wolinsky <isaac.wolinsky@gmail.com> Co-authored-by: David Wolinsky <isaac.wolinsky@gmail.com>
Motivation
This is an alternative version of what #528 and the previous PR for limitation of nesting of type tags provides.
This approach installs custom serializers at the recursion points of the
TypeTagenum. Those serializer use a thread local to track the nesting of the type tag, both for serialization and deserialization.The usage of a thread local is safe and a common technique to provide extra state for implementations which miss it (e.g. serde). A given thread has a single execution stack and this will always count the depth counter consistently up and down. Because Rust has no exceptions are other exit points, this cannot be corrupted. Possibly, thread locals may cause inefficiency. However, we expect TypeTags to be small (a few constructors, limited nestings).
The technique used for type tags can be generalized for any other recursive type if needed. Eventually, we hope serde will support per-type nesting, and possibly we should talk with the author if we can add it ourselves.
(Write your motivation for proposed changes here.)
Have you read the Contributing Guidelines on pull requests?
Yes
Test Plan
This uses and passes the tests from #528.