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 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
151 0xFFFF, // Used to block all invalid port numbers (see | 151 0xFFFF, // Used to block all invalid port numbers (see |
152 // third_party/WebKit/Source/WebCore/platform/KURLGoogle.cpp, port()) | 152 // third_party/WebKit/Source/WebCore/platform/KURLGoogle.cpp, port()) |
153 }; | 153 }; |
154 | 154 |
155 // FTP overrides the following restricted ports. | 155 // FTP overrides the following restricted ports. |
156 static const int kAllowedFtpPorts[] = { | 156 static const int kAllowedFtpPorts[] = { |
157 21, // ftp data | 157 21, // ftp data |
158 22, // ssh | 158 22, // ssh |
159 }; | 159 }; |
160 | 160 |
| 161 template<typename STR> |
| 162 typename STR::size_type CountTrailingChars( |
| 163 const STR& input, |
| 164 const typename STR::value_type |
| 165 trailing_chars[]) { |
| 166 const typename STR::size_type last_good_char = |
| 167 input.find_last_not_of(trailing_chars); |
| 168 |
| 169 if (last_good_char == std::string::npos) |
| 170 return input.length(); |
| 171 else |
| 172 return input.length() - last_good_char - 1; |
| 173 } |
| 174 |
161 // Similar to Base64Decode. Decodes a Q-encoded string to a sequence | 175 // Similar to Base64Decode. Decodes a Q-encoded string to a sequence |
162 // of bytes. If input is invalid, return false. | 176 // of bytes. If input is invalid, return false. |
163 bool QPDecode(const std::string& input, std::string* output) { | 177 bool QPDecode(const std::string& input, std::string* output) { |
164 std::string temp; | 178 std::string temp; |
165 temp.reserve(input.size()); | 179 temp.reserve(input.size()); |
166 std::string::const_iterator it = input.begin(); | 180 std::string::const_iterator it = input.begin(); |
167 while (it != input.end()) { | 181 while (it != input.end()) { |
168 if (*it == '_') { | 182 if (*it == '_') { |
169 temp.push_back(' '); | 183 temp.push_back(' '); |
170 } else if (*it == '=') { | 184 } else if (*it == '=') { |
(...skipping 1210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1381 const std::string& suggested_name, | 1395 const std::string& suggested_name, |
1382 const string16& default_name) { | 1396 const string16& default_name) { |
1383 // TODO: this function to be updated to match the httpbis recommendations. | 1397 // TODO: this function to be updated to match the httpbis recommendations. |
1384 // Talk to abarth for the latest news. | 1398 // Talk to abarth for the latest news. |
1385 | 1399 |
1386 // We don't translate this fallback string, "download". If localization is | 1400 // We don't translate this fallback string, "download". If localization is |
1387 // needed, the caller should provide localized fallback default_name. | 1401 // needed, the caller should provide localized fallback default_name. |
1388 static const char* kFinalFallbackName = "download"; | 1402 static const char* kFinalFallbackName = "download"; |
1389 | 1403 |
1390 std::string filename; | 1404 std::string filename; |
| 1405 std::string::size_type trimmed_trailing_character_count = 0; |
1391 | 1406 |
1392 // Try to extract from content-disposition first. | 1407 // Try to extract from content-disposition first. |
1393 if (!content_disposition.empty()) | 1408 if (!content_disposition.empty()) |
1394 filename = GetFileNameFromCD(content_disposition, referrer_charset); | 1409 filename = GetFileNameFromCD(content_disposition, referrer_charset); |
1395 | 1410 |
1396 // Then try to use suggested name. | 1411 // Then try to use suggested name. |
1397 if (filename.empty() && !suggested_name.empty()) | 1412 if (filename.empty() && !suggested_name.empty()) |
1398 filename = suggested_name; | 1413 filename = suggested_name; |
1399 | 1414 |
1400 if (!filename.empty()) { | 1415 if (!filename.empty()) { |
1401 // Replace any path information the server may have sent, by changing | 1416 // Replace any path information the server may have sent, by changing |
1402 // path separators with underscores. | 1417 // path separators with underscores. |
1403 ReplaceSubstringsAfterOffset(&filename, 0, "/", "_"); | 1418 ReplaceSubstringsAfterOffset(&filename, 0, "/", "_"); |
1404 ReplaceSubstringsAfterOffset(&filename, 0, "\\", "_"); | 1419 ReplaceSubstringsAfterOffset(&filename, 0, "\\", "_"); |
1405 | 1420 |
1406 // Next, remove "." from the beginning and end of the file name to avoid | 1421 // Next, remove "." from the beginning and end of the file name to avoid |
1407 // tricks with hidden files, "..", and "." | 1422 // tricks with hidden files, "..", and "." |
| 1423 trimmed_trailing_character_count += CountTrailingChars(filename, "."); |
1408 TrimString(filename, ".", &filename); | 1424 TrimString(filename, ".", &filename); |
1409 } | 1425 } |
1410 | 1426 |
1411 if (filename.empty()) { | 1427 if (filename.empty()) { |
| 1428 trimmed_trailing_character_count = 0; |
1412 // about: and data: URLs don't have file names, but esp. data: URLs may | 1429 // about: and data: URLs don't have file names, but esp. data: URLs may |
1413 // contain parts that look like ones (i.e., contain a slash). | 1430 // contain parts that look like ones (i.e., contain a slash). |
1414 // Therefore we don't attempt to divine a file name out of them. | 1431 // Therefore we don't attempt to divine a file name out of them. |
1415 if (url.SchemeIs("about") || url.SchemeIs("data")) { | 1432 if (url.SchemeIs("about") || url.SchemeIs("data")) { |
1416 return default_name.empty() ? ASCIIToUTF16(kFinalFallbackName) | 1433 return default_name.empty() ? ASCIIToUTF16(kFinalFallbackName) |
1417 : default_name; | 1434 : default_name; |
1418 } | 1435 } |
1419 | 1436 |
1420 if (url.is_valid()) { | 1437 if (url.is_valid()) { |
1421 const std::string unescaped_url_filename = UnescapeURLComponent( | 1438 const std::string unescaped_url_filename = UnescapeURLComponent( |
(...skipping 10 matching lines...) Expand all Loading... |
1432 &decoded_filename); | 1449 &decoded_filename); |
1433 } | 1450 } |
1434 | 1451 |
1435 filename = decoded_filename; | 1452 filename = decoded_filename; |
1436 } | 1453 } |
1437 } | 1454 } |
1438 | 1455 |
1439 #if defined(OS_WIN) | 1456 #if defined(OS_WIN) |
1440 { // Handle CreateFile() stripping trailing dots and spaces on filenames | 1457 { // Handle CreateFile() stripping trailing dots and spaces on filenames |
1441 // http://support.microsoft.com/kb/115827 | 1458 // http://support.microsoft.com/kb/115827 |
1442 std::string::size_type pos = filename.find_last_not_of(" ."); | 1459 trimmed_trailing_character_count += CountTrailingChars(filename, " ."); |
1443 if (pos == std::string::npos) | 1460 filename.resize(filename.length() - trimmed_trailing_character_count); |
1444 filename.resize(0); | |
1445 else | |
1446 filename.resize(++pos); | |
1447 } | 1461 } |
1448 #endif | 1462 #endif |
1449 // Trim '.' once more. | 1463 // Trim '.' once more. |
1450 TrimString(filename, ".", &filename); | 1464 TrimString(filename, ".", &filename); |
1451 | 1465 |
1452 // If there's no filename or it gets trimed to be empty, use | 1466 // If there's no filename or it gets trimed to be empty, use |
1453 // the URL hostname or default_name | 1467 // the URL hostname or default_name |
1454 if (filename.empty()) { | 1468 if (filename.empty()) { |
| 1469 trimmed_trailing_character_count = 0; |
1455 if (!default_name.empty()) { | 1470 if (!default_name.empty()) { |
1456 return default_name; | 1471 return default_name; |
1457 } else if (url.is_valid()) { | 1472 } else if (url.is_valid()) { |
1458 // Some schemes (e.g. file) do not have a hostname. Even though it's | 1473 // Some schemes (e.g. file) do not have a hostname. Even though it's |
1459 // not likely to reach here, let's hardcode the last fallback name. | 1474 // not likely to reach here, let's hardcode the last fallback name. |
1460 // TODO(jungshik) : Decode a 'punycoded' IDN hostname. (bug 1264451) | 1475 // TODO(jungshik) : Decode a 'punycoded' IDN hostname. (bug 1264451) |
1461 filename = url.host().empty() ? kFinalFallbackName : url.host(); | 1476 filename = url.host().empty() ? kFinalFallbackName : url.host(); |
1462 } else { | 1477 } else { |
1463 NOTREACHED(); | 1478 NOTREACHED(); |
1464 } | 1479 } |
1465 } | 1480 } |
1466 | 1481 |
1467 #if defined(OS_WIN) | 1482 #if defined(OS_WIN) |
1468 string16 path = UTF8ToUTF16(filename); | 1483 string16 path = UTF8ToUTF16(filename); |
| 1484 // On Windows we want to preserve or replace all characters including |
| 1485 // whitespace to prevent file extension obfuscation on trusted websites |
| 1486 // e.g. Gmail might think evil.exe. is safe, so we don't want it to become |
| 1487 // evil.exe when we download it |
| 1488 trimmed_trailing_character_count += path.length(); |
| 1489 TrimWhitespace(path, TRIM_TRAILING, &path); |
| 1490 trimmed_trailing_character_count -= path.length(); |
1469 file_util::ReplaceIllegalCharactersInPath(&path, '-'); | 1491 file_util::ReplaceIllegalCharactersInPath(&path, '-'); |
| 1492 path.append(trimmed_trailing_character_count, '-'); |
1470 return path; | 1493 return path; |
1471 #else | 1494 #else |
1472 std::string path = filename; | 1495 std::string path = filename; |
1473 file_util::ReplaceIllegalCharactersInPath(&path, '-'); | 1496 file_util::ReplaceIllegalCharactersInPath(&path, '-'); |
1474 return UTF8ToUTF16(path); | 1497 return UTF8ToUTF16(path); |
1475 #endif | 1498 #endif |
1476 } | 1499 } |
1477 | 1500 |
1478 FilePath GenerateFileName(const GURL& url, | 1501 FilePath GenerateFileName(const GURL& url, |
1479 const std::string& content_disposition, | 1502 const std::string& content_disposition, |
(...skipping 923 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2403 | 2426 |
2404 NetworkInterface::NetworkInterface(const std::string& name, | 2427 NetworkInterface::NetworkInterface(const std::string& name, |
2405 const IPAddressNumber& address) | 2428 const IPAddressNumber& address) |
2406 : name(name), address(address) { | 2429 : name(name), address(address) { |
2407 } | 2430 } |
2408 | 2431 |
2409 NetworkInterface::~NetworkInterface() { | 2432 NetworkInterface::~NetworkInterface() { |
2410 } | 2433 } |
2411 | 2434 |
2412 } // namespace net | 2435 } // namespace net |
OLD | NEW |