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::LinkedHashMap;
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 LinkedHashMapMethods {
33     Insert { key: Data, value: Data },
34     Remove { key: Data },
35     ContainsKey { key: Data },
36     Get { key: Data },
37     EntryOrInsert { key: Data, value: Data },
38     Iter,
39     Drain,
40     Clear,
41     Reserve { additional: usize },
42     ShrinkToFit,
43 }
44 
45 fuzz_target!(|commands: Vec<LinkedHashMapMethods>| {
46     let mut map = LinkedHashMap::new();
47     for command in commands {
48         match command {
49             LinkedHashMapMethods::Insert { key, value } => {
50                 map.insert(key, value);
51             }
52             LinkedHashMapMethods::Remove { key } => {
53                 map.remove(&key);
54             }
55             LinkedHashMapMethods::ContainsKey { key } => {
56                 map.contains_key(&key);
57             }
58             LinkedHashMapMethods::Get { key } => {
59                 map.get(&key);
60             }
61             LinkedHashMapMethods::EntryOrInsert { key, value } => {
62                 map.entry(key).or_insert(value);
63             }
64             LinkedHashMapMethods::Iter => {
65                 std::hint::black_box(map.iter().count());
66             }
67             LinkedHashMapMethods::Drain => {
68                 std::hint::black_box(map.drain().count());
69             }
70             LinkedHashMapMethods::Clear => {
71                 map.clear();
72             }
73             LinkedHashMapMethods::Reserve { additional } => {
74                 // Avoid allocating too much memory and crashing the fuzzer.
75                 map.reserve(additional % MAX_RESERVE);
76             }
77             LinkedHashMapMethods::ShrinkToFit => {
78                 map.shrink_to_fit();
79             }
80         }
81     }
82 });
83