blob: f11c0e13c9b430454ecfdb419d43e5ef5bc78f22 [file]
// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/strings/string_tokenizer.h"
#include <stddef.h>
#include <stdint.h>
#include <string>
#include <string_view>
#include <tuple>
#include "base/containers/span.h"
#include "testing/libfuzzer/libfuzzer_base_wrappers.h"
void GetAllTokens(base::StringTokenizer& t) {
while (t.GetNext()) {
std::ignore = t.token();
}
}
// Entry point for LibFuzzer.
DEFINE_LLVM_FUZZER_TEST_ONE_INPUT_SPAN(base::span<const uint8_t> data) {
if (data.size() < sizeof(size_t) + 1) {
return 0;
}
// Calculate pattern size based on remaining bytes, otherwise fuzzing is
// inefficient with bailouts in most cases.
size_t pattern_size;
base::byte_span_from_ref(pattern_size)
.copy_from_nonoverlapping(data.take_first<sizeof(size_t)>());
pattern_size %= data.size();
auto [pattern_span, input_span] = data.split_at(pattern_size);
const std::string pattern(std::from_range, pattern_span);
const std::string input(std::from_range, input_span);
// Allow quote_chars and options to be set. Otherwise full coverage
// won't be possible since IsQuote, FullGetNext and other functions
// won't be called.
for (bool return_delims : {false, true}) {
for (bool return_empty_strings : {false, true}) {
int options = 0;
if (return_delims) {
options |= base::StringTokenizer::RETURN_DELIMS;
}
if (return_empty_strings) {
options |= base::StringTokenizer::RETURN_EMPTY_TOKENS;
}
base::StringTokenizer t(input, pattern);
t.set_options(options);
GetAllTokens(t);
base::StringTokenizer t_quote(input, pattern);
t_quote.set_quote_chars("\"");
t_quote.set_options(options);
GetAllTokens(t_quote);
}
}
return 0;
}