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

Unified Diff: net/base/net_util.cc

Issue 7647014: Replace whitespace at beginning and end of file with hyphens, rather than silently discarding. (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Changed filename char replacement to percent encoding. 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/base/net_util.cc
diff --git a/net/base/net_util.cc b/net/base/net_util.cc
index ef8eb534d12792c4ae76978f1425470acce9cd00..5918b5db55f23807e241705e133fe4f6e60c7b37 100644
--- a/net/base/net_util.cc
+++ b/net/base/net_util.cc
@@ -158,6 +158,103 @@ static const int kAllowedFtpPorts[] = {
22, // ssh
};
+// This list should generally match the one in string_util.cc
+const char16 kWhitespaceUTF16[] = {
jschuh 2011/08/17 14:38:46 Seems like we should add missed whitespace charact
+ 0x0009, /* <control-0009> to <control-000D> */ \
+ 0x000A, \
+ 0x000B, \
+ 0x000C, \
+ 0x000D, \
+ 0x0020, /* Space */ \
+ 0x0085, /* <control-0085> */ \
+ 0x00A0, /* No-Break Space */ \
+ 0x1680, /* Ogham Space Mark */ \
+ 0x180E, /* Mongolian Vowel Separator */ \
+ 0x2000, /* En Quad to Hair Space */ \
+ 0x2001, \
+ 0x2002, \
+ 0x2003, \
+ 0x2004, \
+ 0x2005, \
+ 0x2006, \
+ 0x2007, \
+ 0x2008, \
+ 0x2009, \
+ 0x200A, \
+ 0x200C, /* Zero Width Non-Joiner */ \
+ 0x2028, /* Line Separator */ \
+ 0x2029, /* Paragraph Separator */ \
+ 0x202F, /* Narrow No-Break Space */ \
+ 0x205F, /* Medium Mathematical Space */ \
+ 0x3000, /* Ideographic Space */ \
+ 0
+};
+
+static const char* const kHexString = "0123456789ABCDEF";
+inline char IntToHex(int i) {
+ return kHexString[i & 0xf];
+}
+
+std::string EscapeCharsInString(const std::string& input) {
+ std::string escaped_string;
+
+ escaped_string.reserve(input.length() * 3);
+ for (unsigned int i = 0; i < input.length(); i++) {
+ unsigned char c = static_cast<unsigned char>(input[i]);
+ escaped_string.push_back('%');
+ escaped_string.push_back(IntToHex(c >> 4));
+ escaped_string.push_back(IntToHex(c & 0xf));
+ }
+ return escaped_string;
+}
+
+string16 EscapeCharsInString(const string16& input) {
+ string16 escaped_string;
+
+ escaped_string.reserve(input.length() * 6);
+ for (unsigned int i = 0; i < input.length(); i++) {
+ char16 c = static_cast<char16>(input[i]);
+ escaped_string.push_back('%');
+ escaped_string.push_back('u');
+ escaped_string.push_back(IntToHex(c >> 12));
+ escaped_string.push_back(IntToHex((c >> 8) & 0xf));
+ escaped_string.push_back(IntToHex((c >> 4) & 0xf));
+ escaped_string.push_back(IntToHex(c & 0xf));
+ }
+ return escaped_string;
+}
+
+template<typename STR>
+void EscapeTrimChars(const STR& input,
+ const typename STR::value_type escape_chars[],
+ TrimPositions positions,
+ STR* output) {
+ // Find the edges of leading/trailing whitespace as desired.
+ const typename STR::size_type last_char = input.length() - 1;
+ const typename STR::size_type first_good_char = (positions & TRIM_LEADING) ?
+ input.find_first_not_of(escape_chars) : 0;
+ const typename STR::size_type last_good_char = (positions & TRIM_TRAILING) ?
+ input.find_last_not_of(escape_chars) : last_char;
+ STR temp_string;
+
+ if (input.empty())
+ return;
+
+ if ((first_good_char == STR::npos) || (last_good_char == STR::npos)) {
+ // Escapery magic on whole string
+ return;
+ }
+
+ temp_string = EscapeCharsInString(input.substr(0,first_good_char));
+ temp_string += input.substr(first_good_char, last_good_char -
+ first_good_char + 1);
+ if (last_good_char < last_char)
+ temp_string += EscapeCharsInString(input.substr(last_good_char+1));
+ *output = temp_string;
+
+ return;
+}
+
// 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) {
@@ -1405,7 +1502,11 @@ string16 GetSuggestedFilename(const GURL& url,
// Next, remove "." from the beginning and end of the file name to avoid
// tricks with hidden files, "..", and "."
+#if defined(OS_WIN)
+ EscapeTrimChars(filename, ".", TRIM_ALL, &filename);
+#else
TrimString(filename, ".", &filename);
+#endif
}
if (filename.empty()) {
@@ -1439,11 +1540,7 @@ string16 GetSuggestedFilename(const GURL& url,
#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);
+ EscapeTrimChars(filename, " .", TRIM_TRAILING, &filename);
}
#endif
// Trim '.' once more.
@@ -1466,6 +1563,11 @@ string16 GetSuggestedFilename(const GURL& url,
#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
+ EscapeTrimChars(path, kWhitespaceUTF16, TRIM_ALL, &path);
file_util::ReplaceIllegalCharactersInPath(&path, '-');
return path;
#else
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698