1 /*
2  * Copyright 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #include "fuzzer/FuzzedDataProvider.h"
17 #include "utils/Vector.h"
18 static constexpr uint16_t MAX_VEC_SIZE = 5000;
19 
runVectorFuzz(const uint8_t * data,size_t size)20 void runVectorFuzz(const uint8_t* data, size_t size) {
21     FuzzedDataProvider dataProvider(data, size);
22     android::Vector<uint8_t> vec = android::Vector<uint8_t>();
23     // We want to test handling of sizeof as well.
24     android::Vector<uint32_t> vec32 = android::Vector<uint32_t>();
25 
26     // We're going to generate two vectors of this size
27     size_t vectorSize = dataProvider.ConsumeIntegralInRange<size_t>(0, MAX_VEC_SIZE);
28     vec.setCapacity(vectorSize);
29     vec32.setCapacity(vectorSize);
30     for (size_t i = 0; i < vectorSize; i++) {
31         uint8_t count = dataProvider.ConsumeIntegralInRange<uint8_t>(1, 5);
32         vec.insertAt((uint8_t)i, i, count);
33         vec32.insertAt((uint32_t)i, i, count);
34         vec.push_front(i);
35         vec32.push(i);
36     }
37 
38     // Now we'll perform some test operations with any remaining data
39     // Index to perform operations at
40     size_t index = dataProvider.ConsumeIntegralInRange<size_t>(0, vec.size());
41     std::vector<uint8_t> remainingVec = dataProvider.ConsumeRemainingBytes<uint8_t>();
42     // Insert an array and vector
43     vec.insertArrayAt(remainingVec.data(), index, remainingVec.size());
44     android::Vector<uint8_t> vecCopy = android::Vector<uint8_t>(vec);
45     vec.insertVectorAt(vecCopy, index);
46     // Same thing for 32 bit vector
47     android::Vector<uint32_t> vec32Copy = android::Vector<uint32_t>(vec32);
48     vec32.insertArrayAt(vec32Copy.array(), index, vec32.size());
49     vec32.insertVectorAt(vec32Copy, index);
50     // Replace single character
51     if (remainingVec.size() > 0) {
52         vec.replaceAt(remainingVec[0], index);
53         vec32.replaceAt(static_cast<uint32_t>(remainingVec[0]), index);
54     } else {
55         vec.replaceAt(0, index);
56         vec32.replaceAt(0, index);
57     }
58     // Add any remaining bytes
59     for (uint8_t i : remainingVec) {
60         vec.add(i);
61         vec32.add(static_cast<uint32_t>(i));
62     }
63     // Shrink capactiy
64     vec.setCapacity(remainingVec.size());
65     vec32.setCapacity(remainingVec.size());
66     // Iterate through each pointer
67     size_t sum = 0;
68     for (auto& it : vec) {
69         sum += it;
70     }
71     for (auto& it : vec32) {
72         sum += it;
73     }
74     // Cleanup
75     vec.clear();
76     vecCopy.clear();
77     vec32.clear();
78     vec32Copy.clear();
79 }
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)80 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
81     runVectorFuzz(data, size);
82     return 0;
83 }
84