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),