xref: /aosp_15_r20/external/cronet/base/files/file_path_fuzzer.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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 Worker FilePath::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 Worker bool 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 Worker extern "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