diff options
Diffstat (limited to 'net/base/net_util.cc')
| -rw-r--r-- | net/base/net_util.cc | 91 |
1 files changed, 74 insertions, 17 deletions
diff --git a/net/base/net_util.cc b/net/base/net_util.cc index c1f769e..5afba6f 100644 --- a/net/base/net_util.cc +++ b/net/base/net_util.cc @@ -181,7 +181,7 @@ STR GetSpecificHeaderT(const STR& headers, const STR& name) { typename STR::const_iterator begin = search(headers.begin(), headers.end(), match.begin(), match.end(), - CaseInsensitiveCompareASCII<typename STR::value_type>()); + base::CaseInsensitiveCompareASCII<typename STR::value_type>()); if (begin == headers.end()) return STR(); @@ -374,9 +374,7 @@ bool DecodeWord(const std::string& encoded_word, // it should be Ok because we're not an email client but a // web browser. - // What IE6/7 does: %-escaped UTF-8. We could extend this to - // support a rudimentary form of RFC 2231 with charset label, but - // it'd gain us little in terms of compatibility. + // What IE6/7 does: %-escaped UTF-8. tmp = UnescapeURLComponent(encoded_word, UnescapeRule::SPACES); if (IsStringUTF8(tmp)) { output->swap(tmp); @@ -425,11 +423,12 @@ bool DecodeParamValue(const std::string& input, // TODO(mpcomplete): This is a quick and dirty implementation for now. I'm // sure this doesn't properly handle all (most?) cases. template<typename STR> -STR GetHeaderParamValueT(const STR& header, const STR& param_name) { +STR GetHeaderParamValueT(const STR& header, const STR& param_name, + QuoteRule::Type quote_rule) { // This assumes args are formatted exactly like "bla; arg1=value; arg2=value". typename STR::const_iterator param_begin = search(header.begin(), header.end(), param_name.begin(), param_name.end(), - CaseInsensitiveCompareASCII<typename STR::value_type>()); + base::CaseInsensitiveCompareASCII<typename STR::value_type>()); if (param_begin == header.end()) return STR(); @@ -448,7 +447,7 @@ STR GetHeaderParamValueT(const STR& header, const STR& param_name) { return STR(); typename STR::const_iterator param_end; - if (*param_begin == '"') { + if (*param_begin == '"' && quote_rule == QuoteRule::REMOVE_OUTER_QUOTES) { param_end = find(param_begin+1, header.end(), '"'); if (param_end == header.end()) return STR(); // poorly formatted param? @@ -1096,29 +1095,86 @@ std::string GetSpecificHeader(const std::string& headers, return GetSpecificHeaderT(headers, name); } +bool DecodeCharset(const std::string& input, + std::string* decoded_charset, + std::string* value) { + StringTokenizer t(input, "'"); + t.set_options(StringTokenizer::RETURN_DELIMS); + std::string temp_charset; + std::string temp_value; + int numDelimsSeen = 0; + while (t.GetNext()) { + if (t.token_is_delim()) { + ++numDelimsSeen; + continue; + } else { + switch (numDelimsSeen) { + case 0: + temp_charset = t.token(); + break; + case 1: + // Language is ignored. + break; + case 2: + temp_value = t.token(); + break; + default: + return false; + } + } + } + if (numDelimsSeen != 2) + return false; + if (temp_charset.empty() || temp_value.empty()) + return false; + decoded_charset->swap(temp_charset); + value->swap(temp_value); + return true; +} + std::string GetFileNameFromCD(const std::string& header, const std::string& referrer_charset) { - std::string param_value = GetHeaderParamValue(header, "filename"); + std::string decoded; + std::string param_value = GetHeaderParamValue(header, "filename*", + QuoteRule::KEEP_OUTER_QUOTES); + if (!param_value.empty()) { + if (param_value.find('"') == std::string::npos) { + std::string charset; + std::string value; + if (DecodeCharset(param_value, &charset, &value)) { + // RFC 5987 value should be ASCII-only. + if (!IsStringASCII(value)) + return std::string(); + std::string tmp = UnescapeURLComponent(value, UnescapeRule::SPACES); + if (base::ConvertToUtf8AndNormalize(tmp, charset, &decoded)) + return decoded; + } + } + } + param_value = GetHeaderParamValue(header, "filename", + QuoteRule::REMOVE_OUTER_QUOTES); if (param_value.empty()) { // Some servers use 'name' parameter. - param_value = GetHeaderParamValue(header, "name"); + param_value = GetHeaderParamValue(header, "name", + QuoteRule::REMOVE_OUTER_QUOTES); } if (param_value.empty()) return std::string(); - std::string decoded; if (DecodeParamValue(param_value, referrer_charset, &decoded)) return decoded; return std::string(); } std::wstring GetHeaderParamValue(const std::wstring& field, - const std::wstring& param_name) { - return GetHeaderParamValueT(field, param_name); + const std::wstring& param_name, + QuoteRule::Type quote_rule) { + return GetHeaderParamValueT(field, param_name, quote_rule); } std::string GetHeaderParamValue(const std::string& field, - const std::string& param_name) { - return GetHeaderParamValueT(field, param_name); + const std::string& param_name, + QuoteRule::Type quote_rule) { + return GetHeaderParamValueT(field, param_name, quote_rule); } // TODO(brettw) bug 734373: check the scripts for each host component and @@ -1681,10 +1737,11 @@ void SetExplicitlyAllowedPorts(const std::string& allowed_ports) { (allowed_ports[i] != kComma)) return; if (i == size || allowed_ports[i] == kComma) { - size_t length = i - last; - if (length > 0) { + if (i > last) { int port; - base::StringToInt(allowed_ports.substr(last, length), &port); + base::StringToInt(allowed_ports.begin() + last, + allowed_ports.begin() + i, + &port); ports.insert(port); } last = i + 1; |
