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

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

Issue 7607013: Call GenerateSafeFilename() from GetSuggestedFilename(). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Comments 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
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 904 matching lines...) Expand 10 before | Expand all | Expand 10 after
915 } 915 }
916 916
917 char* do_strdup(const char* src) { 917 char* do_strdup(const char* src) {
918 #if defined(OS_WIN) 918 #if defined(OS_WIN)
919 return _strdup(src); 919 return _strdup(src);
920 #else 920 #else
921 return strdup(src); 921 return strdup(src);
922 #endif 922 #endif
923 } 923 }
924 924
925 void TrimGeneratedFileName(std::string& filename) {
926 if (!filename.empty()) {
927 // Remove "." from the beginning and end of the file name to avoid tricks
928 // with hidden files, "..", and "."
929 TrimString(filename, ".", &filename);
930 #if defined(OS_WIN)
931 // Handle CreateFile() stripping trailing dots and spaces on filenames
932 // http://support.microsoft.com/kb/115827
933 std::string::size_type pos = filename.find_last_not_of(" .");
934 if (pos == std::string::npos)
935 filename.resize(0);
936 else
937 filename.resize(++pos);
938 #endif
939 }
940 }
941
942 std::string GetFileNameFromURL(const GURL& url,
943 const std::string& referrer_charset) {
944 // about: and data: URLs don't have file names, but esp. data: URLs may
945 // contain parts that look like ones (i.e., contain a slash). Therefore we
946 // don't attempt to divine a file name out of them.
947 if (!url.is_valid() || url.SchemeIs("about") || url.SchemeIs("data"))
948 return std::string();
949
950 const std::string unescaped_url_filename = UnescapeURLComponent(
951 url.ExtractFileName(),
952 UnescapeRule::SPACES | UnescapeRule::URL_SPECIAL_CHARS);
953
954 // The URL's path should be escaped UTF-8, but may not be.
955 std::string decoded_filename = unescaped_url_filename;
956 if (!IsStringASCII(decoded_filename)) {
957 bool ignore;
958 // TODO(jshin): this is probably not robust enough. To be sure, we need
959 // encoding detection.
960 DecodeWord(unescaped_url_filename, referrer_charset, &ignore,
961 &decoded_filename);
962 }
963
964 return decoded_filename;
965 }
966
925 #if defined(OS_WIN) 967 #if defined(OS_WIN)
926 // Returns whether the specified extension is automatically integrated into the 968 // Returns whether the specified extension is automatically integrated into the
927 // windows shell. 969 // windows shell.
928 bool IsShellIntegratedExtension(const string16& extension) { 970 bool IsShellIntegratedExtension(const string16& extension) {
929 string16 extension_lower = StringToLowerASCII(extension); 971 string16 extension_lower = StringToLowerASCII(extension);
930 972
931 static const wchar_t* const integrated_extensions[] = { 973 static const wchar_t* const integrated_extensions[] = {
932 // See <http://msdn.microsoft.com/en-us/library/ms811694.aspx>. 974 // See <http://msdn.microsoft.com/en-us/library/ms811694.aspx>.
933 L"local", 975 L"local",
934 // Right-clicking on shortcuts can be magical. 976 // Right-clicking on shortcuts can be magical.
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after
1372 *file_path = file_path->Append(leaf_name); 1414 *file_path = file_path->Append(leaf_name);
1373 } 1415 }
1374 } 1416 }
1375 #endif 1417 #endif
1376 } 1418 }
1377 1419
1378 string16 GetSuggestedFilename(const GURL& url, 1420 string16 GetSuggestedFilename(const GURL& url,
1379 const std::string& content_disposition, 1421 const std::string& content_disposition,
1380 const std::string& referrer_charset, 1422 const std::string& referrer_charset,
1381 const std::string& suggested_name, 1423 const std::string& suggested_name,
1424 const std::string& mime_type,
1382 const string16& default_name) { 1425 const string16& default_name) {
1383 // TODO: this function to be updated to match the httpbis recommendations. 1426 // TODO: this function to be updated to match the httpbis recommendations.
1384 // Talk to abarth for the latest news. 1427 // Talk to abarth for the latest news.
1385 1428
1386 // We don't translate this fallback string, "download". If localization is 1429 // We don't translate this fallback string, "download". If localization is
1387 // needed, the caller should provide localized fallback default_name. 1430 // needed, the caller should provide localized fallback in |default_name|.
1388 static const char* kFinalFallbackName = "download"; 1431 static const char* kFinalFallbackName = "download";
1432 std::string filename; // In UTF-8
1389 1433
1390 std::string filename; 1434 // Try to extract a filename from content-disposition first.
1391
1392 // Try to extract from content-disposition first.
1393 if (!content_disposition.empty()) 1435 if (!content_disposition.empty())
1394 filename = GetFileNameFromCD(content_disposition, referrer_charset); 1436 filename = GetFileNameFromCD(content_disposition, referrer_charset);
1395 1437
1396 // Then try to use suggested name. 1438 // Then try to use the suggested name.
1397 if (filename.empty() && !suggested_name.empty()) 1439 if (filename.empty() && !suggested_name.empty())
1398 filename = suggested_name; 1440 filename = suggested_name;
1399 1441
1400 if (!filename.empty()) { 1442 // Now try extracting the filename from the URL. GetFileNameFromURL() only
1401 // Replace any path information the server may have sent, by changing 1443 // looks at the last component of the URL and doesn't return the hostname as a
1402 // path separators with underscores. 1444 // failover.
1403 ReplaceSubstringsAfterOffset(&filename, 0, "/", "_"); 1445 if (filename.empty())
1404 ReplaceSubstringsAfterOffset(&filename, 0, "\\", "_"); 1446 filename = GetFileNameFromURL(url, referrer_charset);
1405 1447
1406 // Next, remove "." from the beginning and end of the file name to avoid 1448 // Finally try the URL hostname, but only if there's no default specified in
1407 // tricks with hidden files, "..", and "." 1449 // |default_name|. Some schemes (e.g.: file:, about:, data:) do not have a
1408 TrimString(filename, ".", &filename); 1450 // host name.
1451 if (filename.empty() && default_name.empty() &&
1452 url.is_valid() && !url.host().empty()) {
1453 // TODO(jungshik) : Decode a 'punycoded' IDN hostname. (bug 1264451)
1454 filename = url.host();
1409 } 1455 }
1410 1456
1411 if (filename.empty()) { 1457 TrimGeneratedFileName(filename);
asanka 2011/08/15 18:16:34 As discussed in the previous CL, we are trimming t
1412 // about: and data: URLs don't have file names, but esp. data: URLs may 1458 if (filename.empty() && default_name.empty())
1413 // contain parts that look like ones (i.e., contain a slash). 1459 filename = kFinalFallbackName;
1414 // Therefore we don't attempt to divine a file name out of them.
1415 if (url.SchemeIs("about") || url.SchemeIs("data")) {
1416 return default_name.empty() ? ASCIIToUTF16(kFinalFallbackName)
1417 : default_name;
1418 }
1419 1460
1420 if (url.is_valid()) { 1461 // Replace any path information by changing path separators with
1421 const std::string unescaped_url_filename = UnescapeURLComponent( 1462 // underscores.
1422 url.ExtractFileName(), 1463 ReplaceSubstringsAfterOffset(&filename, 0, "/", "_");
rvargas (doing something else) 2011/08/16 22:20:00 nit: Maybe we should move this to TrimGeneratedFil
asanka 2011/08/17 16:22:00 Done.
1423 UnescapeRule::SPACES | UnescapeRule::URL_SPECIAL_CHARS); 1464 ReplaceSubstringsAfterOffset(&filename, 0, "\\", "_");
1424
1425 // The URL's path should be escaped UTF-8, but may not be.
1426 std::string decoded_filename = unescaped_url_filename;
1427 if (!IsStringASCII(decoded_filename)) {
1428 bool ignore;
1429 // TODO(jshin): this is probably not robust enough. To be sure, we
1430 // need encoding detection.
1431 DecodeWord(unescaped_url_filename, referrer_charset, &ignore,
1432 &decoded_filename);
1433 }
1434
1435 filename = decoded_filename;
1436 }
1437 }
1438 1465
1439 #if defined(OS_WIN) 1466 #if defined(OS_WIN)
1440 { // Handle CreateFile() stripping trailing dots and spaces on filenames 1467 string16 path = (filename.empty())? default_name : UTF8ToUTF16(filename);
1441 // http://support.microsoft.com/kb/115827
1442 std::string::size_type pos = filename.find_last_not_of(" .");
1443 if (pos == std::string::npos)
1444 filename.resize(0);
1445 else
1446 filename.resize(++pos);
1447 }
1448 #endif
1449 // Trim '.' once more.
1450 TrimString(filename, ".", &filename);
1451
1452 // If there's no filename or it gets trimed to be empty, use
1453 // the URL hostname or default_name
1454 if (filename.empty()) {
1455 if (!default_name.empty()) {
1456 return default_name;
1457 } else if (url.is_valid()) {
1458 // 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.
1460 // TODO(jungshik) : Decode a 'punycoded' IDN hostname. (bug 1264451)
1461 filename = url.host().empty() ? kFinalFallbackName : url.host();
1462 } else {
1463 NOTREACHED();
1464 }
1465 }
1466
1467 #if defined(OS_WIN)
1468 string16 path = UTF8ToUTF16(filename);
1469 file_util::ReplaceIllegalCharactersInPath(&path, '-'); 1468 file_util::ReplaceIllegalCharactersInPath(&path, '-');
1470 return path; 1469 FilePath result(path);
1470 GenerateSafeFileName(mime_type, &result);
1471 return result.value();
1471 #else 1472 #else
1472 std::string path = filename; 1473 std::string path = (filename.empty())? UTF16ToUTF8(default_name) : filename;
1473 file_util::ReplaceIllegalCharactersInPath(&path, '-'); 1474 file_util::ReplaceIllegalCharactersInPath(&path, '-');
1474 return UTF8ToUTF16(path); 1475 FilePath result(path);
1476 GenerateSafeFileName(mime_type, &result);
1477 return UTF8ToUTF16(result.value());
1475 #endif 1478 #endif
1476 } 1479 }
1477 1480
1478 FilePath GenerateFileName(const GURL& url, 1481 FilePath GenerateFileName(const GURL& url,
1479 const std::string& content_disposition, 1482 const std::string& content_disposition,
1480 const std::string& referrer_charset, 1483 const std::string& referrer_charset,
1481 const std::string& suggested_name, 1484 const std::string& suggested_name,
1482 const std::string& mime_type, 1485 const std::string& mime_type,
1483 const string16& default_file_name) { 1486 const string16& default_file_name) {
1484 string16 new_name = GetSuggestedFilename(GURL(url), 1487 string16 file_name = GetSuggestedFilename(GURL(url),
asanka 2011/08/15 18:16:34 This function now just calls GetSuggestedFilename(
rvargas (doing something else) 2011/08/16 22:20:00 nit: looks like we don't need GURL() anymore.
asanka 2011/08/17 16:22:00 Done.
1485 content_disposition, 1488 content_disposition,
1486 referrer_charset, 1489 referrer_charset,
1487 suggested_name, 1490 suggested_name,
1488 default_file_name); 1491 mime_type,
1492 default_file_name);
1489 1493
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) 1494 #if defined(OS_WIN)
1495 FilePath generated_name = FilePath(new_name); 1495 FilePath generated_name(file_name);
1496 #else 1496 #else
1497 FilePath generated_name = FilePath( 1497 FilePath generated_name(base::SysWideToNativeMB(UTF16ToWide(file_name)));
1498 base::SysWideToNativeMB(UTF16ToWide(new_name)));
1499 #endif 1498 #endif
1500
1501 DCHECK(!generated_name.empty()); 1499 DCHECK(!generated_name.empty());
1502 1500
1503 GenerateSafeFileName(mime_type, &generated_name);
1504 return generated_name; 1501 return generated_name;
1505 } 1502 }
1506 1503
1507 bool IsPortAllowedByDefault(int port) { 1504 bool IsPortAllowedByDefault(int port) {
1508 int array_size = arraysize(kRestrictedPorts); 1505 int array_size = arraysize(kRestrictedPorts);
1509 for (int i = 0; i < array_size; i++) { 1506 for (int i = 0; i < array_size; i++) {
1510 if (kRestrictedPorts[i] == port) { 1507 if (kRestrictedPorts[i] == port) {
1511 return false; 1508 return false;
1512 } 1509 }
1513 } 1510 }
(...skipping 889 matching lines...) Expand 10 before | Expand all | Expand 10 after
2403 2400
2404 NetworkInterface::NetworkInterface(const std::string& name, 2401 NetworkInterface::NetworkInterface(const std::string& name,
2405 const IPAddressNumber& address) 2402 const IPAddressNumber& address)
2406 : name(name), address(address) { 2403 : name(name), address(address) {
2407 } 2404 }
2408 2405
2409 NetworkInterface::~NetworkInterface() { 2406 NetworkInterface::~NetworkInterface() {
2410 } 2407 }
2411 2408
2412 } // namespace net 2409 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698