File: form_data_parser_fuzzer.cc

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (97 lines) | stat: -rw-r--r-- 2,525 bytes parent folder | download | duplicates (9)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <stdint.h>

#include <memory>
#include <string>
#include <utility>
#include <vector>

#include <fuzzer/FuzzedDataProvider.h>

#include "base/logging.h"
#include "extensions/browser/api/web_request/form_data_parser.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_util.h"

using extensions::FormDataParser;

namespace {

// Does initialization and holds state that's shared across all runs.
class Environment {
 public:
  Environment() {
    // Disable noisy logging.
    logging::SetMinLogLevel(logging::LOGGING_FATAL);
  }
};

net::HttpRequestHeaders GenerateHttpRequestHeaders(
    FuzzedDataProvider& provider) {
  net::HttpRequestHeaders headers;
  for (;;) {
    const std::string key = provider.ConsumeRandomLengthString();
    const std::string value = provider.ConsumeRandomLengthString();
    if (key.empty() || !net::HttpUtil::IsValidHeaderName(key) ||
        !net::HttpUtil::IsValidHeaderValue(value)) {
      break;
    }
    headers.SetHeader(key, value);
  }
  return headers;
}

}  // namespace

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
  static Environment env;
  FuzzedDataProvider provider(data, size);

  // Create parser sources. Per API contract, they must outlive the parser.
  std::vector<std::string> sources;
  for (;;) {
    std::string source = provider.ConsumeRandomLengthString();
    if (source.empty()) {
      break;
    }
    sources.push_back(std::move(source));
  }

  // Create a parser with random initialization parameters.
  std::unique_ptr<FormDataParser> parser;
  switch (provider.ConsumeIntegralInRange<int>(0, 2)) {
    case 0: {
      parser = FormDataParser::Create(GenerateHttpRequestHeaders(provider));
      break;
    }
    case 1: {
      parser = FormDataParser::CreateFromContentTypeHeader(
          /*content_type_header=*/nullptr);
      break;
    }
    case 2: {
      std::string content_type_header = provider.ConsumeRandomLengthString();
      parser =
          FormDataParser::CreateFromContentTypeHeader(&content_type_header);
      break;
    }
  }
  if (!parser) {
    return 0;
  }

  // Run the parser.
  for (const auto& source : sources) {
    parser->SetSource(source);

    FormDataParser::Result result;
    while (parser->GetNextNameValue(&result)) {
      // Discard the result - we can't verify anything in it here.
    }
  }

  return 0;
}