1 /*
2  * Copyright (C) 2021 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 <cppbor_parse.h>
17 
18 using namespace cppbor;
19 
20 class FuzzParseClient : public ParseClient {
21   public:
item(std::unique_ptr<Item> &,const uint8_t *,const uint8_t *,const uint8_t *)22     virtual ParseClient* item(std::unique_ptr<Item>&, const uint8_t*, const uint8_t*,
23                               const uint8_t*) override {
24         return this;
25     }
itemEnd(std::unique_ptr<Item> &,const uint8_t *,const uint8_t *,const uint8_t *)26     virtual ParseClient* itemEnd(std::unique_ptr<Item>&, const uint8_t*, const uint8_t*,
27                                  const uint8_t*) override {
28         return this;
29     }
error(const uint8_t *,const std::string &)30     virtual void error(const uint8_t*, const std::string&) override {}
31 };
32 
FuzzParse(const uint8_t * data,size_t size)33 void FuzzParse(const uint8_t* data, size_t size) {
34     const uint8_t* cursor = data;
35     const uint8_t* end = data + size;
36     while (cursor < end) {
37         auto [item, newPos, errMsg] = parse(cursor, end);
38         if (!item || !errMsg.empty()) {
39             return;
40         }
41         cursor = newPos;
42     }
43 }
44 
FuzzParseWithViews(const uint8_t * data,size_t size)45 void FuzzParseWithViews(const uint8_t* data, size_t size) {
46     const uint8_t* cursor = data;
47     const uint8_t* end = data + size;
48     while (cursor < end) {
49         auto [item, newPos, errMsg] = parseWithViews(cursor, end);
50         if (!item || !errMsg.empty()) {
51             return;
52         }
53         cursor = newPos;
54     }
55 }
56 
FuzzParseWithClient(const uint8_t * data,size_t size)57 void FuzzParseWithClient(const uint8_t* data, size_t size) {
58     const uint8_t* end = data + size;
59     FuzzParseClient parseClient;
60     parse(data, end, &parseClient);
61 }
62 
FuzzParseWithClientAndViews(const uint8_t * data,size_t size)63 void FuzzParseWithClientAndViews(const uint8_t* data, size_t size) {
64     const uint8_t* end = data + size;
65     FuzzParseClient parseClient;
66     parseWithViews(data, end, &parseClient);
67 }
68 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)69 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
70     FuzzParse(data, size);
71     FuzzParseWithViews(data, size);
72     FuzzParseWithClient(data, size);
73     FuzzParseWithClientAndViews(data, size);
74     return 0;
75 }
76