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