| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/http/http_content_disposition.h" | 5 #include "net/http/http_content_disposition.h" |
| 6 | 6 |
| 7 #include "base/base64.h" | 7 #include "base/base64.h" |
| 8 #include "base/i18n/icu_string_conversions.h" | 8 #include "base/i18n/icu_string_conversions.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
| 11 #include "base/strings/string_tokenizer.h" |
| 11 #include "base/sys_string_conversions.h" | 12 #include "base/sys_string_conversions.h" |
| 12 #include "base/utf_string_conversions.h" | 13 #include "base/utf_string_conversions.h" |
| 13 #include "net/base/net_util.h" | 14 #include "net/base/net_util.h" |
| 14 #include "net/http/http_util.h" | 15 #include "net/http/http_util.h" |
| 15 #include "third_party/icu/public/common/unicode/ucnv.h" | 16 #include "third_party/icu/public/common/unicode/ucnv.h" |
| 16 | 17 |
| 17 namespace { | 18 namespace { |
| 18 | 19 |
| 19 enum RFC2047EncodingType { | 20 enum RFC2047EncodingType { |
| 20 Q_ENCODING, | 21 Q_ENCODING, |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 124 | 125 |
| 125 // RFC 2047 : one of encoding methods supported by Firefox and relatively | 126 // RFC 2047 : one of encoding methods supported by Firefox and relatively |
| 126 // widely used by web servers. | 127 // widely used by web servers. |
| 127 // =?charset?<E>?<encoded string>?= where '<E>' is either 'B' or 'Q'. | 128 // =?charset?<E>?<encoded string>?= where '<E>' is either 'B' or 'Q'. |
| 128 // We don't care about the length restriction (72 bytes) because | 129 // We don't care about the length restriction (72 bytes) because |
| 129 // many web servers generate encoded words longer than the limit. | 130 // many web servers generate encoded words longer than the limit. |
| 130 std::string decoded_word; | 131 std::string decoded_word; |
| 131 *is_rfc2047 = true; | 132 *is_rfc2047 = true; |
| 132 int part_index = 0; | 133 int part_index = 0; |
| 133 std::string charset; | 134 std::string charset; |
| 134 StringTokenizer t(encoded_word, "?"); | 135 base::StringTokenizer t(encoded_word, "?"); |
| 135 RFC2047EncodingType enc_type = Q_ENCODING; | 136 RFC2047EncodingType enc_type = Q_ENCODING; |
| 136 while (*is_rfc2047 && t.GetNext()) { | 137 while (*is_rfc2047 && t.GetNext()) { |
| 137 std::string part = t.token(); | 138 std::string part = t.token(); |
| 138 switch (part_index) { | 139 switch (part_index) { |
| 139 case 0: | 140 case 0: |
| 140 if (part != "=") { | 141 if (part != "=") { |
| 141 *is_rfc2047 = false; | 142 *is_rfc2047 = false; |
| 142 break; | 143 break; |
| 143 } | 144 } |
| 144 ++part_index; | 145 ++part_index; |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 229 // strings. Non-ASCII strings are interpreted based on |referrer_charset|. | 230 // strings. Non-ASCII strings are interpreted based on |referrer_charset|. |
| 230 bool DecodeFilenameValue(const std::string& input, | 231 bool DecodeFilenameValue(const std::string& input, |
| 231 const std::string& referrer_charset, | 232 const std::string& referrer_charset, |
| 232 std::string* output, | 233 std::string* output, |
| 233 int* parse_result_flags) { | 234 int* parse_result_flags) { |
| 234 int current_parse_result_flags = 0; | 235 int current_parse_result_flags = 0; |
| 235 std::string decoded_value; | 236 std::string decoded_value; |
| 236 bool is_previous_token_rfc2047 = true; | 237 bool is_previous_token_rfc2047 = true; |
| 237 | 238 |
| 238 // Tokenize with whitespace characters. | 239 // Tokenize with whitespace characters. |
| 239 StringTokenizer t(input, " \t\n\r"); | 240 base::StringTokenizer t(input, " \t\n\r"); |
| 240 t.set_options(StringTokenizer::RETURN_DELIMS); | 241 t.set_options(base::StringTokenizer::RETURN_DELIMS); |
| 241 while (t.GetNext()) { | 242 while (t.GetNext()) { |
| 242 if (t.token_is_delim()) { | 243 if (t.token_is_delim()) { |
| 243 // If the previous non-delimeter token is not RFC2047-encoded, | 244 // If the previous non-delimeter token is not RFC2047-encoded, |
| 244 // put in a space in its place. Otheriwse, skip over it. | 245 // put in a space in its place. Otheriwse, skip over it. |
| 245 if (!is_previous_token_rfc2047) | 246 if (!is_previous_token_rfc2047) |
| 246 decoded_value.push_back(' '); | 247 decoded_value.push_back(' '); |
| 247 continue; | 248 continue; |
| 248 } | 249 } |
| 249 // We don't support a single multibyte character split into | 250 // We don't support a single multibyte character split into |
| 250 // adjacent encoded words. Some broken mail clients emit headers | 251 // adjacent encoded words. Some broken mail clients emit headers |
| (...skipping 11 matching lines...) Expand all Loading... |
| 262 *parse_result_flags |= current_parse_result_flags; | 263 *parse_result_flags |= current_parse_result_flags; |
| 263 return true; | 264 return true; |
| 264 } | 265 } |
| 265 | 266 |
| 266 // Parses the charset and value-chars out of an ext-value string. | 267 // Parses the charset and value-chars out of an ext-value string. |
| 267 // | 268 // |
| 268 // ext-value = charset "'" [ language ] "'" value-chars | 269 // ext-value = charset "'" [ language ] "'" value-chars |
| 269 bool ParseExtValueComponents(const std::string& input, | 270 bool ParseExtValueComponents(const std::string& input, |
| 270 std::string* charset, | 271 std::string* charset, |
| 271 std::string* value_chars) { | 272 std::string* value_chars) { |
| 272 StringTokenizer t(input, "'"); | 273 base::StringTokenizer t(input, "'"); |
| 273 t.set_options(StringTokenizer::RETURN_DELIMS); | 274 t.set_options(base::StringTokenizer::RETURN_DELIMS); |
| 274 std::string temp_charset; | 275 std::string temp_charset; |
| 275 std::string temp_value; | 276 std::string temp_value; |
| 276 int numDelimsSeen = 0; | 277 int numDelimsSeen = 0; |
| 277 while (t.GetNext()) { | 278 while (t.GetNext()) { |
| 278 if (t.token_is_delim()) { | 279 if (t.token_is_delim()) { |
| 279 ++numDelimsSeen; | 280 ++numDelimsSeen; |
| 280 continue; | 281 continue; |
| 281 } else { | 282 } else { |
| 282 switch (numDelimsSeen) { | 283 switch (numDelimsSeen) { |
| 283 case 0: | 284 case 0: |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 446 | 447 |
| 447 if (!ext_filename.empty()) | 448 if (!ext_filename.empty()) |
| 448 filename_ = ext_filename; | 449 filename_ = ext_filename; |
| 449 else if (!filename.empty()) | 450 else if (!filename.empty()) |
| 450 filename_ = filename; | 451 filename_ = filename; |
| 451 else | 452 else |
| 452 filename_ = name; | 453 filename_ = name; |
| 453 } | 454 } |
| 454 | 455 |
| 455 } // namespace net | 456 } // namespace net |
| OLD | NEW |