Skip to content

Commit

Permalink
RUST-2028 Fix Decimal128 panic when parsing strings w/o a char bounda…
Browse files Browse the repository at this point in the history
…ry at idx 34 (#496)
  • Loading branch information
arthurprs authored Sep 9, 2024
1 parent 28e3925 commit 692cd75
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 0 deletions.
8 changes: 8 additions & 0 deletions src/decimal128.rs
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,7 @@ pub enum ParseError {
Overflow,
Underflow,
InexactRounding,
Unparseable,
}

impl fmt::Display for ParseError {
Expand All @@ -344,6 +345,7 @@ impl fmt::Display for ParseError {
ParseError::Overflow => write!(f, "overflow"),
ParseError::Underflow => write!(f, "underflow"),
ParseError::InexactRounding => write!(f, "inexact rounding"),
ParseError::Unparseable => write!(f, "unparseable"),
}
}
}
Expand Down Expand Up @@ -469,6 +471,12 @@ impl std::str::FromStr for ParsedDecimal128 {
}

fn round_decimal_str(s: &str, precision: usize) -> Result<&str, ParseError> {
// TODO: In 1.80+ there's split_at_checked to make sure the split doesn't
// panic if the index doesn't falls at a codepoint boundary, until then
// we can check it with s.is_char_boundary(precision)
if !s.is_char_boundary(precision) {
return Err(ParseError::Unparseable);
}
let (pre, post) = s.split_at(precision);
// Any nonzero trimmed digits mean it would be an imprecise round.
if post.chars().any(|c| c != '0') {
Expand Down
12 changes: 12 additions & 0 deletions src/raw/test/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,22 @@ use crate::{
Binary,
Bson,
DateTime,
Decimal128,
Regex,
Timestamp,
};

#[test]
fn test_decimal128_doesnt_panic_on_bad_codepoint_boundary() {
use crate::decimal128::ParseError;
use std::str::FromStr;
// idx 34 (Coefficient::MAX_DIGITS) on this string isn't a valid codepoint boundary
assert!(matches!(
Decimal128::from_str("111111111111111111111111111111111❤"),
Err(ParseError::Unparseable)
))
}

#[test]
fn string_from_document() {
let rawdoc = rawdoc! {
Expand Down

0 comments on commit 692cd75

Please sign in to comment.