xref: /aosp_15_r20/external/cronet/net/base/filename_util_icu.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2014 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 "net/base/filename_util.h"
6 
7 #include <string>
8 
9 #include "base/check.h"
10 #include "base/files/file_path.h"
11 #include "base/i18n/file_util_icu.h"
12 #include "build/chromeos_buildflags.h"
13 #include "net/base/filename_util_internal.h"
14 
15 class GURL;
16 
17 namespace net {
18 
IsSafePortablePathComponent(const base::FilePath & component)19 bool IsSafePortablePathComponent(const base::FilePath& component) {
20   std::u16string component16;
21   base::FilePath::StringType sanitized = component.value();
22   SanitizeGeneratedFileName(&sanitized, true);
23   base::FilePath::StringType extension = component.Extension();
24   if (!extension.empty())
25     extension.erase(extension.begin());  // Erase preceding '.'.
26   return !component.empty() && (component == component.BaseName()) &&
27          (component == component.StripTrailingSeparators()) &&
28          FilePathToString16(component, &component16) &&
29          base::i18n::IsFilenameLegal(component16) &&
30          !IsShellIntegratedExtension(extension) &&
31          (sanitized == component.value()) &&
32          !IsReservedNameOnWindows(component.value());
33 }
34 
IsSafePortableRelativePath(const base::FilePath & path)35 bool IsSafePortableRelativePath(const base::FilePath& path) {
36   if (path.empty() || path.IsAbsolute() || path.EndsWithSeparator())
37     return false;
38   std::vector<base::FilePath::StringType> components = path.GetComponents();
39   if (components.empty())
40     return false;
41   for (size_t i = 0; i < components.size() - 1; ++i) {
42     if (!IsSafePortablePathComponent(base::FilePath(components[i])))
43       return false;
44   }
45   return IsSafePortablePathComponent(path.BaseName());
46 }
47 
GetSuggestedFilename(const GURL & url,const std::string & content_disposition,const std::string & referrer_charset,const std::string & suggested_name,const std::string & mime_type,const std::string & default_name)48 std::u16string GetSuggestedFilename(const GURL& url,
49                                     const std::string& content_disposition,
50                                     const std::string& referrer_charset,
51                                     const std::string& suggested_name,
52                                     const std::string& mime_type,
53                                     const std::string& default_name) {
54   return GetSuggestedFilenameImpl(url, content_disposition, referrer_charset,
55                                   suggested_name, mime_type, default_name,
56                                   false, /* should_replace_extension */
57                                   &base::i18n::ReplaceIllegalCharactersInPath);
58 }
59 
GenerateFileName(const GURL & url,const std::string & content_disposition,const std::string & referrer_charset,const std::string & suggested_name,const std::string & mime_type,const std::string & default_file_name)60 base::FilePath GenerateFileName(const GURL& url,
61                                 const std::string& content_disposition,
62                                 const std::string& referrer_charset,
63                                 const std::string& suggested_name,
64                                 const std::string& mime_type,
65                                 const std::string& default_file_name) {
66   return GenerateFileName(url, content_disposition, referrer_charset,
67                           suggested_name, mime_type, default_file_name,
68                           false /* should_replace_extension */);
69 }
70 
GenerateFileName(const GURL & url,const std::string & content_disposition,const std::string & referrer_charset,const std::string & suggested_name,const std::string & mime_type,const std::string & default_file_name,bool should_replace_extension)71 base::FilePath GenerateFileName(const GURL& url,
72                                 const std::string& content_disposition,
73                                 const std::string& referrer_charset,
74                                 const std::string& suggested_name,
75                                 const std::string& mime_type,
76                                 const std::string& default_file_name,
77                                 bool should_replace_extension) {
78   base::FilePath generated_name(GenerateFileNameImpl(
79       url, content_disposition, referrer_charset, suggested_name, mime_type,
80       default_file_name, should_replace_extension,
81       &base::i18n::ReplaceIllegalCharactersInPath));
82 
83 #if BUILDFLAG(IS_CHROMEOS_ASH)
84   // When doing file manager operations on ChromeOS, the file paths get
85   // normalized in WebKit layer, so let's ensure downloaded files have
86   // normalized names. Otherwise, we won't be able to handle files with NFD
87   // utf8 encoded characters in name.
88   base::i18n::NormalizeFileNameEncoding(&generated_name);
89 #endif
90 
91   DCHECK(!generated_name.empty());
92 
93   return generated_name;
94 }
95 
96 }  // namespace net
97