From 679247590bd9ca905dab47d63161ac6947371eae Mon Sep 17 00:00:00 2001 From: Emanuel Pilz Date: Fri, 18 Oct 2024 02:17:45 +0200 Subject: [PATCH] feat(ciborium-ll): fail decoding invalid two-byte encodings of simple values Signed-off-by: Emanuel Pilz --- ciborium-ll/src/hdr.rs | 9 ++++++++- ciborium-ll/src/lib.rs | 11 +++++++++-- ciborium/tests/error.rs | 8 ++++---- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/ciborium-ll/src/hdr.rs b/ciborium-ll/src/hdr.rs index dec1788..adfb1e9 100644 --- a/ciborium-ll/src/hdr.rs +++ b/ciborium-ll/src/hdr.rs @@ -107,7 +107,9 @@ impl TryFrom for Header { Title(Major::Other, Minor::More) => Self::Break, Title(Major::Other, Minor::This(x)) => Self::Simple(x), - Title(Major::Other, Minor::Next1(x)) => Self::Simple(x[0]), + // Two-byte sequences for simple values below 32 are not considered well-formed + Title(Major::Other, Minor::Next1([0..=31])) => Err(InvalidError(()))?, + Title(Major::Other, Minor::Next1([x])) => Self::Simple(x), Title(Major::Other, Minor::Next2(x)) => Self::Float(f16::from_be_bytes(x).into()), Title(Major::Other, Minor::Next4(x)) => Self::Float(f32::from_be_bytes(x).into()), Title(Major::Other, Minor::Next8(x)) => Self::Float(f64::from_be_bytes(x)), @@ -140,6 +142,11 @@ impl From<Header> for Title { Header::Simple(x) => match x { x @ 0..=23 => Title(Major::Other, Minor::This(x)), + // Simple(24) is irrepresentable + // Simple(25) to Simple(27) are floats + // Simple(28) to Simple(30) are reserved + // Should this panic or error (i.e. use TryFrom instead of From) ? + // See: https://www.rfc-editor.org/rfc/rfc8949.html#section-3.3 x => Title(Major::Other, Minor::Next1([x])), }, diff --git a/ciborium-ll/src/lib.rs b/ciborium-ll/src/lib.rs index 5b47ba9..ecf76a4 100644 --- a/ciborium-ll/src/lib.rs +++ b/ciborium-ll/src/lib.rs @@ -273,12 +273,19 @@ mod tests { (Header::Float(INFINITY), "fb7ff0000000000000", false), (Header::Float(NAN), "fb7ff8000000000000", false), (Header::Float(-INFINITY), "fbfff0000000000000", false), + (Header::Simple(0), "e0", true), + (Header::Simple(1), "e1", true), + (Header::Simple(16), "f0", true), + (Header::Simple(17), "f1", true), + (Header::Simple(18), "f2", true), + (Header::Simple(19), "f3", true), (Header::Simple(simple::FALSE), "f4", true), (Header::Simple(simple::TRUE), "f5", true), (Header::Simple(simple::NULL), "f6", true), (Header::Simple(simple::UNDEFINED), "f7", true), - (Header::Simple(16), "f0", true), - (Header::Simple(24), "f818", true), + (Header::Break, "ff", true), + (Header::Simple(32), "f820", true), + (Header::Simple(64), "f840", true), (Header::Simple(255), "f8ff", true), (Header::Tag(0), "c0", true), (Header::Tag(1), "c1", true), diff --git a/ciborium/tests/error.rs b/ciborium/tests/error.rs index 2bc42d9..9619222 100644 --- a/ciborium/tests/error.rs +++ b/ciborium/tests/error.rs @@ -115,10 +115,10 @@ fn eof() -> Error<std::io::Error> { case("fe", Error::Syntax(0)), // Reserved two-byte encodings of simple values: - case("f800", Error::Semantic(None, "invalid type: simple, expected known simple value".into())), - case("f801", Error::Semantic(None, "invalid type: simple, expected known simple value".into())), - case("f818", Error::Semantic(None, "invalid type: simple, expected known simple value".into())), - case("f81f", Error::Semantic(None, "invalid type: simple, expected known simple value".into())), + case("f800", Error::Syntax(0)), + case("f801", Error::Syntax(0)), + case("f818", Error::Syntax(0)), + case("f81f", Error::Syntax(0)), // Indefinite-length string chunks not of the correct type: case("5f00ff", Error::Syntax(1)),