1*6777b538SAndroid Build Coastguard Worker // Copyright 2022 The Chromium Authors 2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file. 4*6777b538SAndroid Build Coastguard Worker 5*6777b538SAndroid Build Coastguard Worker #include <fuzzer/FuzzedDataProvider.h> 6*6777b538SAndroid Build Coastguard Worker #include <stdint.h> 7*6777b538SAndroid Build Coastguard Worker 8*6777b538SAndroid Build Coastguard Worker #include <string> 9*6777b538SAndroid Build Coastguard Worker #include <tuple> 10*6777b538SAndroid Build Coastguard Worker 11*6777b538SAndroid Build Coastguard Worker #include "base/check.h" 12*6777b538SAndroid Build Coastguard Worker #include "base/check_op.h" 13*6777b538SAndroid Build Coastguard Worker #include "base/files/file_path.h" 14*6777b538SAndroid Build Coastguard Worker #include "base/pickle.h" 15*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_util.h" 16*6777b538SAndroid Build Coastguard Worker #include "base/strings/utf_string_conversions.h" 17*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h" 18*6777b538SAndroid Build Coastguard Worker 19*6777b538SAndroid Build Coastguard Worker namespace base { 20*6777b538SAndroid Build Coastguard Worker 21*6777b538SAndroid Build Coastguard Worker namespace { 22*6777b538SAndroid Build Coastguard Worker GenerateNativeString(FuzzedDataProvider & provider)23*6777b538SAndroid Build Coastguard WorkerFilePath::StringType GenerateNativeString(FuzzedDataProvider& provider) { 24*6777b538SAndroid Build Coastguard Worker const std::string raw_string = provider.ConsumeRandomLengthString(); 25*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN) 26*6777b538SAndroid Build Coastguard Worker return UTF8ToWide(raw_string); 27*6777b538SAndroid Build Coastguard Worker #else 28*6777b538SAndroid Build Coastguard Worker return raw_string; 29*6777b538SAndroid Build Coastguard Worker #endif 30*6777b538SAndroid Build Coastguard Worker } 31*6777b538SAndroid Build Coastguard Worker IsValidExtension(const FilePath::StringType & text)32*6777b538SAndroid Build Coastguard Workerbool IsValidExtension(const FilePath::StringType& text) { 33*6777b538SAndroid Build Coastguard Worker return text.empty() || text[0] == FilePath::kExtensionSeparator; 34*6777b538SAndroid Build Coastguard Worker } 35*6777b538SAndroid Build Coastguard Worker 36*6777b538SAndroid Build Coastguard Worker } // namespace 37*6777b538SAndroid Build Coastguard Worker LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)38*6777b538SAndroid Build Coastguard Workerextern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { 39*6777b538SAndroid Build Coastguard Worker if (size > 10 * 1000) { 40*6777b538SAndroid Build Coastguard Worker // Bail out on huge inputs to avoid spurious timeout or OOM reports. 41*6777b538SAndroid Build Coastguard Worker return 0; 42*6777b538SAndroid Build Coastguard Worker } 43*6777b538SAndroid Build Coastguard Worker FuzzedDataProvider provider(data, size); 44*6777b538SAndroid Build Coastguard Worker 45*6777b538SAndroid Build Coastguard Worker // Create a random path. Smoke-test its getters. 46*6777b538SAndroid Build Coastguard Worker const FilePath path(GenerateNativeString(provider)); 47*6777b538SAndroid Build Coastguard Worker std::ignore = path.GetComponents(); 48*6777b538SAndroid Build Coastguard Worker std::ignore = path.DirName(); 49*6777b538SAndroid Build Coastguard Worker std::ignore = path.BaseName(); 50*6777b538SAndroid Build Coastguard Worker std::ignore = path.Extension(); 51*6777b538SAndroid Build Coastguard Worker std::ignore = path.FinalExtension(); 52*6777b538SAndroid Build Coastguard Worker std::ignore = path.RemoveExtension(); 53*6777b538SAndroid Build Coastguard Worker std::ignore = path.RemoveFinalExtension(); 54*6777b538SAndroid Build Coastguard Worker std::ignore = path.IsAbsolute(); 55*6777b538SAndroid Build Coastguard Worker std::ignore = path.IsNetwork(); 56*6777b538SAndroid Build Coastguard Worker std::ignore = path.EndsWithSeparator(); 57*6777b538SAndroid Build Coastguard Worker std::ignore = path.AsEndingWithSeparator(); 58*6777b538SAndroid Build Coastguard Worker std::ignore = path.StripTrailingSeparators(); 59*6777b538SAndroid Build Coastguard Worker std::ignore = path.ReferencesParent(); 60*6777b538SAndroid Build Coastguard Worker std::ignore = path.LossyDisplayName(); 61*6777b538SAndroid Build Coastguard Worker std::ignore = path.MaybeAsASCII(); 62*6777b538SAndroid Build Coastguard Worker std::ignore = path.AsUTF8Unsafe(); 63*6777b538SAndroid Build Coastguard Worker std::ignore = path.AsUTF16Unsafe(); 64*6777b538SAndroid Build Coastguard Worker std::ignore = path.NormalizePathSeparators(); 65*6777b538SAndroid Build Coastguard Worker 66*6777b538SAndroid Build Coastguard Worker // Smoke-test operations against a text. 67*6777b538SAndroid Build Coastguard Worker const auto text = GenerateNativeString(provider); 68*6777b538SAndroid Build Coastguard Worker std::ignore = path.InsertBeforeExtension(text); 69*6777b538SAndroid Build Coastguard Worker std::ignore = path.AddExtension(text); 70*6777b538SAndroid Build Coastguard Worker std::ignore = path.ReplaceExtension(text); 71*6777b538SAndroid Build Coastguard Worker if (IsValidExtension(text)) { 72*6777b538SAndroid Build Coastguard Worker std::ignore = path.MatchesExtension(text); 73*6777b538SAndroid Build Coastguard Worker std::ignore = path.MatchesFinalExtension(text); 74*6777b538SAndroid Build Coastguard Worker } 75*6777b538SAndroid Build Coastguard Worker // Check ASCII variants as well. 76*6777b538SAndroid Build Coastguard Worker const auto text_ascii = provider.ConsumeRandomLengthString(); 77*6777b538SAndroid Build Coastguard Worker if (IsStringASCII(text_ascii)) { 78*6777b538SAndroid Build Coastguard Worker std::ignore = path.InsertBeforeExtensionASCII(text_ascii); 79*6777b538SAndroid Build Coastguard Worker std::ignore = path.AddExtensionASCII(text_ascii); 80*6777b538SAndroid Build Coastguard Worker } 81*6777b538SAndroid Build Coastguard Worker 82*6777b538SAndroid Build Coastguard Worker // Test Pickle roundtrip. 83*6777b538SAndroid Build Coastguard Worker Pickle pickle; 84*6777b538SAndroid Build Coastguard Worker path.WriteToPickle(&pickle); 85*6777b538SAndroid Build Coastguard Worker PickleIterator pickle_iterator(pickle); 86*6777b538SAndroid Build Coastguard Worker FilePath decoded; 87*6777b538SAndroid Build Coastguard Worker CHECK(decoded.ReadFromPickle(&pickle_iterator)); 88*6777b538SAndroid Build Coastguard Worker CHECK_EQ(decoded, path); 89*6777b538SAndroid Build Coastguard Worker 90*6777b538SAndroid Build Coastguard Worker // Smoke-test operations against a second path. 91*6777b538SAndroid Build Coastguard Worker FilePath second_path(GenerateNativeString(provider)); 92*6777b538SAndroid Build Coastguard Worker std::ignore = path.IsParent(second_path); 93*6777b538SAndroid Build Coastguard Worker if (!second_path.IsAbsolute()) 94*6777b538SAndroid Build Coastguard Worker std::ignore = path.Append(second_path); 95*6777b538SAndroid Build Coastguard Worker FilePath relative_path; 96*6777b538SAndroid Build Coastguard Worker std::ignore = path.AppendRelativePath(second_path, &relative_path); 97*6777b538SAndroid Build Coastguard Worker 98*6777b538SAndroid Build Coastguard Worker return 0; 99*6777b538SAndroid Build Coastguard Worker } 100*6777b538SAndroid Build Coastguard Worker 101*6777b538SAndroid Build Coastguard Worker } // namespace base 102