Skip to content
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

SerdeAnyMap: add unsafe_stable_anymap feature that uses type_name instead of TypeId::of #1952

Merged
merged 6 commits into from
Mar 19, 2024

Conversation

domenukk
Copy link
Member

@domenukk domenukk commented Mar 17, 2024

While technically unsound, this just might give us a build-agnostic anymap which would pre pretty nice to have to store and load state.

/edit: fixes #1374

@domenukk domenukk changed the title Test: Use type_name instead of type_id in AnyMap SerdeAnyMap: add unsafe_stable_anymap feature that uses type_name instead of TypeId::of Mar 17, 2024
@domenukk domenukk marked this pull request as ready for review March 18, 2024 07:48
@domenukk
Copy link
Member Author

@addisoncrump just how stupid of an idea is this?

@addisoncrump
Copy link
Collaborator

Since we already require 'static, it's actually safe afaik. That said, it will be significantly more expensive to compute since we end up hashing what could be a very long name to enter the item into the hashmap.

@addisoncrump
Copy link
Collaborator

Ah, actually, it theoretically could be problematic if the type names (not including the crate path) are exactly the same, but I'm quite certain this won't happen in practice.

@domenukk
Copy link
Member Author

If they are all 'static we could also &'static str directly? That sounds faster to compare in the best case?

@domenukk
Copy link
Member Author

Sad, doesn't seem to work:

error: lifetime may not live long enough
   --> libafl_bolts/src/serdeany.rs:143:21
    |
132 |     impl<'de> serde::de::Visitor<'de> for BoxDynVisitor {
    |          --- lifetime `'de` defined here
...
143 |             let id: TypeRepr = visitor.next_element()?.unwrap();
    |                     ^^^^^^^^ type annotation requires that `'de` must outlive `'static`

error: lifetime may not live long enough
   --> libafl_bolts/src/serdeany.rs:227:9
    |
225 |     #[derive(Debug, Serialize, Deserialize)]
    |                                ----------- lifetime `'de` defined here
226 |     pub struct SerdeAnyMap {
227 |         map: HashMap<TypeRepr, Box<dyn SerdeAny>>,
    |         ^^^ requires that `'de` must outlive `'static`

error: lifetime may not live long enough
   --> libafl_bolts/src/serdeany.rs:424:9
    |
422 |     #[derive(Debug, Serialize, Deserialize)]
    |                                ----------- lifetime `'de` defined here
423 |     pub struct NamedSerdeAnyMap {
424 |         map: HashMap<TypeRepr, HashMap<u64, Box<dyn crate::serdeany::SerdeAny>>>,
    |         ^^^ requires that `'de` must outlive `'static`

@addisoncrump
Copy link
Collaborator

We can manually impl Deserialize here.

@addisoncrump
Copy link
Collaborator

If they are all 'static we could also &'static str directly? That sounds faster to compare in the best case?

Static lifetime means that, if I own the value, it will live for as long as I hold it. It doesn't guarantee that these values will be in the same place between executions, so we can't serialize them as &'static str. Instead, we'll need to manually deserialise to match the entries in the local registry.

@addisoncrump
Copy link
Collaborator

addisoncrump commented Mar 18, 2024

Actually, we can do a sneaky and impl Deserialize for a wrapper type around the TypeRepr to simplify this.

@domenukk
Copy link
Member Author

Do you want to give it a shot?

@addisoncrump
Copy link
Collaborator

Sure, I'll take a crack at it now.

@addisoncrump
Copy link
Collaborator

Can you commit the non-working code? I'll fix it from there.

@domenukk
Copy link
Member Author

I just replaced String with &'static str as TypeRepr

@@ -98,7 +140,7 @@ pub mod serdeany_registry {
where
V: serde::de::SeqAccess<'de>,
{
let id: u128 = visitor.next_element()?.unwrap();
let id: TypeRepr = visitor.next_element()?.unwrap();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@addisoncrump I'm not 100% sure if this type annotation is correct (or should be borrowed or something?)

@domenukk domenukk merged commit 2efa747 into main Mar 19, 2024
27 checks passed
@domenukk domenukk deleted the type_name_anymap_test branch March 19, 2024 19:15
@domenukk
Copy link
Member Author

@addisoncrump just open a new PR if you manage to do it with 'static str somehow

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Why Hash the Hashmap Key?
2 participants