From 35019bca8272ea5fd8c5fff91e4b333b44e41b58 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 1 Nov 2024 19:14:31 -0600 Subject: [PATCH] const-oid: elimiate arithmetic side effects in arc encoder (#1598) Ensures overflow will always cause a panic instead --- const-oid/src/encoder.rs | 16 +++++++++++++--- const-oid/src/parser.rs | 1 + 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/const-oid/src/encoder.rs b/const-oid/src/encoder.rs index 1ee47d3d..4c8831cf 100644 --- a/const-oid/src/encoder.rs +++ b/const-oid/src/encoder.rs @@ -51,6 +51,7 @@ impl Encoder { } /// Encode an [`Arc`] as base 128 into the internal buffer. + #[allow(clippy::panic_in_result_fn)] pub(crate) const fn arc(mut self, arc: Arc) -> Result { match self.state { State::Initial => { @@ -61,15 +62,24 @@ impl Encoder { self.state = State::FirstArc(arc); Ok(self) } - // Ensured not to overflow by `ARC_MAX_SECOND` check - #[allow(clippy::arithmetic_side_effects)] State::FirstArc(first_arc) => { if arc > ARC_MAX_SECOND { return Err(Error::ArcInvalid { arc }); } self.state = State::Body; - self.bytes[0] = (first_arc * (ARC_MAX_SECOND + 1)) as u8 + arc as u8; + self.bytes[0] = match (ARC_MAX_SECOND + 1).checked_mul(first_arc) { + // TODO(tarcieri): use `and_then` when const traits are stable + Some(n) => match n.checked_add(arc) { + Some(byte) => byte as u8, + None => { + // TODO(tarcieri): use `unreachable!` + panic!("overflow prevented by ARC_MAX_SECOND check") + } + }, + // TODO(tarcieri): use `unreachable!` + None => panic!("overflow prevented by ARC_MAX_SECOND check"), + }; self.cursor = 1; Ok(self) } diff --git a/const-oid/src/parser.rs b/const-oid/src/parser.rs index fe687e39..4810294d 100644 --- a/const-oid/src/parser.rs +++ b/const-oid/src/parser.rs @@ -59,6 +59,7 @@ impl Parser { None => 0, }; + // TODO(tarcieri): use `and_then` when const traits are stable self.current_arc = match arc.checked_mul(10) { Some(arc) => match arc.checked_add(digit as Arc) { None => return Err(Error::ArcTooBig),