diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:02:58 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:02:58 +0000 |
commit | 698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch) | |
tree | 173a775858bd501c378080a10dca74132f05bc50 /vendor/tendril/examples/fuzz.rs | |
parent | Initial commit. (diff) | |
download | rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip |
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/tendril/examples/fuzz.rs')
-rw-r--r-- | vendor/tendril/examples/fuzz.rs | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/vendor/tendril/examples/fuzz.rs b/vendor/tendril/examples/fuzz.rs new file mode 100644 index 000000000..37daf560b --- /dev/null +++ b/vendor/tendril/examples/fuzz.rs @@ -0,0 +1,146 @@ +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! A simple fuzz tester for the library. + +#![deny(warnings)] + +extern crate rand; +extern crate tendril; + +use std::borrow::ToOwned; + +use rand::distributions::{IndependentSample, Range}; +use rand::Rng; +use tendril::StrTendril; + +fn fuzz() { + let mut rng = rand::thread_rng(); + let capacity = Range::new(0u32, 1 << 14).ind_sample(&mut rng); + let mut buf_string = String::with_capacity(capacity as usize); + let mut buf_tendril = StrTendril::with_capacity(capacity); + let mut string_slices = vec![]; + let mut tendril_slices = vec![]; + + for _ in 1..100_000 { + if buf_string.len() > (1 << 30) { + buf_string.truncate(0); + buf_tendril.clear(); + } + + let dist_action = Range::new(0, 100); + match dist_action.ind_sample(&mut rng) { + 0..=15 => { + let (start, end) = random_slice(&mut rng, TEXT); + let snip = &TEXT[start..end]; + buf_string.push_str(snip); + buf_tendril.push_slice(snip); + assert_eq!(&*buf_string, &*buf_tendril); + } + + 16..=31 => { + let (start, end) = random_slice(&mut rng, &buf_string); + let snip = &buf_string[start..end].to_owned(); + buf_string.push_str(&snip); + buf_tendril.push_slice(&snip); + assert_eq!(&*buf_string, &*buf_tendril); + } + + 32..=47 => { + let lenstr = format!("[length = {}]", buf_tendril.len()); + buf_string.push_str(&lenstr); + buf_tendril.push_slice(&lenstr); + assert_eq!(&*buf_string, &*buf_tendril); + } + + 48..=63 => { + let n = random_boundary(&mut rng, &buf_string); + buf_tendril.pop_front(n as u32); + buf_string = buf_string[n..].to_owned(); + assert_eq!(&*buf_string, &*buf_tendril); + } + + 64..=79 => { + let new_len = random_boundary(&mut rng, &buf_string); + let n = buf_string.len() - new_len; + buf_string.truncate(new_len); + buf_tendril.pop_back(n as u32); + assert_eq!(&*buf_string, &*buf_tendril); + } + + 80..=90 => { + let (start, end) = random_slice(&mut rng, &buf_string); + buf_string = buf_string[start..end].to_owned(); + buf_tendril = buf_tendril.subtendril(start as u32, (end - start) as u32); + assert_eq!(&*buf_string, &*buf_tendril); + } + + 91..=96 => { + let c = rng.gen(); + buf_string.push(c); + assert!(buf_tendril.try_push_char(c).is_ok()); + assert_eq!(&*buf_string, &*buf_tendril); + } + + 97 => { + buf_string.truncate(0); + buf_tendril.clear(); + assert_eq!(&*buf_string, &*buf_tendril); + } + + _ => { + let (start, end) = random_slice(&mut rng, &buf_string); + string_slices.push(buf_string[start..end].to_owned()); + tendril_slices.push(buf_tendril.subtendril(start as u32, (end - start) as u32)); + assert_eq!(string_slices.len(), tendril_slices.len()); + assert!(string_slices + .iter() + .zip(tendril_slices.iter()) + .all(|(s, t)| **s == **t)); + } + } + } +} + +fn random_boundary<R: Rng>(rng: &mut R, text: &str) -> usize { + loop { + let i = Range::new(0, text.len() + 1).ind_sample(rng); + if text.is_char_boundary(i) { + return i; + } + } +} + +fn random_slice<R: Rng>(rng: &mut R, text: &str) -> (usize, usize) { + loop { + let start = Range::new(0, text.len() + 1).ind_sample(rng); + let end = Range::new(start, text.len() + 1).ind_sample(rng); + if !text.is_char_boundary(start) { + continue; + } + if end < text.len() && !text.is_char_boundary(end) { + continue; + } + return (start, end); + } +} + +static TEXT: &'static str = + "It was from the artists and poets that the pertinent answers came, and I \ + know that panic would have broken loose had they been able to compare notes. \ + As it was, lacking their original letters, I half suspected the compiler of \ + having asked leading questions, or of having edited the correspondence in \ + corroboration of what he had latently resolved to see.\ +\ + ˙ǝǝs oʇ pǝʌʃosǝɹ ʎʃʇuǝʇɐʃ pɐɥ ǝɥ ʇɐɥʍ ɟo uoıʇɐɹoqoɹɹoɔ uı ǝɔuǝpuodsǝɹɹoɔ ǝɥʇ \ + pǝʇıpǝ ƃuıʌɐɥ ɟo ɹo 'suoıʇsǝnb ƃuıpɐǝʃ pǝʞsɐ ƃuıʌɐɥ ɟo ɹǝʃıdɯoɔ ǝɥʇ pǝʇɔǝdsns \ + ɟʃɐɥ I 'sɹǝʇʇǝʃ ʃɐuıƃıɹo ɹıǝɥʇ ƃuıʞɔɐʃ 'sɐʍ ʇı s∀ ˙sǝʇou ǝɹɐdɯoɔ oʇ ǝʃqɐ uǝǝq \ + ʎǝɥʇ pɐɥ ǝsooʃ uǝʞoɹq ǝʌɐɥ pʃnoʍ ɔıuɐd ʇɐɥʇ ʍouʞ I puɐ 'ǝɯɐɔ sɹǝʍsuɐ ʇuǝuıʇɹǝd \ + ǝɥʇ ʇɐɥʇ sʇǝod puɐ sʇsıʇɹɐ ǝɥʇ ɯoɹɟ sɐʍ ʇI"; + +fn main() { + fuzz(); +} |