// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/40284755): Remove this and spanify to fix the errors.
#pragma allow_unsafe_buffers
#endif
// Fuzzer for SpdyHeaderstoHttpResponseHeadersUsingBuilder. Compares the output
// for the same input to SpdyHeadersToHttpResponseHeadersUsingRawString and
// verifies they match.
// TODO(ricea): Remove this when SpdyHeadersToHttpResponseHeadersUsingRawString
// is removed.
#include <stddef.h>
#include <string_view>
#include "base/check.h"
#include "base/check_op.h"
#include "base/memory/ref_counted.h"
#include "base/types/expected.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_util.h"
#include "net/spdy/spdy_http_utils.h"
#include "net/third_party/quiche/src/quiche/common/http/http_header_block.h"
namespace net {
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
std::string_view rest(reinterpret_cast<const char*>(data), size);
// We split the input at "\n" to force the fuzzer to produce a corpus that is
// human-readable. "\n" cannot appear in a valid header name or value so this
// is safe.
auto get_string = [&rest]() {
size_t newline_pos = rest.find('\n');
if (newline_pos == std::string_view::npos) {
newline_pos = rest.size();
}
std::string_view first_line = rest.substr(0, newline_pos);
if (newline_pos + 1 < rest.size()) {
rest = rest.substr(newline_pos + 1);
} else {
rest = std::string_view();
}
return first_line;
};
quiche::HttpHeaderBlock input;
const std::string_view status = get_string();
if (!HttpUtil::IsValidHeaderValue(status)) {
return 0;
}
input[":status"] = status;
while (!rest.empty()) {
const std::string_view name = get_string();
if (!HttpUtil::IsValidHeaderName(name)) {
return 0;
}
const std::string_view value = get_string();
if (!HttpUtil::IsValidHeaderValue(value)) {
return 0;
}
input.AppendValueOrAddHeader(name, value);
}
const auto by_builder = SpdyHeadersToHttpResponseHeadersUsingBuilder(input);
const auto by_raw_string =
SpdyHeadersToHttpResponseHeadersUsingRawString(input);
if (by_builder.has_value()) {
CHECK(by_builder.value()->StrictlyEquals(*by_raw_string.value()));
} else {
CHECK(!by_raw_string.has_value());
CHECK_EQ(by_builder.error(), by_raw_string.error());
}
return 0;
}
} // namespace net