Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(565)

Side by Side Diff: net/url_request/url_request_data_job_fuzzer.cc

Issue 1919013003: Add fuzzer to test Fuzz URLRequestDataJob (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@url_request_fuzzer
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/BUILD.gn ('k') | net/url_request/url_request_test_util.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2016 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 #include <algorithm>
6 #include <memory>
7
8 #include "base/memory/ptr_util.h"
9 #include "base/run_loop.h"
10 #include "base/strings/stringprintf.h"
11 #include "net/base/fuzzed_data_provider.h"
12 #include "net/http/http_request_headers.h"
13 #include "net/url_request/data_protocol_handler.h"
14 #include "net/url_request/url_request_job_factory_impl.h"
15 #include "net/url_request/url_request_test_util.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17
18 namespace {
19
20 std::string GenerateRandomRange(const char* bytes, size_t size) {
eroman 2016/04/25 23:51:30 Please document. This isn't necessarily generatin
Charlie Harrison 2016/04/26 12:58:40 The goal is to give some structure so the fuzzer d
eroman 2016/04/27 00:43:01 I prefer having the fuzzer build the range request
Charlie Harrison 2016/04/27 17:39:54 Sounds good to me. I've removed this code.
21 static std::vector<char> range_vals{'\0', '-', '0', '1', '2', '3', '4',
eroman 2016/04/27 00:43:01 unfortunately our style guide doesn't allow this y
Charlie Harrison 2016/04/27 17:39:54 Removed.
22 '5', '6', '7', '8', '9', ','};
23 std::string range = "bytes=";
24 for (size_t i = 0; i < size; i++) {
25 char elt = range_vals[bytes[i] % range_vals.size()];
26 if (elt == '\0')
27 break;
28 range.push_back(elt);
29 }
30 return range;
31 }
32
33 } // namespace
34
35 // Fuzz different read lengths, different range requests, and different data.
eroman 2016/04/25 23:51:31 Please add a more general description of what the
Charlie Harrison 2016/04/26 12:58:40 Done.
36 // The structure of the data that the fuzzer generates looks like:
37 // |-- 16 bytes of header --|------ data url ------|-- read metadata --|
38 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
39 static const size_t max_length = 256;
40 static const size_t max_range_length = 16;
41 EXPECT_LE(size, max_length);
42
43 // Statically initialize most of the harness, per fuzzing efficiency best
44 // practices. Without these the test runs much slower.
45 static char range_bytes[max_range_length];
eroman 2016/04/25 23:51:30 Rather than N different statics, please extract th
Charlie Harrison 2016/04/26 12:58:40 Done. Good suggestion.
46 static char data_bytes[max_length];
47 static net::TestURLRequestContext context(true);
48 static net::URLRequestJobFactoryImpl job_factory;
49 static net::TestDelegate delegate;
50 static std::vector<size_t> read_lengths;
51 static net::IOBuffer* buf = new net::IOBuffer(size);
52
53 // One off initialization.
54 static bool initialized = false;
55 if (!initialized) {
56 job_factory.SetProtocolHandler(
eroman 2016/04/25 23:51:30 This for instance would just be part of the single
Charlie Harrison 2016/04/26 12:58:39 Done.
57 "data", base::WrapUnique(new net::DataProtocolHandler()));
58 context.set_job_factory(&job_factory);
59 context.Init();
60 initialized = true;
61 }
62
63 // Per-test initialization.
64 read_lengths.clear();
65 net::FuzzedDataProvider provider(data, size);
66
67 // Generate data for range header. Use 16 bytes to get a good range of header
68 // values, including multiple ranges. Early return if the generated range
69 // header is invalid.
70 size_t range_bytes_size =
71 provider.ConsumeBytes(range_bytes, max_range_length);
72 std::string range = GenerateRandomRange(range_bytes, range_bytes_size);
73 if (!net::HttpUtil::IsValidHeaderValue(range))
74 return 0;
75
76 // Generate a sequence of reads sufficient to read the entire data url.
77 size_t bytes_for_data_url = 0;
78 if (size > range_bytes_size)
79 bytes_for_data_url = size - range_bytes_size;
80
81 size_t simulated_bytes_read = 0;
82 while (simulated_bytes_read < bytes_for_data_url) {
83 size_t read_length = provider.ConsumeBits(8);
84 read_lengths.push_back(read_length);
85 simulated_bytes_read += read_length;
86 // subtract one because we are consuming 8 bits off the end with every read
87 // for metadata.
88 bytes_for_data_url -= 1;
eroman 2016/04/25 23:51:30 This seems like something that could be encapsulat
Charlie Harrison 2016/04/26 12:58:40 We'll still need to keep track of this length to m
89 }
90 size_t data_size = provider.ConsumeBytes(data_bytes, bytes_for_data_url);
91 std::string data_string(data_bytes, data_size);
92
93 // Finally, create a URLRequest with the given data url and start reading from
94 // it.
95 std::unique_ptr<net::URLRequest> request = context.CreateRequest(
96 GURL("data:" + data_string), net::DEFAULT_PRIORITY, &delegate);
97 request->SetExtraRequestHeaderByName("Range", range, true);
eroman 2016/04/25 23:51:30 Might want "no range header" to be a possible inpu
Charlie Harrison 2016/04/26 12:58:39 Done.
98 request->Start();
99 for (const size_t read_length : read_lengths) {
100 base::RunLoop().RunUntilIdle();
101 int bytes_read = 0;
102 request->Read(buf, read_length, &bytes_read);
103 }
104 return 0;
105 }
OLDNEW
« no previous file with comments | « net/BUILD.gn ('k') | net/url_request/url_request_test_util.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698