OLD | NEW |
| (Empty) |
1 // Copyright 2017 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 // Fuzzer for content/renderer | |
6 | |
7 #include <stddef.h> | |
8 #include <stdint.h> | |
9 #include <memory> | |
10 #include <sstream> | |
11 | |
12 #include "content/test/fuzzer/fuzzer_support.h" | |
13 #include "content/test/fuzzer/html_tree.pb.h" | |
14 #include "third_party/libprotobuf-mutator/src/src/binary_format.h" | |
15 #include "third_party/libprotobuf-mutator/src/src/libfuzzer/libfuzzer_mutator.h" | |
16 | |
17 protobuf_mutator::protobuf::LogSilencer log_silincer; | |
18 | |
19 namespace content { | |
20 | |
21 class HtmlTreeWriter { | |
22 public: | |
23 HtmlTreeWriter() {} | |
24 | |
25 template <typename T> | |
26 HtmlTreeWriter& operator<<(const T& t) { | |
27 out_ << t; | |
28 return *this; | |
29 } | |
30 | |
31 std::string str() const { return out_.str(); } | |
32 | |
33 private: | |
34 std::ostringstream out_; | |
35 }; | |
36 | |
37 static HtmlTreeWriter& operator<<(HtmlTreeWriter& w, | |
38 const Attribute::Value& value) { | |
39 switch (value.value_case()) { | |
40 case Attribute::Value::kBoolValue: | |
41 return w << (value.bool_value() ? "true" : "false"); | |
42 case Attribute::Value::kUintValue: | |
43 return w << value.uint_value(); | |
44 case Attribute::Value::kIntValue: | |
45 return w << value.int_value(); | |
46 case Attribute::Value::kDoubleValue: | |
47 return w << value.double_value(); | |
48 case Attribute::Value::kPxValue: | |
49 return w << value.px_value() << "px"; | |
50 case Attribute::Value::kPctValue: | |
51 return w << value.pct_value() << "%"; | |
52 case Attribute::Value::VALUE_NOT_SET: | |
53 return w; | |
54 } | |
55 } | |
56 | |
57 static HtmlTreeWriter& operator<<(HtmlTreeWriter& w, | |
58 const Attribute::Name& name) { | |
59 return w << Attribute_Name_Name(name); | |
60 } | |
61 | |
62 static HtmlTreeWriter& operator<<(HtmlTreeWriter& w, const Attribute& attr) { | |
63 return w << attr.name() << "=\"" << attr.value() << "\""; | |
64 } | |
65 | |
66 static HtmlTreeWriter& operator<<(HtmlTreeWriter& w, const Tag::Name& tagName) { | |
67 return w << Tag_Name_Name(tagName); | |
68 } | |
69 | |
70 static void operator<<(HtmlTreeWriter& w, const Tag& tag) { | |
71 w << "<" << tag.name(); | |
72 for (const auto& attr : tag.attrs()) { | |
73 w << " " << attr; | |
74 } | |
75 | |
76 w << ">"; | |
77 for (const auto& subtag : tag.subtags()) { | |
78 w << subtag; | |
79 } | |
80 w << "</" << tag.name() << ">"; | |
81 } | |
82 | |
83 static void operator<<(HtmlTreeWriter& w, const Document& document) { | |
84 w << document.root(); | |
85 } | |
86 | |
87 static std::string str(const uint8_t* data, size_t size) { | |
88 Document document; | |
89 protobuf_mutator::ParseBinaryMessage(data, size, &document); | |
90 | |
91 HtmlTreeWriter writer; | |
92 writer << document; | |
93 return writer.str(); | |
94 // return document.ShortDebugString(); | |
95 } | |
96 | |
97 extern "C" void LLVMPrintInput(const uint8_t* data, size_t size) { | |
98 // fprintf(stderr, "NEW %s\n", str(data, size).c_str()); | |
99 } | |
100 | |
101 extern "C" size_t LLVMFuzzerCustomMutator(uint8_t* data, | |
102 size_t size, | |
103 size_t max_size, | |
104 unsigned int seed) { | |
105 fprintf(stderr, "BEFORE %s\n", str(data, size).c_str()); | |
106 size_t new_size = protobuf_mutator::libfuzzer::MutateBinaryMessage<Document>( | |
107 data, size, max_size, seed); | |
108 fprintf(stderr, "AFTER %s\n", str(data, new_size).c_str()); | |
109 return new_size; | |
110 } | |
111 | |
112 extern "C" size_t LLVMFuzzerCustomCrossOver(const uint8_t* data1, | |
113 size_t size1, | |
114 const uint8_t* data2, | |
115 size_t size2, | |
116 uint8_t* out, | |
117 size_t max_out_size, | |
118 unsigned int seed) { | |
119 fprintf(stderr, "BEFOR1 %s\n", str(data1, size1).c_str()); | |
120 fprintf(stderr, "BEFOR2 %s\n", str(data2, size2).c_str()); | |
121 size_t new_size = | |
122 protobuf_mutator::libfuzzer::CrossOverBinaryMessages<Document>( | |
123 data1, size1, data2, size2, out, max_out_size, seed); | |
124 fprintf(stderr, "AFTER %s\n", str(data1, new_size).c_str()); | |
125 return new_size; | |
126 } | |
127 | |
128 static Env* env = nullptr; | |
129 | |
130 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { | |
131 // Environment has to be initialized in the same thread. | |
132 if (env == nullptr) | |
133 env = new Env(); | |
134 | |
135 // str(data, size); | |
136 | |
137 env->adapter->LoadHTML(str(data, size), "http://www.example.org"); | |
138 | |
139 // fprintf(stderr, "%s\n", writer.str().c_str()); | |
140 | |
141 return 0; | |
142 } | |
143 | |
144 } // namespace content | |
OLD | NEW |