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

fix | Implement de_ignored_any to consume unknown fields #5

Closed

Conversation

frunobulax-the-poodle
Copy link

@frunobulax-the-poodle frunobulax-the-poodle commented Jul 13, 2023

Short Context

The MicroG implementation of FIDO2 includes the optional transports which isn't in ctap-types and the "appid" extension.

After I day I tracked the issue down to the cbor parser, which fails on map fields not present in the struct it's trying to parse.

Issue

When deserializing a map that has fields not present in the struct, the key is consumed, but the value is instead skipped entirely.

When deserialization continues, there is leftover unexpected data in the input, leading to errors (usually bad major)

Fix

Implement deserialize_ignored_any for Deserializer, so the values are fully consumed.

This does kind of go against not supporting deserialize_any, but I don't think there's a way around it.

@frunobulax-the-poodle frunobulax-the-poodle changed the title fix | Implement de_ignored_any to consume unknown map fields fix | Implement de_ignored_any to consume unknown fields Jul 13, 2023
Copy link
Contributor

@sosthene-nitrokey sosthene-nitrokey left a comment

Choose a reason for hiding this comment

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

Thank you for the pull request.

However I believe that ignored_any should completely ignore the value and end on a visit_unit. For example that is what serde_json does: https://docs.rs/serde_json/latest/src/serde_json/de.rs.html#1897-1903

Comment on lines +705 to +706
0 => self.deserialize_u32(visitor),
1 => self.deserialize_i32(visitor),
Copy link
Contributor

Choose a reason for hiding this comment

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

This means that a value that does not fit in a i32 or a u32 de-serialization will fail.
I believe this should not actually de-serialize the value but just discard it.

Comment on lines +1044 to +1064
struct Struct {
a: u8,
b: i16,
}

#[derive(Debug, Serialize)]
struct SuperStruct {
a: u8,
c: Struct,
b: i16,
}

let mut buf = [0u8; 64];
let base = Struct { a: 22, b: -161 };
let sup = SuperStruct { a: 22, b: -161, c: base.clone() };

let ser = cbor_serialize(&sup, &mut buf).unwrap();
let de: Struct = cbor_deserialize(&ser).unwrap();

assert_eq!(de, base);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Here if you replace the u8 with u64 and 22 with 0xFFFFFFFFF this will lead to DeserializeBadU32.

@frunobulax-the-poodle
Copy link
Author

frunobulax-the-poodle commented Nov 18, 2023

Thank you for the pull request.

However I believe that ignored_any should completely ignore the value and end on a visit_unit. For example that is what serde_json does: https://docs.rs/serde_json/latest/src/serde_json/de.rs.html#1897-1903

Seems you're right. This was pretty far outside my wheelhouse so I expected to screw something up :)

As you've already got a better PR out and are in a better position to maybe actually get it merged I'd be happy to just close this one.

@sosthene-nitrokey
Copy link
Contributor

I will close this PR in favour of #6

Now that this has been moved to trussed-dev we (Nitrokey) will be able to merge and release the other PRs.

Thank you.

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.

2 participants