1 // Copyright 2021, The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #![allow(missing_docs)]
16 #![no_main]
17 
18 use hashlink::LinkedHashSet;
19 use libfuzzer_sys::arbitrary::Arbitrary;
20 use libfuzzer_sys::fuzz_target;
21 
22 const MAX_RESERVE: usize = 1024;
23 
24 #[derive(Arbitrary, Debug, Eq, Hash, PartialEq)]
25 enum Data {
26     A,
27     B,
28     Int { val: u8 },
29 }
30 
31 #[derive(Arbitrary, Debug)]
32 enum LinkedHashSetMethods {
33     Insert { value: Data },
34     Remove { value: Data },
35     Contains { value: Data },
36     Get { value: Data },
37     GetOrInsert { value: Data },
38     Iter,
39     Drain,
40     Clear,
41     Reserve { additional: usize },
42     ShrinkToFit,
43 }
44 
45 fuzz_target!(|commands: Vec<LinkedHashSetMethods>| {
46     let mut set = LinkedHashSet::new();
47     for command in commands {
48         match command {
49             LinkedHashSetMethods::Insert { value } => {
50                 set.insert(value);
51             }
52             LinkedHashSetMethods::Remove { value } => {
53                 set.remove(&value);
54             }
55             LinkedHashSetMethods::Contains { value } => {
56                 set.contains(&value);
57             }
58             LinkedHashSetMethods::Get { value } => {
59                 set.get(&value);
60             }
61             LinkedHashSetMethods::GetOrInsert { value } => {
62                 set.get_or_insert(value);
63             }
64             LinkedHashSetMethods::Iter => {
65                 std::hint::black_box(set.iter().count());
66             }
67             LinkedHashSetMethods::Drain => {
68                 std::hint::black_box(set.drain().count());
69             }
70             LinkedHashSetMethods::Clear => {
71                 set.clear();
72             }
73             LinkedHashSetMethods::Reserve { additional } => {
74                 // Avoid allocating too much memory and crashing the fuzzer.
75                 set.reserve(additional % MAX_RESERVE);
76             }
77             LinkedHashSetMethods::ShrinkToFit => {
78                 set.shrink_to_fit();
79             }
80         }
81     }
82 });
83