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