Ensure string::slice does not panic with usize overflow

This commit is contained in:
Tobie Morgan Hitchcock 2022-12-03 23:30:38 +00:00
parent 09021ee103
commit 3c4f194610
2 changed files with 12 additions and 3 deletions

View file

@ -53,12 +53,16 @@ pub fn reverse((string,): (String,)) -> Result<Value, Error> {
pub fn slice((val, beg, lim): (String, Option<isize>, Option<isize>)) -> Result<Value, Error> { pub fn slice((val, beg, lim): (String, Option<isize>, Option<isize>)) -> Result<Value, Error> {
let val = match beg { let val = match beg {
Some(v) if v < 0 => val.chars().skip(val.len() - v.unsigned_abs()).collect::<String>(), Some(v) if v < 0 => {
val.chars().skip(val.len().saturating_sub(v.unsigned_abs())).collect::<String>()
}
Some(v) => val.chars().skip(v as usize).collect::<String>(), Some(v) => val.chars().skip(v as usize).collect::<String>(),
None => val, None => val,
}; };
let val = match lim { let val = match lim {
Some(v) if v < 0 => val.chars().take(val.len() - v.unsigned_abs()).collect::<String>(), Some(v) if v < 0 => {
val.chars().take(val.len().saturating_sub(v.unsigned_abs())).collect::<String>()
}
Some(v) => val.chars().take(v as usize).collect::<String>(), Some(v) => val.chars().take(v as usize).collect::<String>(),
None => val, None => val,
}; };

View file

@ -235,11 +235,12 @@ async fn function_string_slice() -> Result<(), Error> {
RETURN string::slice("the quick brown fox jumps over the lazy dog.", 0, -1); RETURN string::slice("the quick brown fox jumps over the lazy dog.", 0, -1);
RETURN string::slice("the quick brown fox jumps over the lazy dog.", 16, -1); RETURN string::slice("the quick brown fox jumps over the lazy dog.", 16, -1);
RETURN string::slice("the quick brown fox jumps over the lazy dog.", -9, -1); RETURN string::slice("the quick brown fox jumps over the lazy dog.", -9, -1);
RETURN string::slice("the quick brown fox jumps over the lazy dog.", -100, -100);
"#; "#;
let dbs = Datastore::new("memory").await?; let dbs = Datastore::new("memory").await?;
let ses = Session::for_kv().with_ns("test").with_db("test"); let ses = Session::for_kv().with_ns("test").with_db("test");
let res = &mut dbs.execute(&sql, &ses, None, false).await?; let res = &mut dbs.execute(&sql, &ses, None, false).await?;
assert_eq!(res.len(), 6); assert_eq!(res.len(), 7);
// //
let tmp = res.remove(0).result?; let tmp = res.remove(0).result?;
let val = Value::parse("'the quick brown fox jumps over the lazy dog.'"); let val = Value::parse("'the quick brown fox jumps over the lazy dog.'");
@ -265,5 +266,9 @@ async fn function_string_slice() -> Result<(), Error> {
let val = Value::parse("'lazy dog'"); let val = Value::parse("'lazy dog'");
assert_eq!(tmp, val); assert_eq!(tmp, val);
// //
let tmp = res.remove(0).result?;
let val = Value::parse("''");
assert_eq!(tmp, val);
//
Ok(()) Ok(())
} }