rust-embedded-community / serde-json-core

`serde-json` for `no_std` programs
Apache License 2.0
161 stars 59 forks source link

Library panics when deserializing certain types due to `unreachable!()` statements #48

Open ryan-summers opened 3 years ago

ryan-summers commented 3 years ago

When deserializing certain types, the library may hit unreachable!() statements, which results in a panic. This appears to be because serde-json-core does not support deserializing complex enums (e.g. pub struct Test(u32).

That being said, the library should never internally panic. Instead, it should propagate an error out to the user.

dnadlinger commented 3 years ago

(The particular issue of newtype has been fixed in https://github.com/rust-embedded-community/serde-json-core/commit/cce045cf76eb4b60d08241cf0a2a2458b49189c1; not sure whether there are any others left.)

jordens commented 3 years ago

These are all known at compile time. Shouldn't already the derive fail?

ryan-summers commented 3 years ago

The derive is done in serde, which doesn't care about the support of the underlying serialize/deserialize engine. Hence, we are just provided a serde-compatible API at the serde-json-core level. We don't have any proc-macros in this repository, we just have functions that can deserialize/serialize objects that implement serde::Serialize and serde::Deserialize. In other backends for serde, these types are supported.

ryan-summers commented 1 year ago

Closing, as I don't think this has any open defects anymore with newtype resolved.

jordens commented 1 year ago

I think it's still pretty easy to hit, e.g. serde_json_core::to_vec::<_, 10>(&'a'), serde_json_core::from_slice::<char>(b"");

gdemenibus commented 11 months ago

You can also hit an unreachable section by serializing an enum with a tuple element.

jordens commented 11 months ago

I don't think this general behavior is a bug. It seems to be standard practice of serde trait implementations to panic on unimplemented/unimplementable things. What would be the alternative?

ryan-summers commented 11 months ago

I think the core issue is that it's marked as unreachable!() when in reality it's an unimplemented!(). In either case, an internal panic is likely the only solution if we don't want to propogate an error up the stack.

jordens commented 11 months ago

The title should probably reflect that then.

ryan-summers commented 3 months ago

I believe this should be mostly fixed now that #83 has made these functions return Err instead of unreachable!(). There's still some unreachable!() statements in src/de/map.rs.

I think the only case you'll now hit these is if you use some non-string as a map key, such as {0: "Test"}