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::LruCache;
19 use libfuzzer_sys::arbitrary::Arbitrary;
20 use libfuzzer_sys::fuzz_target;
21 
22 #[derive(Arbitrary, Debug, Eq, Hash, PartialEq)]
23 enum Data {
24     A,
25     B,
26     Int { val: u8 },
27 }
28 
29 #[derive(Arbitrary, Debug)]
30 struct LruCacheFuzzInfo {
31     capacity: u8,
32     commands: Vec<LruCacheMethods>,
33 }
34 
35 #[derive(Arbitrary, Debug)]
36 enum LruCacheMethods {
37     Insert { key: Data, value: Data },
38     Remove { key: Data },
39     ContainsKey { key: Data },
40     Get { key: Data },
41     EntryOrInsert { key: Data, value: Data },
42     Iter,
43     Drain,
44     Clear,
45     Peek { key: Data },
46     RemoveLru,
47 }
48 
49 fuzz_target!(|info: LruCacheFuzzInfo| {
50     let mut cache = LruCache::new(info.capacity.into());
51     for command in info.commands {
52         match command {
53             LruCacheMethods::Insert { key, value } => {
54                 cache.insert(key, value);
55             }
56             LruCacheMethods::Remove { key } => {
57                 cache.remove(&key);
58             }
59             LruCacheMethods::ContainsKey { key } => {
60                 cache.contains_key(&key);
61             }
62             LruCacheMethods::Get { key } => {
63                 cache.get(&key);
64             }
65             LruCacheMethods::EntryOrInsert { key, value } => {
66                 cache.entry(key).or_insert(value);
67             }
68             LruCacheMethods::Iter => {
69                 std::hint::black_box(cache.iter().count());
70             }
71             LruCacheMethods::Drain => {
72                 std::hint::black_box(cache.drain().count());
73             }
74             LruCacheMethods::Clear => {
75                 cache.clear();
76             }
77             LruCacheMethods::Peek { key } => {
78                 cache.peek(&key);
79             }
80             LruCacheMethods::RemoveLru => {
81                 cache.remove_lru();
82             }
83         }
84     }
85 });
86