blob: e3091b0763c00c8f9f392605094f60565d984438 [file] [log] [blame]
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <limits>
#include <memory>
#include <string>
#include <vector>
#include "base/check_op.h"
#include "base/optional.h"
#include "base/strings/string_piece.h"
#include "net/dns/record_rdata.h"
namespace net {
namespace {
base::StringPiece MakeStringPiece(const std::vector<uint8_t>& vec) {
return base::StringPiece(reinterpret_cast<const char*>(vec.data()),
vec.size());
}
// For arbitrary data, check that parse(data).serialize() == data.
void ParseThenSerializeProperty(const std::vector<uint8_t>& data) {
auto parsed = IntegrityRecordRdata::Create(MakeStringPiece(data));
CHECK(parsed);
base::Optional<std::vector<uint8_t>> maybe_serialized = parsed->Serialize();
// Since |data| is chosen by a fuzzer, the record's digest is unlikely to
// match its nonce. As a result, |parsed->IsIntact()| may be false, and thus
// |parsed->Serialize()| may be |base::nullopt|.
CHECK_EQ(parsed->IsIntact(), !!maybe_serialized);
if (maybe_serialized) {
CHECK(data == *maybe_serialized);
}
}
// For arbitrary IntegrityRecordRdata r, check that parse(r.serialize()) == r.
void SerializeThenParseProperty(const std::vector<uint8_t>& data) {
// Ensure that the nonce is not too long to be serialized.
if (data.size() > std::numeric_limits<uint16_t>::max()) {
// Property is vacuously true because the record is not serializable.
return;
}
// Build an IntegrityRecordRdata by treating |data| as a nonce.
IntegrityRecordRdata record(data);
CHECK(record.IsIntact());
base::Optional<std::vector<uint8_t>> maybe_serialized = record.Serialize();
CHECK(maybe_serialized.has_value());
// Parsing |serialized| always produces a record identical to the original.
auto parsed =
IntegrityRecordRdata::Create(MakeStringPiece(*maybe_serialized));
CHECK(parsed);
CHECK(parsed->IsIntact());
CHECK(parsed->IsEqual(&record));
}
} // namespace
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
const std::vector<uint8_t> data_vec(data, data + size);
ParseThenSerializeProperty(data_vec);
SerializeThenParseProperty(data_vec);
// Construct a random IntegrityRecordRdata to exercise that code path. No need
// to exercise parse/serialize since we already did that with |data|.
IntegrityRecordRdata rand_record(IntegrityRecordRdata::Random());
return 0;
}
} // namespace net