Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(43)

Side by Side Diff: net/base/net_util.cc

Issue 7300005: Move filename determination to net_util (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: " Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/base/net_util.h ('k') | net/base/net_util_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/net_util.h" 5 #include "net/base/net_util.h"
6 6
7 #include <unicode/regex.h> 7 #include <unicode/regex.h>
8 #include <unicode/ucnv.h> 8 #include <unicode/ucnv.h>
9 #include <unicode/uidna.h> 9 #include <unicode/uidna.h>
10 #include <unicode/ulocdata.h> 10 #include <unicode/ulocdata.h>
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 #include "base/time.h" 57 #include "base/time.h"
58 #include "base/utf_offset_string_conversions.h" 58 #include "base/utf_offset_string_conversions.h"
59 #include "base/utf_string_conversions.h" 59 #include "base/utf_string_conversions.h"
60 #include "googleurl/src/gurl.h" 60 #include "googleurl/src/gurl.h"
61 #include "googleurl/src/url_canon.h" 61 #include "googleurl/src/url_canon.h"
62 #include "googleurl/src/url_canon_ip.h" 62 #include "googleurl/src/url_canon_ip.h"
63 #include "googleurl/src/url_parse.h" 63 #include "googleurl/src/url_parse.h"
64 #include "grit/net_resources.h" 64 #include "grit/net_resources.h"
65 #include "net/base/dns_util.h" 65 #include "net/base/dns_util.h"
66 #include "net/base/escape.h" 66 #include "net/base/escape.h"
67 #include "net/base/mime_util.h"
67 #include "net/base/net_module.h" 68 #include "net/base/net_module.h"
68 #if defined(OS_WIN) 69 #if defined(OS_WIN)
69 #include "net/base/winsock_init.h" 70 #include "net/base/winsock_init.h"
70 #endif 71 #endif
71 #include "unicode/datefmt.h" 72 #include "unicode/datefmt.h"
72 73
73 using base::Time; 74 using base::Time;
74 75
75 namespace net { 76 namespace net {
76 77
(...skipping 837 matching lines...) Expand 10 before | Expand all | Expand 10 after
914 } 915 }
915 916
916 char* do_strdup(const char* src) { 917 char* do_strdup(const char* src) {
917 #if defined(OS_WIN) 918 #if defined(OS_WIN)
918 return _strdup(src); 919 return _strdup(src);
919 #else 920 #else
920 return strdup(src); 921 return strdup(src);
921 #endif 922 #endif
922 } 923 }
923 924
925 #if defined(OS_WIN)
926 // Returns whether the specified extension is automatically integrated into the
927 // windows shell.
928 bool IsShellIntegratedExtension(const string16& extension) {
929 string16 extension_lower = StringToLowerASCII(extension);
930
931 static const wchar_t* const integrated_extensions[] = {
932 // See <http://msdn.microsoft.com/en-us/library/ms811694.aspx>.
933 L"local",
934 // Right-clicking on shortcuts can be magical.
935 L"lnk",
936 };
937
938 for (int i = 0; i < arraysize(integrated_extensions); ++i) {
939 if (extension_lower == integrated_extensions[i])
940 return true;
941 }
942
943 // See <http://www.juniper.net/security/auto/vulnerabilities/vuln2612.html>.
944 // That vulnerability report is not exactly on point, but files become magical
945 // if their end in a CLSID. Here we block extensions that look like CLSIDs.
946 if (!extension_lower.empty() && extension_lower[0] == L'{' &&
947 extension_lower[extension_lower.length() - 1] == L'}')
948 return true;
949
950 return false;
951 }
952
953 // Returns whether the specified file name is a reserved name on windows.
954 // This includes names like "com2.zip" (which correspond to devices) and
955 // desktop.ini and thumbs.db which have special meaning to the windows shell.
956 bool IsReservedName(const string16& filename) {
957 // This list is taken from the MSDN article "Naming a file"
958 // http://msdn2.microsoft.com/en-us/library/aa365247(VS.85).aspx
959 // I also added clock$ because GetSaveFileName seems to consider it as a
960 // reserved name too.
961 static const wchar_t* const known_devices[] = {
962 L"con", L"prn", L"aux", L"nul", L"com1", L"com2", L"com3", L"com4", L"com5",
963 L"com6", L"com7", L"com8", L"com9", L"lpt1", L"lpt2", L"lpt3", L"lpt4",
964 L"lpt5", L"lpt6", L"lpt7", L"lpt8", L"lpt9", L"clock$"
965 };
966 string16 filename_lower = StringToLowerASCII(filename);
967
968 for (int i = 0; i < arraysize(known_devices); ++i) {
969 // Exact match.
970 if (filename_lower == known_devices[i])
971 return true;
972 // Starts with "DEVICE.".
973 if (filename_lower.find(string16(known_devices[i]) + L".") == 0)
974 return true;
975 }
976
977 static const wchar_t* const magic_names[] = {
978 // These file names are used by the "Customize folder" feature of the shell.
979 L"desktop.ini",
980 L"thumbs.db",
981 };
982
983 for (int i = 0; i < arraysize(magic_names); ++i) {
984 if (filename_lower == magic_names[i])
985 return true;
986 }
987
988 return false;
989 }
990 #endif // OS_WIN
991
992 void GenerateSafeExtension(const std::string& mime_type, FilePath* file_name) {
993 // We're worried about two things here:
994 //
995 // 1) Usability. If the site fails to provide a file extension, we want to
996 // guess a reasonable file extension based on the content type.
997 //
998 // 2) Shell integration. Some file extensions automatically integrate with
999 // the shell. We block these extensions to prevent a malicious web site
1000 // from integrating with the user's shell.
1001
1002 // See if our file name already contains an extension.
1003 FilePath::StringType extension = file_name->Extension();
1004 if (!extension.empty())
1005 extension.erase(extension.begin()); // Erase preceding '.'.
1006
1007 #if defined(OS_WIN)
1008 static const FilePath::CharType default_extension[] =
1009 FILE_PATH_LITERAL("download");
1010
1011 // Rename shell-integrated extensions.
1012 // TODO(asanka): Consider stripping out the bad extension and replacing it
1013 // with the preferred extension for the MIME type if one is available.
1014 if (IsShellIntegratedExtension(extension))
1015 extension.assign(default_extension);
1016 #endif
1017
1018 if (extension.empty() && !mime_type.empty()) {
1019 // The GetPreferredExtensionForMimeType call will end up going to disk. Do
1020 // this on another thread to avoid slowing the IO thread.
1021 // http://crbug.com/61827
1022 // TODO(asanka): Remove this ScopedAllowIO once all callers have switched
1023 // over to IO safe threads.
1024 base::ThreadRestrictions::ScopedAllowIO allow_io;
1025 net::GetPreferredExtensionForMimeType(mime_type, &extension);
1026 }
1027
1028 *file_name = file_name->ReplaceExtension(extension);
1029 }
1030
924 } // namespace 1031 } // namespace
925 1032
926 const FormatUrlType kFormatUrlOmitNothing = 0; 1033 const FormatUrlType kFormatUrlOmitNothing = 0;
927 const FormatUrlType kFormatUrlOmitUsernamePassword = 1 << 0; 1034 const FormatUrlType kFormatUrlOmitUsernamePassword = 1 << 0;
928 const FormatUrlType kFormatUrlOmitHTTP = 1 << 1; 1035 const FormatUrlType kFormatUrlOmitHTTP = 1 << 1;
929 const FormatUrlType kFormatUrlOmitTrailingSlashOnBareHostname = 1 << 2; 1036 const FormatUrlType kFormatUrlOmitTrailingSlashOnBareHostname = 1 << 2;
930 const FormatUrlType kFormatUrlOmitAll = kFormatUrlOmitUsernamePassword | 1037 const FormatUrlType kFormatUrlOmitAll = kFormatUrlOmitUsernamePassword |
931 kFormatUrlOmitHTTP | kFormatUrlOmitTrailingSlashOnBareHostname; 1038 kFormatUrlOmitHTTP | kFormatUrlOmitTrailingSlashOnBareHostname;
932 1039
933 // TODO(viettrungluu): We don't want non-POD globals; change this. 1040 // TODO(viettrungluu): We don't want non-POD globals; change this.
(...skipping 27 matching lines...) Expand all
961 1068
962 #if defined(OS_POSIX) 1069 #if defined(OS_POSIX)
963 ReplaceSubstringsAfterOffset(&url_string, 0, 1070 ReplaceSubstringsAfterOffset(&url_string, 0,
964 FILE_PATH_LITERAL("\\"), FILE_PATH_LITERAL("%5C")); 1071 FILE_PATH_LITERAL("\\"), FILE_PATH_LITERAL("%5C"));
965 #endif 1072 #endif
966 1073
967 return GURL(url_string); 1074 return GURL(url_string);
968 } 1075 }
969 1076
970 std::string GetSpecificHeader(const std::string& headers, 1077 std::string GetSpecificHeader(const std::string& headers,
971 const std::string& name) { 1078 const std::string& name) {
972 // We want to grab the Value from the "Key: Value" pairs in the headers, 1079 // We want to grab the Value from the "Key: Value" pairs in the headers,
973 // which should look like this (no leading spaces, \n-separated) (we format 1080 // which should look like this (no leading spaces, \n-separated) (we format
974 // them this way in url_request_inet.cc): 1081 // them this way in url_request_inet.cc):
975 // HTTP/1.1 200 OK\n 1082 // HTTP/1.1 200 OK\n
976 // ETag: "6d0b8-947-24f35ec0"\n 1083 // ETag: "6d0b8-947-24f35ec0"\n
977 // Content-Length: 2375\n 1084 // Content-Length: 2375\n
978 // Content-Type: text/html; charset=UTF-8\n 1085 // Content-Type: text/html; charset=UTF-8\n
979 // Last-Modified: Sun, 03 Sep 2006 04:34:43 GMT\n 1086 // Last-Modified: Sun, 03 Sep 2006 04:34:43 GMT\n
980 if (headers.empty()) 1087 if (headers.empty())
981 return std::string(); 1088 return std::string();
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
1241 result.append(");</script>\n"); 1348 result.append(");</script>\n");
1242 1349
1243 return result; 1350 return result;
1244 } 1351 }
1245 1352
1246 string16 StripWWW(const string16& text) { 1353 string16 StripWWW(const string16& text) {
1247 const string16 www(ASCIIToUTF16("www.")); 1354 const string16 www(ASCIIToUTF16("www."));
1248 return StartsWith(text, www, true) ? text.substr(www.length()) : text; 1355 return StartsWith(text, www, true) ? text.substr(www.length()) : text;
1249 } 1356 }
1250 1357
1358 void GenerateSafeFileName(const std::string& mime_type, FilePath* file_path) {
1359 // Make sure we get the right file extension
1360 GenerateSafeExtension(mime_type, file_path);
1361
1362 #if defined(OS_WIN)
1363 // Prepend "_" to the file name if it's a reserved name
1364 FilePath::StringType leaf_name = file_path->BaseName().value();
1365 DCHECK(!leaf_name.empty());
1366 if (IsReservedName(leaf_name)) {
1367 leaf_name = FilePath::StringType(FILE_PATH_LITERAL("_")) + leaf_name;
1368 *file_path = file_path->DirName();
1369 if (file_path->value() == FilePath::kCurrentDirectory) {
1370 *file_path = FilePath(leaf_name);
1371 } else {
1372 *file_path = file_path->Append(leaf_name);
1373 }
1374 }
1375 #endif
1376 }
1377
1251 string16 GetSuggestedFilename(const GURL& url, 1378 string16 GetSuggestedFilename(const GURL& url,
1252 const std::string& content_disposition, 1379 const std::string& content_disposition,
1253 const std::string& referrer_charset, 1380 const std::string& referrer_charset,
1254 const std::string& suggested_name, 1381 const std::string& suggested_name,
1255 const string16& default_name) { 1382 const string16& default_name) {
1256 // TODO: this function to be updated to match the httpbis recommendations. 1383 // TODO: this function to be updated to match the httpbis recommendations.
1257 // Talk to abarth for the latest news. 1384 // Talk to abarth for the latest news.
1258 1385
1259 // We don't translate this fallback string, "download". If localization is 1386 // We don't translate this fallback string, "download". If localization is
1260 // needed, the caller should provide localized fallback default_name. 1387 // needed, the caller should provide localized fallback default_name.
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
1341 string16 path = UTF8ToUTF16(filename); 1468 string16 path = UTF8ToUTF16(filename);
1342 file_util::ReplaceIllegalCharactersInPath(&path, '-'); 1469 file_util::ReplaceIllegalCharactersInPath(&path, '-');
1343 return path; 1470 return path;
1344 #else 1471 #else
1345 std::string path = filename; 1472 std::string path = filename;
1346 file_util::ReplaceIllegalCharactersInPath(&path, '-'); 1473 file_util::ReplaceIllegalCharactersInPath(&path, '-');
1347 return UTF8ToUTF16(path); 1474 return UTF8ToUTF16(path);
1348 #endif 1475 #endif
1349 } 1476 }
1350 1477
1478 FilePath GenerateFileName(const GURL& url,
1479 const std::string& content_disposition,
1480 const std::string& referrer_charset,
1481 const std::string& suggested_name,
1482 const std::string& mime_type,
1483 const string16& default_file_name) {
1484 string16 new_name = GetSuggestedFilename(GURL(url),
1485 content_disposition,
1486 referrer_charset,
1487 suggested_name,
1488 default_file_name);
1489
1490 // TODO(evan): this code is totally wrong -- we should just generate
1491 // Unicode filenames and do all this encoding switching at the end.
1492 // However, I'm just shuffling wrong code around, at least not adding
1493 // to it.
1494 #if defined(OS_WIN)
1495 FilePath generated_name = FilePath(new_name);
1496 #else
1497 FilePath generated_name = FilePath(
1498 base::SysWideToNativeMB(UTF16ToWide(new_name)));
1499 #endif
1500
1501 DCHECK(!generated_name.empty());
1502
1503 GenerateSafeFileName(mime_type, &generated_name);
1504 return generated_name;
1505 }
1506
1351 bool IsPortAllowedByDefault(int port) { 1507 bool IsPortAllowedByDefault(int port) {
1352 int array_size = arraysize(kRestrictedPorts); 1508 int array_size = arraysize(kRestrictedPorts);
1353 for (int i = 0; i < array_size; i++) { 1509 for (int i = 0; i < array_size; i++) {
1354 if (kRestrictedPorts[i] == port) { 1510 if (kRestrictedPorts[i] == port) {
1355 return false; 1511 return false;
1356 } 1512 }
1357 } 1513 }
1358 return true; 1514 return true;
1359 } 1515 }
1360 1516
(...skipping 886 matching lines...) Expand 10 before | Expand all | Expand 10 after
2247 2403
2248 NetworkInterface::NetworkInterface(const std::string& name, 2404 NetworkInterface::NetworkInterface(const std::string& name,
2249 const IPAddressNumber& address) 2405 const IPAddressNumber& address)
2250 : name(name), address(address) { 2406 : name(name), address(address) {
2251 } 2407 }
2252 2408
2253 NetworkInterface::~NetworkInterface() { 2409 NetworkInterface::~NetworkInterface() {
2254 } 2410 }
2255 2411
2256 } // namespace net 2412 } // namespace net
OLDNEW
« no previous file with comments | « net/base/net_util.h ('k') | net/base/net_util_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698