]> git.proxmox.com Git - rustc.git/blame - vendor/tendril/examples/fuzz.rs
New upstream version 1.63.0+dfsg1
[rustc.git] / vendor / tendril / examples / fuzz.rs
CommitLineData
83c7162d 1// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
923072b8
FG
2// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
3// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
83c7162d
XL
4// option. This file may not be copied, modified, or distributed
5// except according to those terms.
6
7//! A simple fuzz tester for the library.
8
9#![deny(warnings)]
10
11extern crate rand;
12extern crate tendril;
13
14use std::borrow::ToOwned;
15
83c7162d 16use rand::distributions::{IndependentSample, Range};
923072b8 17use rand::Rng;
83c7162d
XL
18use tendril::StrTendril;
19
20fn fuzz() {
21 let mut rng = rand::thread_rng();
22 let capacity = Range::new(0u32, 1 << 14).ind_sample(&mut rng);
23 let mut buf_string = String::with_capacity(capacity as usize);
24 let mut buf_tendril = StrTendril::with_capacity(capacity);
25 let mut string_slices = vec![];
26 let mut tendril_slices = vec![];
27
923072b8 28 for _ in 1..100_000 {
83c7162d
XL
29 if buf_string.len() > (1 << 30) {
30 buf_string.truncate(0);
31 buf_tendril.clear();
32 }
33
34 let dist_action = Range::new(0, 100);
35 match dist_action.ind_sample(&mut rng) {
923072b8 36 0..=15 => {
83c7162d
XL
37 let (start, end) = random_slice(&mut rng, TEXT);
38 let snip = &TEXT[start..end];
39 buf_string.push_str(snip);
40 buf_tendril.push_slice(snip);
41 assert_eq!(&*buf_string, &*buf_tendril);
42 }
43
923072b8 44 16..=31 => {
83c7162d
XL
45 let (start, end) = random_slice(&mut rng, &buf_string);
46 let snip = &buf_string[start..end].to_owned();
47 buf_string.push_str(&snip);
48 buf_tendril.push_slice(&snip);
49 assert_eq!(&*buf_string, &*buf_tendril);
50 }
51
923072b8 52 32..=47 => {
83c7162d
XL
53 let lenstr = format!("[length = {}]", buf_tendril.len());
54 buf_string.push_str(&lenstr);
55 buf_tendril.push_slice(&lenstr);
56 assert_eq!(&*buf_string, &*buf_tendril);
57 }
58
923072b8 59 48..=63 => {
83c7162d
XL
60 let n = random_boundary(&mut rng, &buf_string);
61 buf_tendril.pop_front(n as u32);
62 buf_string = buf_string[n..].to_owned();
63 assert_eq!(&*buf_string, &*buf_tendril);
64 }
65
923072b8 66 64..=79 => {
83c7162d
XL
67 let new_len = random_boundary(&mut rng, &buf_string);
68 let n = buf_string.len() - new_len;
69 buf_string.truncate(new_len);
70 buf_tendril.pop_back(n as u32);
71 assert_eq!(&*buf_string, &*buf_tendril);
72 }
73
923072b8 74 80..=90 => {
83c7162d
XL
75 let (start, end) = random_slice(&mut rng, &buf_string);
76 buf_string = buf_string[start..end].to_owned();
77 buf_tendril = buf_tendril.subtendril(start as u32, (end - start) as u32);
78 assert_eq!(&*buf_string, &*buf_tendril);
79 }
80
923072b8 81 91..=96 => {
83c7162d
XL
82 let c = rng.gen();
83 buf_string.push(c);
84 assert!(buf_tendril.try_push_char(c).is_ok());
85 assert_eq!(&*buf_string, &*buf_tendril);
86 }
87
88 97 => {
89 buf_string.truncate(0);
90 buf_tendril.clear();
91 assert_eq!(&*buf_string, &*buf_tendril);
92 }
93
94 _ => {
95 let (start, end) = random_slice(&mut rng, &buf_string);
96 string_slices.push(buf_string[start..end].to_owned());
97 tendril_slices.push(buf_tendril.subtendril(start as u32, (end - start) as u32));
98 assert_eq!(string_slices.len(), tendril_slices.len());
923072b8
FG
99 assert!(string_slices
100 .iter()
101 .zip(tendril_slices.iter())
102 .all(|(s, t)| **s == **t));
83c7162d
XL
103 }
104 }
105 }
106}
107
108fn random_boundary<R: Rng>(rng: &mut R, text: &str) -> usize {
109 loop {
923072b8 110 let i = Range::new(0, text.len() + 1).ind_sample(rng);
83c7162d
XL
111 if text.is_char_boundary(i) {
112 return i;
113 }
114 }
115}
116
117fn random_slice<R: Rng>(rng: &mut R, text: &str) -> (usize, usize) {
118 loop {
923072b8
FG
119 let start = Range::new(0, text.len() + 1).ind_sample(rng);
120 let end = Range::new(start, text.len() + 1).ind_sample(rng);
83c7162d
XL
121 if !text.is_char_boundary(start) {
122 continue;
123 }
124 if end < text.len() && !text.is_char_boundary(end) {
125 continue;
126 }
127 return (start, end);
128 }
129}
130
131static TEXT: &'static str =
132 "It was from the artists and poets that the pertinent answers came, and I \
133 know that panic would have broken loose had they been able to compare notes. \
134 As it was, lacking their original letters, I half suspected the compiler of \
135 having asked leading questions, or of having edited the correspondence in \
136 corroboration of what he had latently resolved to see.\
137\
138 ˙ǝǝs oʇ pǝʌʃosǝɹ ʎʃʇuǝʇɐʃ pɐɥ ǝɥ ʇɐɥʍ ɟo uoıʇɐɹoqoɹɹoɔ uı ǝɔuǝpuodsǝɹɹoɔ ǝɥʇ \
139 pǝʇıpǝ ƃuıʌɐɥ ɟo ɹo 'suoıʇsǝnb ƃuıpɐǝʃ pǝʞsɐ ƃuıʌɐɥ ɟo ɹǝʃıdɯoɔ ǝɥʇ pǝʇɔǝdsns \
140 ɟʃɐɥ I 'sɹǝʇʇǝʃ ʃɐuıƃıɹo ɹıǝɥʇ ƃuıʞɔɐʃ 'sɐʍ ʇı s∀ ˙sǝʇou ǝɹɐdɯoɔ oʇ ǝʃqɐ uǝǝq \
141 ʎǝɥʇ pɐɥ ǝsooʃ uǝʞoɹq ǝʌɐɥ pʃnoʍ ɔıuɐd ʇɐɥʇ ʍouʞ I puɐ 'ǝɯɐɔ sɹǝʍsuɐ ʇuǝuıʇɹǝd \
142 ǝɥʇ ʇɐɥʇ sʇǝod puɐ sʇsıʇɹɐ ǝɥʇ ɯoɹɟ sɐʍ ʇI";
143
144fn main() {
145 fuzz();
146}