| Index: net/base/escape.cc
|
| ===================================================================
|
| --- net/base/escape.cc (revision 36299)
|
| +++ net/base/escape.cc (working copy)
|
| @@ -108,9 +108,10 @@
|
| 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0
|
| };
|
|
|
| -std::string UnescapeURLImpl(const std::string& escaped_text,
|
| - UnescapeRule::Type rules,
|
| - size_t* offset_for_adjustment) {
|
| +template<typename STR>
|
| +STR UnescapeURLImpl(const STR& escaped_text,
|
| + UnescapeRule::Type rules,
|
| + size_t* offset_for_adjustment) {
|
| size_t offset_temp = string16::npos;
|
| if (!offset_for_adjustment)
|
| offset_for_adjustment = &offset_temp;
|
| @@ -124,13 +125,22 @@
|
| // The output of the unescaping is always smaller than the input, so we can
|
| // reserve the input size to make sure we have enough buffer and don't have
|
| // to allocate in the loop below.
|
| - std::string result;
|
| + STR result;
|
| result.reserve(escaped_text.length());
|
|
|
| for (size_t i = 0, max = escaped_text.size(); i < max; ++i) {
|
| - if (escaped_text[i] == '%' && i + 2 < max) {
|
| - const std::string::value_type most_sig_digit(escaped_text[i + 1]);
|
| - const std::string::value_type least_sig_digit(escaped_text[i + 2]);
|
| + if (static_cast<unsigned char>(escaped_text[i]) >= 128) {
|
| + // Non ASCII character, append as is.
|
| + result.push_back(escaped_text[i]);
|
| + continue;
|
| + }
|
| +
|
| + char current_char = static_cast<char>(escaped_text[i]);
|
| + if (current_char == '%' && i + 2 < max) {
|
| + const typename STR::value_type most_sig_digit(
|
| + static_cast<typename STR::value_type>(escaped_text[i + 1]));
|
| + const typename STR::value_type least_sig_digit(
|
| + static_cast<typename STR::value_type>(escaped_text[i + 2]));
|
| if (IsHex(most_sig_digit) && IsHex(least_sig_digit)) {
|
| unsigned char value = HexToInt(most_sig_digit) * 16 +
|
| HexToInt(least_sig_digit);
|
| @@ -275,11 +285,17 @@
|
| return UnescapeURLImpl(escaped_text, rules, NULL);
|
| }
|
|
|
| +string16 UnescapeURLComponent(const string16& escaped_text,
|
| + UnescapeRule::Type rules) {
|
| + return UnescapeURLImpl(escaped_text, rules, NULL);
|
| +}
|
| +
|
| +
|
| template <class str>
|
| void AppendEscapedCharForHTMLImpl(typename str::value_type c, str* output) {
|
| static const struct {
|
| char key;
|
| - const char *replacement;
|
| + const char* replacement;
|
| } kCharsToEscape[] = {
|
| { '<', "<" },
|
| { '>', ">" },
|
| @@ -326,3 +342,38 @@
|
| string16 EscapeForHTML(const string16& input) {
|
| return EscapeForHTMLImpl(input);
|
| }
|
| +
|
| +string16 UnescapeForHTML(const string16& input) {
|
| + static const struct {
|
| + const wchar_t* ampersand_code;
|
| + const char replacement;
|
| + } kEscapeToChars[] = {
|
| + { L"<", '<' },
|
| + { L">", '>' },
|
| + { L"&", '&' },
|
| + { L""", '"' },
|
| + { L"'", '\''},
|
| + };
|
| +
|
| + if (input.find(WideToUTF16(L"&")) == std::string::npos)
|
| + return input;
|
| +
|
| + string16 ampersand_chars[ARRAYSIZE_UNSAFE(kEscapeToChars)];
|
| + string16 text(input);
|
| + for (string16::iterator iter = text.begin(); iter != text.end(); ++iter) {
|
| + if (*iter == '&') {
|
| + // Potential ampersand encode char.
|
| + size_t index = iter - text.begin();
|
| + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kEscapeToChars); i++) {
|
| + if (ampersand_chars[i].empty())
|
| + ampersand_chars[i] = WideToUTF16(kEscapeToChars[i].ampersand_code);
|
| + if (text.find(ampersand_chars[i], index) == index) {
|
| + text.replace(iter, iter + ampersand_chars[i].length(),
|
| + 1, kEscapeToChars[i].replacement);
|
| + break;
|
| + }
|
| + }
|
| + }
|
| + }
|
| + return text;
|
| +}
|
|
|