| Index: net/base/net_util.cc
|
| ===================================================================
|
| --- net/base/net_util.cc (revision 97172)
|
| +++ net/base/net_util.cc (working copy)
|
| @@ -158,6 +158,20 @@
|
| 22, // ssh
|
| };
|
|
|
| +template<typename STR>
|
| +typename STR::size_type CountTrailingChars(
|
| + const STR& input,
|
| + const typename STR::value_type
|
| + trailing_chars[]) {
|
| + const typename STR::size_type last_good_char =
|
| + input.find_last_not_of(trailing_chars);
|
| +
|
| + if (last_good_char == std::string::npos)
|
| + return input.length();
|
| + else
|
| + return input.length() - last_good_char - 1;
|
| +}
|
| +
|
| // Similar to Base64Decode. Decodes a Q-encoded string to a sequence
|
| // of bytes. If input is invalid, return false.
|
| bool QPDecode(const std::string& input, std::string* output) {
|
| @@ -1388,6 +1402,7 @@
|
| static const char* kFinalFallbackName = "download";
|
|
|
| std::string filename;
|
| + std::string::size_type trimmed_trailing_character_count = 0;
|
|
|
| // Try to extract from content-disposition first.
|
| if (!content_disposition.empty())
|
| @@ -1405,10 +1420,12 @@
|
|
|
| // Next, remove "." from the beginning and end of the file name to avoid
|
| // tricks with hidden files, "..", and "."
|
| + trimmed_trailing_character_count += CountTrailingChars(filename, ".");
|
| TrimString(filename, ".", &filename);
|
| }
|
|
|
| if (filename.empty()) {
|
| + trimmed_trailing_character_count = 0;
|
| // about: and data: URLs don't have file names, but esp. data: URLs may
|
| // contain parts that look like ones (i.e., contain a slash).
|
| // Therefore we don't attempt to divine a file name out of them.
|
| @@ -1439,11 +1456,8 @@
|
| #if defined(OS_WIN)
|
| { // Handle CreateFile() stripping trailing dots and spaces on filenames
|
| // http://support.microsoft.com/kb/115827
|
| - std::string::size_type pos = filename.find_last_not_of(" .");
|
| - if (pos == std::string::npos)
|
| - filename.resize(0);
|
| - else
|
| - filename.resize(++pos);
|
| + trimmed_trailing_character_count += CountTrailingChars(filename, " .");
|
| + filename.resize(filename.length() - trimmed_trailing_character_count);
|
| }
|
| #endif
|
| // Trim '.' once more.
|
| @@ -1452,6 +1466,7 @@
|
| // If there's no filename or it gets trimed to be empty, use
|
| // the URL hostname or default_name
|
| if (filename.empty()) {
|
| + trimmed_trailing_character_count = 0;
|
| if (!default_name.empty()) {
|
| return default_name;
|
| } else if (url.is_valid()) {
|
| @@ -1466,7 +1481,15 @@
|
|
|
| #if defined(OS_WIN)
|
| string16 path = UTF8ToUTF16(filename);
|
| + // On Windows we want to preserve or replace all characters including
|
| + // whitespace to prevent file extension obfuscation on trusted websites
|
| + // e.g. Gmail might think evil.exe. is safe, so we don't want it to become
|
| + // evil.exe when we download it
|
| + trimmed_trailing_character_count += path.length();
|
| + TrimWhitespace(path, TRIM_TRAILING, &path);
|
| + trimmed_trailing_character_count -= path.length();
|
| file_util::ReplaceIllegalCharactersInPath(&path, '-');
|
| + path.append(trimmed_trailing_character_count, '-');
|
| return path;
|
| #else
|
| std::string path = filename;
|
|
|