1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
use super::OwnedKeyExpr;
fn random_chunk(rng: &'_ mut impl rand::Rng) -> impl Iterator<Item = u8> + '_ {
let n = rng.gen_range(1..3);
(0..n).map(move |_| rng.sample(rand::distributions::Uniform::from(b'a'..b'c')))
}
fn make(ke: &mut Vec<u8>, rng: &mut impl rand::Rng) {
let mut iters = 0;
loop {
let n = rng.sample(rand::distributions::Uniform::<u8>::from(0..=255));
match n {
0..=15 => ke.extend(b"/**"),
16..=31 => ke.extend(b"/*"),
32..=47 => {
if !ke.is_empty() && !ke.ends_with(b"*") {
ke.extend(b"$*")
} else {
continue;
}
}
48.. => {
if n >= 128 || ke.ends_with(b"**") || ke.ends_with(b"/*") {
ke.push(b'/')
}
ke.extend(random_chunk(rng))
}
}
if n % (10 - iters) == 0 {
return;
}
iters += 1;
}
}
pub struct KeyExprFuzzer<Rng: rand::Rng>(pub Rng);
impl<Rng: rand::Rng> Iterator for KeyExprFuzzer<Rng> {
type Item = OwnedKeyExpr;
fn next(&mut self) -> Option<Self::Item> {
let mut next = Vec::new();
make(&mut next, &mut self.0);
let mut next = String::from_utf8(next).unwrap();
if let Some(n) = next.strip_prefix('/') {
next = n.to_owned()
}
Some(OwnedKeyExpr::autocanonize(next).unwrap())
}
}