| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/base/filename_util.h" | 5 #include "net/base/filename_util.h" |
| 6 | 6 |
| 7 #include "base/files/file_path.h" | 7 #include "base/files/file_path.h" |
| 8 #include "base/files/file_util.h" | 8 #include "base/files/file_util.h" |
| 9 #include "base/strings/string_util.h" | 9 #include "base/strings/string_util.h" |
| 10 #include "base/strings/sys_string_conversions.h" | 10 #include "base/strings/sys_string_conversions.h" |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 63 url.ExtractFileName(), | 63 url.ExtractFileName(), |
| 64 UnescapeRule::SPACES | UnescapeRule::URL_SPECIAL_CHARS); | 64 UnescapeRule::SPACES | UnescapeRule::URL_SPECIAL_CHARS); |
| 65 | 65 |
| 66 // The URL's path should be escaped UTF-8, but may not be. | 66 // The URL's path should be escaped UTF-8, but may not be. |
| 67 std::string decoded_filename = unescaped_url_filename; | 67 std::string decoded_filename = unescaped_url_filename; |
| 68 if (!base::IsStringUTF8(decoded_filename)) { | 68 if (!base::IsStringUTF8(decoded_filename)) { |
| 69 // TODO(jshin): this is probably not robust enough. To be sure, we need | 69 // TODO(jshin): this is probably not robust enough. To be sure, we need |
| 70 // encoding detection. | 70 // encoding detection. |
| 71 base::string16 utf16_output; | 71 base::string16 utf16_output; |
| 72 if (!referrer_charset.empty() && | 72 if (!referrer_charset.empty() && |
| 73 net::ConvertToUTF16( | 73 net::ConvertToUTF16(unescaped_url_filename, referrer_charset.c_str(), |
| 74 unescaped_url_filename, referrer_charset.c_str(), &utf16_output)) { | 74 &utf16_output)) { |
| 75 decoded_filename = base::UTF16ToUTF8(utf16_output); | 75 decoded_filename = base::UTF16ToUTF8(utf16_output); |
| 76 } else { | 76 } else { |
| 77 decoded_filename = | 77 decoded_filename = |
| 78 base::WideToUTF8(base::SysNativeMBToWide(unescaped_url_filename)); | 78 base::WideToUTF8(base::SysNativeMBToWide(unescaped_url_filename)); |
| 79 } | 79 } |
| 80 } | 80 } |
| 81 // If the URL contains a (possibly empty) query, assume it is a generator, and | 81 // If the URL contains a (possibly empty) query, assume it is a generator, and |
| 82 // allow the determined extension to be overwritten. | 82 // allow the determined extension to be overwritten. |
| 83 *should_overwrite_extension = !decoded_filename.empty() && url.has_query(); | 83 *should_overwrite_extension = !decoded_filename.empty() && url.has_query(); |
| 84 | 84 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 128 for (size_t i = 0; i < arraysize(known_devices); ++i) { | 128 for (size_t i = 0; i < arraysize(known_devices); ++i) { |
| 129 // Exact match. | 129 // Exact match. |
| 130 if (filename_lower == known_devices[i]) | 130 if (filename_lower == known_devices[i]) |
| 131 return true; | 131 return true; |
| 132 // Starts with "DEVICE.". | 132 // Starts with "DEVICE.". |
| 133 if (filename_lower.find(std::string(known_devices[i]) + ".") == 0) | 133 if (filename_lower.find(std::string(known_devices[i]) + ".") == 0) |
| 134 return true; | 134 return true; |
| 135 } | 135 } |
| 136 | 136 |
| 137 static const char* const magic_names[] = { | 137 static const char* const magic_names[] = { |
| 138 // These file names are used by the "Customize folder" feature of the shell. | 138 // These file names are used by the "Customize folder" feature of the |
| 139 "desktop.ini", | 139 // shell. |
| 140 "thumbs.db", | 140 "desktop.ini", |
| 141 "thumbs.db", |
| 141 }; | 142 }; |
| 142 | 143 |
| 143 for (size_t i = 0; i < arraysize(magic_names); ++i) { | 144 for (size_t i = 0; i < arraysize(magic_names); ++i) { |
| 144 if (filename_lower == magic_names[i]) | 145 if (filename_lower == magic_names[i]) |
| 145 return true; | 146 return true; |
| 146 } | 147 } |
| 147 | 148 |
| 148 return false; | 149 return false; |
| 149 } | 150 } |
| 150 | 151 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 170 extension.erase(extension.begin()); // Erase preceding '.'. | 171 extension.erase(extension.begin()); // Erase preceding '.'. |
| 171 | 172 |
| 172 if ((ignore_extension || extension.empty()) && !mime_type.empty()) { | 173 if ((ignore_extension || extension.empty()) && !mime_type.empty()) { |
| 173 base::FilePath::StringType preferred_mime_extension; | 174 base::FilePath::StringType preferred_mime_extension; |
| 174 std::vector<base::FilePath::StringType> all_mime_extensions; | 175 std::vector<base::FilePath::StringType> all_mime_extensions; |
| 175 net::GetPreferredExtensionForMimeType(mime_type, &preferred_mime_extension); | 176 net::GetPreferredExtensionForMimeType(mime_type, &preferred_mime_extension); |
| 176 net::GetExtensionsForMimeType(mime_type, &all_mime_extensions); | 177 net::GetExtensionsForMimeType(mime_type, &all_mime_extensions); |
| 177 // If the existing extension is in the list of valid extensions for the | 178 // If the existing extension is in the list of valid extensions for the |
| 178 // given type, use it. This avoids doing things like pointlessly renaming | 179 // given type, use it. This avoids doing things like pointlessly renaming |
| 179 // "foo.jpg" to "foo.jpeg". | 180 // "foo.jpg" to "foo.jpeg". |
| 180 if (std::find(all_mime_extensions.begin(), | 181 if (std::find(all_mime_extensions.begin(), all_mime_extensions.end(), |
| 181 all_mime_extensions.end(), | |
| 182 extension) != all_mime_extensions.end()) { | 182 extension) != all_mime_extensions.end()) { |
| 183 // leave |extension| alone | 183 // leave |extension| alone |
| 184 } else if (!preferred_mime_extension.empty()) { | 184 } else if (!preferred_mime_extension.empty()) { |
| 185 extension = preferred_mime_extension; | 185 extension = preferred_mime_extension; |
| 186 } | 186 } |
| 187 } | 187 } |
| 188 | 188 |
| 189 #if defined(OS_WIN) | 189 #if defined(OS_WIN) |
| 190 static const base::FilePath::CharType default_extension[] = | 190 static const base::FilePath::CharType default_extension[] = |
| 191 FILE_PATH_LITERAL("download"); | 191 FILE_PATH_LITERAL("download"); |
| 192 | 192 |
| 193 // Rename shell-integrated extensions. | 193 // Rename shell-integrated extensions. |
| 194 // TODO(asanka): Consider stripping out the bad extension and replacing it | 194 // TODO(asanka): Consider stripping out the bad extension and replacing it |
| 195 // with the preferred extension for the MIME type if one is available. | 195 // with the preferred extension for the MIME type if one is available. |
| 196 if (IsShellIntegratedExtension(extension)) | 196 if (IsShellIntegratedExtension(extension)) |
| 197 extension.assign(default_extension); | 197 extension.assign(default_extension); |
| 198 #endif | 198 #endif |
| 199 | 199 |
| 200 *file_name = file_name->ReplaceExtension(extension); | 200 *file_name = file_name->ReplaceExtension(extension); |
| 201 } | 201 } |
| 202 | 202 |
| 203 bool FilePathToString16(const base::FilePath& path, base::string16* converted) { | 203 bool FilePathToString16(const base::FilePath& path, base::string16* converted) { |
| 204 #if defined(OS_WIN) | 204 #if defined(OS_WIN) |
| 205 return base::WideToUTF16( | 205 return base::WideToUTF16(path.value().c_str(), path.value().size(), |
| 206 path.value().c_str(), path.value().size(), converted); | 206 converted); |
| 207 #elif defined(OS_POSIX) | 207 #elif defined(OS_POSIX) |
| 208 std::string component8 = path.AsUTF8Unsafe(); | 208 std::string component8 = path.AsUTF8Unsafe(); |
| 209 return !component8.empty() && | 209 return !component8.empty() && |
| 210 base::UTF8ToUTF16(component8.c_str(), component8.size(), converted); | 210 base::UTF8ToUTF16(component8.c_str(), component8.size(), converted); |
| 211 #endif | 211 #endif |
| 212 } | 212 } |
| 213 | 213 |
| 214 base::string16 GetSuggestedFilenameImpl( | 214 base::string16 GetSuggestedFilenameImpl( |
| 215 const GURL& url, | 215 const GURL& url, |
| 216 const std::string& content_disposition, | 216 const std::string& content_disposition, |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 296 } | 296 } |
| 297 | 297 |
| 298 base::FilePath GenerateFileNameImpl( | 298 base::FilePath GenerateFileNameImpl( |
| 299 const GURL& url, | 299 const GURL& url, |
| 300 const std::string& content_disposition, | 300 const std::string& content_disposition, |
| 301 const std::string& referrer_charset, | 301 const std::string& referrer_charset, |
| 302 const std::string& suggested_name, | 302 const std::string& suggested_name, |
| 303 const std::string& mime_type, | 303 const std::string& mime_type, |
| 304 const std::string& default_file_name, | 304 const std::string& default_file_name, |
| 305 ReplaceIllegalCharactersCallback replace_illegal_characters_callback) { | 305 ReplaceIllegalCharactersCallback replace_illegal_characters_callback) { |
| 306 base::string16 file_name = | 306 base::string16 file_name = GetSuggestedFilenameImpl( |
| 307 GetSuggestedFilenameImpl(url, | 307 url, content_disposition, referrer_charset, suggested_name, mime_type, |
| 308 content_disposition, | 308 default_file_name, replace_illegal_characters_callback); |
| 309 referrer_charset, | |
| 310 suggested_name, | |
| 311 mime_type, | |
| 312 default_file_name, | |
| 313 replace_illegal_characters_callback); | |
| 314 | 309 |
| 315 #if defined(OS_WIN) | 310 #if defined(OS_WIN) |
| 316 base::FilePath generated_name(file_name); | 311 base::FilePath generated_name(file_name); |
| 317 #else | 312 #else |
| 318 base::FilePath generated_name( | 313 base::FilePath generated_name( |
| 319 base::SysWideToNativeMB(base::UTF16ToWide(file_name))); | 314 base::SysWideToNativeMB(base::UTF16ToWide(file_name))); |
| 320 #endif | 315 #endif |
| 321 | 316 |
| 322 DCHECK(!generated_name.empty()); | 317 DCHECK(!generated_name.empty()); |
| 323 | 318 |
| 324 return generated_name; | 319 return generated_name; |
| 325 } | 320 } |
| 326 | 321 |
| 327 } // namespace net | 322 } // namespace net |
| OLD | NEW |