OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |