// 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 #include #include #include #include "base/check.h" #include "base/check_op.h" #include "base/files/file_path.h" #include "base/pickle.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" namespace base { namespace { FilePath::StringType GenerateNativeString(FuzzedDataProvider& provider) { const std::string raw_string = provider.ConsumeRandomLengthString(); #if BUILDFLAG(IS_WIN) return UTF8ToWide(raw_string); #else return raw_string; #endif } bool IsValidExtension(const FilePath::StringType& text) { return text.empty() || text[0] == FilePath::kExtensionSeparator; } } // namespace extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { if (size > 10 * 1000) { // Bail out on huge inputs to avoid spurious timeout or OOM reports. return 0; } FuzzedDataProvider provider(data, size); // Create a random path. Smoke-test its getters. const FilePath path(GenerateNativeString(provider)); std::ignore = path.GetComponents(); std::ignore = path.DirName(); std::ignore = path.BaseName(); std::ignore = path.Extension(); std::ignore = path.FinalExtension(); std::ignore = path.RemoveExtension(); std::ignore = path.RemoveFinalExtension(); std::ignore = path.IsAbsolute(); std::ignore = path.IsNetwork(); std::ignore = path.EndsWithSeparator(); std::ignore = path.AsEndingWithSeparator(); std::ignore = path.StripTrailingSeparators(); std::ignore = path.ReferencesParent(); std::ignore = path.LossyDisplayName(); std::ignore = path.MaybeAsASCII(); std::ignore = path.AsUTF8Unsafe(); std::ignore = path.AsUTF16Unsafe(); std::ignore = path.NormalizePathSeparators(); // Smoke-test operations against a text. const auto text = GenerateNativeString(provider); std::ignore = path.InsertBeforeExtension(text); std::ignore = path.AddExtension(text); std::ignore = path.ReplaceExtension(text); if (IsValidExtension(text)) { std::ignore = path.MatchesExtension(text); std::ignore = path.MatchesFinalExtension(text); } // Check ASCII variants as well. const auto text_ascii = provider.ConsumeRandomLengthString(); if (IsStringASCII(text_ascii)) { std::ignore = path.InsertBeforeExtensionASCII(text_ascii); std::ignore = path.AddExtensionASCII(text_ascii); } // Test Pickle roundtrip. Pickle pickle; path.WriteToPickle(&pickle); PickleIterator pickle_iterator(pickle); FilePath decoded; CHECK(decoded.ReadFromPickle(&pickle_iterator)); CHECK_EQ(decoded, path); // Smoke-test operations against a second path. FilePath second_path(GenerateNativeString(provider)); std::ignore = path.IsParent(second_path); if (!second_path.IsAbsolute()) std::ignore = path.Append(second_path); FilePath relative_path; std::ignore = path.AppendRelativePath(second_path, &relative_path); return 0; } } // namespace base