Skip to content

Commit 0bdbec8

Browse files
authored
Merge pull request #151 from Ekleog-NEAR/patch-2
Make <&str as Arbitrary>::arbitrary_take_rest less likely to fail
2 parents 28ead09 + 5b20f3c commit 0bdbec8

File tree

1 file changed

+30
-18
lines changed

1 file changed

+30
-18
lines changed

src/lib.rs

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -834,29 +834,33 @@ where
834834
}
835835
}
836836

837+
fn arbitrary_str<'a>(u: &mut Unstructured<'a>, size: usize) -> Result<&'a str> {
838+
match str::from_utf8(u.peek_bytes(size).unwrap()) {
839+
Ok(s) => {
840+
u.bytes(size).unwrap();
841+
Ok(s)
842+
}
843+
Err(e) => {
844+
let i = e.valid_up_to();
845+
let valid = u.bytes(i).unwrap();
846+
let s = unsafe {
847+
debug_assert!(str::from_utf8(valid).is_ok());
848+
str::from_utf8_unchecked(valid)
849+
};
850+
Ok(s)
851+
}
852+
}
853+
}
854+
837855
impl<'a> Arbitrary<'a> for &'a str {
838856
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
839857
let size = u.arbitrary_len::<u8>()?;
840-
match str::from_utf8(u.peek_bytes(size).unwrap()) {
841-
Ok(s) => {
842-
u.bytes(size).unwrap();
843-
Ok(s)
844-
}
845-
Err(e) => {
846-
let i = e.valid_up_to();
847-
let valid = u.bytes(i).unwrap();
848-
let s = unsafe {
849-
debug_assert!(str::from_utf8(valid).is_ok());
850-
str::from_utf8_unchecked(valid)
851-
};
852-
Ok(s)
853-
}
854-
}
858+
arbitrary_str(u, size)
855859
}
856860

857-
fn arbitrary_take_rest(u: Unstructured<'a>) -> Result<Self> {
858-
let bytes = u.take_rest();
859-
str::from_utf8(bytes).map_err(|_| Error::IncorrectFormat)
861+
fn arbitrary_take_rest(mut u: Unstructured<'a>) -> Result<Self> {
862+
let size = u.len();
863+
arbitrary_str(&mut u, size)
860864
}
861865

862866
#[inline]
@@ -1255,6 +1259,7 @@ mod test {
12551259

12561260
#[test]
12571261
fn arbitrary_take_rest() {
1262+
// Basic examples
12581263
let x = [1, 2, 3, 4];
12591264
assert_eq!(
12601265
checked_arbitrary_take_rest::<&[u8]>(Unstructured::new(&x)).unwrap(),
@@ -1273,6 +1278,7 @@ mod test {
12731278
"\x01\x02\x03\x04"
12741279
);
12751280

1281+
// Empty remainder
12761282
assert_eq!(
12771283
checked_arbitrary_take_rest::<&[u8]>(Unstructured::new(&[])).unwrap(),
12781284
&[]
@@ -1281,6 +1287,12 @@ mod test {
12811287
checked_arbitrary_take_rest::<Vec<u8>>(Unstructured::new(&[])).unwrap(),
12821288
&[]
12831289
);
1290+
1291+
// Cannot consume all but can consume part of the input
1292+
assert_eq!(
1293+
checked_arbitrary_take_rest::<String>(Unstructured::new(&[1, 0xFF, 2])).unwrap(),
1294+
"\x01"
1295+
);
12841296
}
12851297

12861298
#[test]

0 commit comments

Comments
 (0)