Coverage Report

Created: 2025-01-26 06:54

/src/boost_regex_replace_fuzzer.cc
Line
Count
Source
1
/* Copyright 2024 Google LLC
2
Licensed under the Apache License, Version 2.0 (the "License");
3
you may not use this file except in compliance with the License.
4
You may obtain a copy of the License at
5
      http://www.apache.org/licenses/LICENSE-2.0
6
Unless required by applicable law or agreed to in writing, software
7
distributed under the License is distributed on an "AS IS" BASIS,
8
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9
See the License for the specific language governing permissions and
10
limitations under the License.
11
*/
12
// The ideal place for this fuzz target is the boost repository.
13
#include <boost/regex.hpp>
14
#ifdef DEBUG
15
#include <iostream>
16
#endif
17
#include <sstream>
18
#include <string>
19
#include <iterator>
20
#include <fuzzer/FuzzedDataProvider.h>
21
22
// purpose of the fuzzer:
23
// fuzz the format string syntax used in match-replace
24
//
25
// the mutator comes from a boost example that:
26
// takes the contents of a file and transform to
27
// syntax highlighted code in html format
28
29
boost::regex e1, e2;
30
extern const char* expression_text;
31
extern const char* pre_expression;
32
extern const char* pre_format;
33
extern const char* match_against;
34
35
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) 
36
16.0k
{
37
16.0k
    FuzzedDataProvider fdp(Data, Size);
38
16.0k
    std::string format_string = fdp.ConsumeRemainingBytesAsString();
39
16.0k
    try{
40
16.0k
        e1.assign(expression_text);
41
16.0k
        e2.assign(pre_expression);
42
16.0k
        std::string in;
43
16.0k
        in.assign(match_against);
44
16.0k
        std::ostringstream t(std::ios::out | std::ios::binary);
45
16.0k
        std::ostream_iterator<char, char> oi(t);
46
16.0k
        boost::regex_replace(oi, in.begin(), in.end(),
47
16.0k
            e2, format_string, boost::match_default | boost::format_all);
48
16.0k
        std::string s(t.str());
49
#ifdef DEBUG
50
        std::cout << s << std::endl;
51
#endif
52
16.0k
    } catch(...) {
53
10.6k
    }
54
16.0k
    return 0;
55
16.0k
}
56
57
const char* pre_expression = "(<)|(>)|(&)|\\r";
58
const char* pre_format = "(?1&lt;)(?2&gt;)(?3&amp;)";
59
60
61
const char* expression_text =
62
    // preprocessor directives: index 1
63
    "(^[[:blank:]]*#(?:[^\\\\\\n]|\\\\[^\\n[:punct:][:word:]]*[\\n[:punct:][:word:]])*)|"
64
    // comment: index 2
65
    "(//[^\\n]*|/\\*.*?\\*/)|"
66
    // literals: index 3
67
    "\\<([+-]?(?:(?:0x[[:xdigit:]]+)|(?:(?:[[:digit:]]*\\.)?[[:digit:]]+"
68
    "(?:[eE][+-]?[[:digit:]]+)?))u?(?:(?:int(?:8|16|32|64))|L)?)\\>|"
69
    // string literals: index 4
70
    "('(?:[^\\\\']|\\\\.)*'|\"(?:[^\\\\\"]|\\\\.)*\")|"
71
    // keywords: index 5
72
    "\\<(__asm|__cdecl|__declspec|__export|__far16|__fastcall|__fortran|__import"
73
    "|__pascal|__rtti|__stdcall|_asm|_cdecl|__except|_export|_far16|_fastcall"
74
    "|__finally|_fortran|_import|_pascal|_stdcall|__thread|__try|asm|auto|bool"
75
    "|break|case|catch|cdecl|char|class|const|const_cast|continue|default|delete"
76
    "|do|double|dynamic_cast|else|enum|explicit|extern|false|float|for|friend|goto"
77
    "|if|inline|int|long|mutable|namespace|new|operator|pascal|private|protected"
78
    "|public|register|reinterpret_cast|return|short|signed|sizeof|static|static_cast"
79
    "|struct|switch|template|this|throw|true|try|typedef|typeid|typename|union|unsigned"
80
    "|using|virtual|void|volatile|wchar_t|while)\\>"
81
    ;
82
83
84
const char* match_against = "#include <iostream>"
85
"#include <string>"
86
"#include <vector>"
87
"#include <boost/regex.hpp>"
88
""
89
""
90
"extern \"C\" int main(int argc, char** argv) {"
91
"   std::string regex_string;"
92
"     std::getline(std::cin, regex_string);"
93
"       std::string where(\"AAAA\");"
94
"         try {"
95
"         boost::regex e(regex_string);"
96
"             std::cout << \"Regexp string: \" << regex_string << \"Size: \" << regex_string.size() << std::endl;"
97
"           boost::match_results<std::string::const_iterator> what;"
98
"               bool match = boost::regex_match(where, what, e, boost::match_default | boost::match_partial | boost::match_perl | boost::match_posix | boost::match_any);"
99
"             if (match)"
100
"                     std::cout << match << std::endl;"
101
"               }"
102
"     catch (const std::runtime_error &err) {"
103
"               std::cerr << \"Caught exception: \" << err.what() << std::endl;"
104
"           }"
105
"       return 0;"
106
"}";
107