Commit d165b6b7 authored by tyoshino's avatar tyoshino Committed by Commit bot

Fix URLSearchParams to use the right encoding algorithm

The stringifier of URLSearchParams must use the
application/x-www-form-urlencoded byte serializer algorithm.

The "extract" algorithm of Body mixin defined in the Fetch Standard
should also use the algorithm for processing URLSearchParams.

This algorithm doesn't include CRLF normalization unlike <form>
submission algorithm.

BUG=557063
R=sigbjornf@opera.com,mkwst

Review-Url: https://codereview.chromium.org/1998563002
Cr-Commit-Position: refs/heads/master@{#396801}
parent 997ce8b3
This is a testharness.js-based test.
PASS Serialize space
PASS Serialize empty value
PASS Serialize empty name
PASS Serialize empty name and value
PASS Serialize +
PASS Serialize =
PASS Serialize &
PASS Serialize U+0000 -> '\0'
PASS Serialize U+0001 -> ''
PASS Serialize U+0002 -> ''
PASS Serialize U+0003 -> ''
PASS Serialize U+0004 -> ''
PASS Serialize U+0005 -> ''
PASS Serialize U+0006 -> ''
PASS Serialize U+0007 -> ''
PASS Serialize U+0008 -> ''
PASS Serialize U+0009 -> ' '
PASS Serialize U+000A -> '
'
PASS Serialize U+000B -> ' '
PASS Serialize U+000C -> ' '
PASS Serialize U+000D -> '\r'
PASS Serialize U+000E -> ''
PASS Serialize U+000F -> ''
PASS Serialize U+0010 -> ''
PASS Serialize U+0011 -> ''
PASS Serialize U+0012 -> ''
PASS Serialize U+0013 -> ''
PASS Serialize U+0014 -> ''
PASS Serialize U+0015 -> ''
PASS Serialize U+0016 -> ''
PASS Serialize U+0017 -> ''
PASS Serialize U+0018 -> ''
PASS Serialize U+0019 -> ''
PASS Serialize U+001A -> ''
PASS Serialize U+001B -> ''
PASS Serialize U+001C -> ''
PASS Serialize U+001D -> ''
PASS Serialize U+001E -> ''
PASS Serialize U+001F -> ''
PASS Serialize U+0020 -> ' '
FAIL Serialize U+0021 -> '!' assert_equals: expected "33=%21" but got "33=!"
PASS Serialize U+0022 -> '"'
PASS Serialize U+0023 -> '#'
PASS Serialize U+0024 -> '$'
PASS Serialize U+0025 -> '%'
PASS Serialize U+0026 -> '&'
PASS Serialize U+0027 -> '''
FAIL Serialize U+0028 -> '(' assert_equals: expected "40=%28" but got "40=("
FAIL Serialize U+0029 -> ')' assert_equals: expected "41=%29" but got "41=)"
PASS Serialize U+002A -> '*'
PASS Serialize U+002B -> '+'
PASS Serialize U+002C -> ','
PASS Serialize U+002D -> '-'
PASS Serialize U+002E -> '.'
FAIL Serialize U+002F -> '/' assert_equals: expected "47=%2F" but got "47=/"
PASS Serialize U+0030 -> '0'
PASS Serialize U+0031 -> '1'
PASS Serialize U+0032 -> '2'
PASS Serialize U+0033 -> '3'
PASS Serialize U+0034 -> '4'
PASS Serialize U+0035 -> '5'
PASS Serialize U+0036 -> '6'
PASS Serialize U+0037 -> '7'
PASS Serialize U+0038 -> '8'
PASS Serialize U+0039 -> '9'
PASS Serialize U+003A -> ':'
PASS Serialize U+003B -> ';'
PASS Serialize U+003C -> '<'
PASS Serialize U+003D -> '='
PASS Serialize U+003E -> '>'
PASS Serialize U+003F -> '?'
PASS Serialize U+0040 -> '@'
PASS Serialize U+0041 -> 'A'
PASS Serialize U+0042 -> 'B'
PASS Serialize U+0043 -> 'C'
PASS Serialize U+0044 -> 'D'
PASS Serialize U+0045 -> 'E'
PASS Serialize U+0046 -> 'F'
PASS Serialize U+0047 -> 'G'
PASS Serialize U+0048 -> 'H'
PASS Serialize U+0049 -> 'I'
PASS Serialize U+004A -> 'J'
PASS Serialize U+004B -> 'K'
PASS Serialize U+004C -> 'L'
PASS Serialize U+004D -> 'M'
PASS Serialize U+004E -> 'N'
PASS Serialize U+004F -> 'O'
PASS Serialize U+0050 -> 'P'
PASS Serialize U+0051 -> 'Q'
PASS Serialize U+0052 -> 'R'
PASS Serialize U+0053 -> 'S'
PASS Serialize U+0054 -> 'T'
PASS Serialize U+0055 -> 'U'
PASS Serialize U+0056 -> 'V'
PASS Serialize U+0057 -> 'W'
PASS Serialize U+0058 -> 'X'
PASS Serialize U+0059 -> 'Y'
PASS Serialize U+005A -> 'Z'
PASS Serialize U+005B -> '['
PASS Serialize U+005C -> '\'
PASS Serialize U+005D -> ']'
PASS Serialize U+005E -> '^'
PASS Serialize U+005F -> '_'
PASS Serialize U+0060 -> '`'
PASS Serialize U+0061 -> 'a'
PASS Serialize U+0062 -> 'b'
PASS Serialize U+0063 -> 'c'
PASS Serialize U+0064 -> 'd'
PASS Serialize U+0065 -> 'e'
PASS Serialize U+0066 -> 'f'
PASS Serialize U+0067 -> 'g'
PASS Serialize U+0068 -> 'h'
PASS Serialize U+0069 -> 'i'
PASS Serialize U+006A -> 'j'
PASS Serialize U+006B -> 'k'
PASS Serialize U+006C -> 'l'
PASS Serialize U+006D -> 'm'
PASS Serialize U+006E -> 'n'
PASS Serialize U+006F -> 'o'
PASS Serialize U+0070 -> 'p'
PASS Serialize U+0071 -> 'q'
PASS Serialize U+0072 -> 'r'
PASS Serialize U+0073 -> 's'
PASS Serialize U+0074 -> 't'
PASS Serialize U+0075 -> 'u'
PASS Serialize U+0076 -> 'v'
PASS Serialize U+0077 -> 'w'
PASS Serialize U+0078 -> 'x'
PASS Serialize U+0079 -> 'y'
PASS Serialize U+007A -> 'z'
PASS Serialize U+007B -> '{'
PASS Serialize U+007C -> '|'
PASS Serialize U+007D -> '}'
FAIL Serialize U+007E -> '~' assert_equals: expected "126=%7E" but got "126=~"
PASS Serialize U+007F -> ''
PASS Serialize U+0080 -> '€'
PASS Serialize U+0081 -> ''
PASS Serialize U+0082 -> '‚'
PASS Serialize U+0083 -> 'ƒ'
PASS Serialize U+0084 -> '„'
PASS Serialize U+0085 -> '…'
PASS Serialize U+0086 -> '†'
PASS Serialize U+0087 -> '‡'
PASS Serialize U+0088 -> 'ˆ'
PASS Serialize U+0089 -> '‰'
PASS Serialize U+008A -> 'Š'
PASS Serialize U+008B -> '‹'
PASS Serialize U+008C -> 'Œ'
PASS Serialize U+008D -> ''
PASS Serialize U+008E -> 'Ž'
PASS Serialize U+008F -> ''
PASS Serialize U+0090 -> ''
PASS Serialize U+0091 -> '‘'
PASS Serialize U+0092 -> '’'
PASS Serialize U+0093 -> '“'
PASS Serialize U+0094 -> '”'
PASS Serialize U+0095 -> '•'
PASS Serialize U+0096 -> '–'
PASS Serialize U+0097 -> '—'
PASS Serialize U+0098 -> '˜'
PASS Serialize U+0099 -> '™'
PASS Serialize U+009A -> 'š'
PASS Serialize U+009B -> '›'
PASS Serialize U+009C -> 'œ'
PASS Serialize U+009D -> ''
PASS Serialize U+009E -> 'ž'
PASS Serialize U+009F -> 'Ÿ'
PASS Serialize U+00A0 -> ' '
PASS Serialize U+00A1 -> '¡'
PASS Serialize U+00A2 -> '¢'
PASS Serialize U+00A3 -> '£'
PASS Serialize U+00A4 -> '¤'
PASS Serialize U+00A5 -> '¥'
PASS Serialize U+00A6 -> '¦'
PASS Serialize U+00A7 -> '§'
PASS Serialize U+00A8 -> '¨'
PASS Serialize U+00A9 -> '©'
PASS Serialize U+00AA -> 'ª'
PASS Serialize U+00AB -> '«'
PASS Serialize U+00AC -> '¬'
PASS Serialize U+00AD -> '­'
PASS Serialize U+00AE -> '®'
PASS Serialize U+00AF -> '¯'
PASS Serialize U+00B0 -> '°'
PASS Serialize U+00B1 -> '±'
PASS Serialize U+00B2 -> '²'
PASS Serialize U+00B3 -> '³'
PASS Serialize U+00B4 -> '´'
PASS Serialize U+00B5 -> 'µ'
PASS Serialize U+00B6 -> '¶'
PASS Serialize U+00B7 -> '·'
PASS Serialize U+00B8 -> '¸'
PASS Serialize U+00B9 -> '¹'
PASS Serialize U+00BA -> 'º'
PASS Serialize U+00BB -> '»'
PASS Serialize U+00BC -> '¼'
PASS Serialize U+00BD -> '½'
PASS Serialize U+00BE -> '¾'
PASS Serialize U+00BF -> '¿'
PASS Serialize U+00C0 -> 'À'
PASS Serialize U+00C1 -> 'Á'
PASS Serialize U+00C2 -> 'Â'
PASS Serialize U+00C3 -> 'Ã'
PASS Serialize U+00C4 -> 'Ä'
PASS Serialize U+00C5 -> 'Å'
PASS Serialize U+00C6 -> 'Æ'
PASS Serialize U+00C7 -> 'Ç'
PASS Serialize U+00C8 -> 'È'
PASS Serialize U+00C9 -> 'É'
PASS Serialize U+00CA -> 'Ê'
PASS Serialize U+00CB -> 'Ë'
PASS Serialize U+00CC -> 'Ì'
PASS Serialize U+00CD -> 'Í'
PASS Serialize U+00CE -> 'Î'
PASS Serialize U+00CF -> 'Ï'
PASS Serialize U+00D0 -> 'Ð'
PASS Serialize U+00D1 -> 'Ñ'
PASS Serialize U+00D2 -> 'Ò'
PASS Serialize U+00D3 -> 'Ó'
PASS Serialize U+00D4 -> 'Ô'
PASS Serialize U+00D5 -> 'Õ'
PASS Serialize U+00D6 -> 'Ö'
PASS Serialize U+00D7 -> '×'
PASS Serialize U+00D8 -> 'Ø'
PASS Serialize U+00D9 -> 'Ù'
PASS Serialize U+00DA -> 'Ú'
PASS Serialize U+00DB -> 'Û'
PASS Serialize U+00DC -> 'Ü'
PASS Serialize U+00DD -> 'Ý'
PASS Serialize U+00DE -> 'Þ'
PASS Serialize U+00DF -> 'ß'
PASS Serialize U+00E0 -> 'à'
PASS Serialize U+00E1 -> 'á'
PASS Serialize U+00E2 -> 'â'
PASS Serialize U+00E3 -> 'ã'
PASS Serialize U+00E4 -> 'ä'
PASS Serialize U+00E5 -> 'å'
PASS Serialize U+00E6 -> 'æ'
PASS Serialize U+00E7 -> 'ç'
PASS Serialize U+00E8 -> 'è'
PASS Serialize U+00E9 -> 'é'
PASS Serialize U+00EA -> 'ê'
PASS Serialize U+00EB -> 'ë'
PASS Serialize U+00EC -> 'ì'
PASS Serialize U+00ED -> 'í'
PASS Serialize U+00EE -> 'î'
PASS Serialize U+00EF -> 'ï'
PASS Serialize U+00F0 -> 'ð'
PASS Serialize U+00F1 -> 'ñ'
PASS Serialize U+00F2 -> 'ò'
PASS Serialize U+00F3 -> 'ó'
PASS Serialize U+00F4 -> 'ô'
PASS Serialize U+00F5 -> 'õ'
PASS Serialize U+00F6 -> 'ö'
PASS Serialize U+00F7 -> '÷'
PASS Serialize U+00F8 -> 'ø'
PASS Serialize U+00F9 -> 'ù'
PASS Serialize U+00FA -> 'ú'
PASS Serialize U+00FB -> 'û'
PASS Serialize U+00FC -> 'ü'
PASS Serialize U+00FD -> 'ý'
PASS Serialize U+00FE -> 'þ'
PASS Serialize %
PASS Serialize \0
PASS Serialize 💩
PASS URLSearchParams.toString
Harness: the test ran to completion.
......@@ -96,13 +96,32 @@ function urlEncodedSerialize(n) {
for (var i = 0x00; i < 0xFF; i++) {
// Not all bytes can appear in valid UTF-8, so some bytes aren't covered.
// TODO(mkwst): We fail to properly encode a few bytes: https://crbug.com/557063
var expected = urlEncodedSerialize(i);
test(function() {
var params = new URLSearchParams();
params.append('' + i, String.fromCodePoint(i));
assert_equals(params + '', '' + i + '=' + urlEncodedSerialize(i));
}, "Serialize U+00" + intToHex(i) + " -> '" + String.fromCodePoint(i) + "'");
assert_equals(params + '', '' + i + '=' + expected);
}, "Serialize U+00" + intToHex(i) + " -> '" + expected + "'");
}
test(function() {
var params = new URLSearchParams();
params.append('a', '\r');
assert_equals(params + '', 'a=%0D');
}, 'Serialize \\r');
test(function() {
var params = new URLSearchParams();
params.append('a', '\n');
assert_equals(params + '', 'a=%0A');
}, 'Serialize \\n');
test(function() {
var params = new URLSearchParams();
params.append('a', '\r\n');
assert_equals(params + '', 'a=%0D%0A');
}, 'Serialize \\r\\n');
test(function() {
var params = new URLSearchParams();
params.append('a', 'b%c');
......@@ -143,4 +162,3 @@ test(function() {
</script>
</head>
</html>
......@@ -647,6 +647,31 @@ async_test(function(t) {
.then(function(result) {
assert_equals(result, "sample+string=1234567890");
})
.then(function() {
// Alphanumeric characters and *-._ shouldn't be percent-encoded.
// The others must.
var params = new URLSearchParams();
params.append('\0\x1f!)*+,-./:?[^_{~\x7f\u0080',
'\0\x1f!)*+,-./:?[^_{~\x7f\u0080');
request = new Request(URL, {method: 'POST', body: params});
return request.text();
})
.then(function(result) {
assert_equals(
result,
"%00%1F%21%29*%2B%2C-.%2F%3A%3F%5B%5E_%7B%7E%7F%C2%80=" +
"%00%1F%21%29*%2B%2C-.%2F%3A%3F%5B%5E_%7B%7E%7F%C2%80");
})
.then(function() {
// CR and LF shouldn't be normalized into CRLF.
var params = new URLSearchParams();
params.append('\r \n \r\n', '\r \n \r\n');
request = new Request(URL, {method: 'POST', body: params});
return request.text();
})
.then(function(result) {
assert_equals(result, "%0D+%0A+%0D%0A=%0D+%0A+%0D%0A");
})
.then(function() {
t.done();
})
......
......@@ -7,7 +7,6 @@
#include "core/dom/DOMURL.h"
#include "platform/network/FormDataEncoder.h"
#include "platform/weborigin/KURL.h"
#include "wtf/text/StringBuilder.h"
#include "wtf/text/TextEncoding.h"
namespace blink {
......@@ -124,22 +123,11 @@ void URLSearchParams::setInput(const String& queryString)
runUpdateSteps();
}
static String encodeString(const String& input)
{
return encodeWithURLEscapeSequences(input).replace("%20", "+");
}
String URLSearchParams::toString() const
{
StringBuilder result;
for (size_t i = 0; i < m_params.size(); ++i) {
if (i)
result.append('&');
result.append(encodeString(m_params[i].first));
result.append('=');
result.append(encodeString(m_params[i].second));
}
return result.toString();
Vector<char> encodedData;
encodeAsFormData(encodedData);
return String(encodedData.data(), encodedData.size());
}
void URLSearchParams::append(const String& name, const String& value)
......@@ -212,11 +200,16 @@ void URLSearchParams::set(const String& name, const String& value)
runUpdateSteps();
}
PassRefPtr<EncodedFormData> URLSearchParams::encodeFormData() const
void URLSearchParams::encodeAsFormData(Vector<char>& encodedData) const
{
Vector<char> encodedData;
for (const auto& param : m_params)
FormDataEncoder::addKeyValuePairAsFormData(encodedData, param.first.utf8(), param.second.utf8(), EncodedFormData::FormURLEncoded);
FormDataEncoder::addKeyValuePairAsFormData(encodedData, param.first.utf8(), param.second.utf8(), EncodedFormData::FormURLEncoded, FormDataEncoder::DoNotNormalizeCRLF);
}
PassRefPtr<EncodedFormData> URLSearchParams::toEncodedFormData() const
{
Vector<char> encodedData;
encodeAsFormData(encodedData);
return EncodedFormData::create(encodedData.data(), encodedData.size());
}
......
......@@ -46,7 +46,7 @@ public:
void setInput(const String&);
// Internal helpers
PassRefPtr<EncodedFormData> encodeFormData() const;
PassRefPtr<EncodedFormData> toEncodedFormData() const;
const Vector<std::pair<String, String>>& params() const { return m_params; }
#if ENABLE(ASSERT)
......@@ -63,6 +63,7 @@ private:
void runUpdateSteps();
IterationSource* startIteration(ScriptState*, ExceptionState&) override;
void encodeAsFormData(Vector<char>&) const;
Vector<std::pair<String, String>> m_params;
......
......@@ -10,16 +10,16 @@ namespace blink {
using URLSearchParamsTest = ::testing::Test;
TEST_F(URLSearchParamsTest, EncodedFormData)
TEST_F(URLSearchParamsTest, ToEncodedFormData)
{
URLSearchParams* params = new URLSearchParams(String());
EXPECT_EQ("", params->encodeFormData()->flattenToString());
URLSearchParams* params = URLSearchParams::create(String());
EXPECT_EQ("", params->toEncodedFormData()->flattenToString());
params->append("name", "value");
EXPECT_EQ("name=value", params->encodeFormData()->flattenToString());
EXPECT_EQ("name=value", params->toEncodedFormData()->flattenToString());
params->append("another name", "another value");
EXPECT_EQ("name=value&another+name=another+value", params->encodeFormData()->flattenToString());
EXPECT_EQ("name=value&another+name=another+value", params->toEncodedFormData()->flattenToString());
}
} // namespace blink
......@@ -72,7 +72,7 @@ static void appendMailtoPostFormDataToURL(KURL& url, const EncodedFormData& data
Vector<char> bodyData;
bodyData.append("body=", 5);
FormDataEncoder::encodeStringAsFormData(bodyData, body.utf8());
FormDataEncoder::encodeStringAsFormData(bodyData, body.utf8(), FormDataEncoder::NormalizeCRLF);
body = String(bodyData.data(), bodyData.size()).replace('+', "%20");
StringBuilder query;
......
......@@ -134,7 +134,7 @@ PassRefPtr<EncodedFormData> PasswordCredential::encodeFormData(String& contentTy
contentType = AtomicString("application/x-www-form-urlencoded;charset=UTF-8");
return params->encodeFormData();
return params->toEncodedFormData();
}
// Otherwise, we'll build a multipart response.
......
......@@ -124,7 +124,7 @@ RequestInit::RequestInit(ExecutionContext* context, const Dictionary& options, E
contentType = AtomicString("multipart/form-data; boundary=") + formData->boundary().data();
body = FetchFormDataConsumerHandle::create(context, formData.release());
} else if (V8URLSearchParams::hasInstance(v8Body, isolate)) {
RefPtr<EncodedFormData> formData = V8URLSearchParams::toImpl(v8::Local<v8::Object>::Cast(v8Body))->encodeFormData();
RefPtr<EncodedFormData> formData = V8URLSearchParams::toImpl(v8::Local<v8::Object>::Cast(v8Body))->toEncodedFormData();
contentType = AtomicString("application/x-www-form-urlencoded;charset=UTF-8");
body = FetchFormDataConsumerHandle::create(context, formData.release());
} else if (v8Body->IsString()) {
......
......@@ -48,6 +48,12 @@ static inline void append(Vector<char>& buffer, const CString& string)
buffer.append(string.data(), string.length());
}
static inline void appendPercentEncoded(Vector<char>& buffer, unsigned char c)
{
append(buffer, '%');
appendByteAsHex(c, buffer);
}
static void appendQuotedString(Vector<char>& buffer, const CString& string)
{
// Append a string as a quoted value, escaping quotes and line breaks.
......@@ -177,7 +183,7 @@ void FormDataEncoder::finishMultiPartHeader(Vector<char>& buffer)
append(buffer, "\r\n\r\n");
}
void FormDataEncoder::addKeyValuePairAsFormData(Vector<char>& buffer, const CString& key, const CString& value, EncodedFormData::EncodingType encodingType)
void FormDataEncoder::addKeyValuePairAsFormData(Vector<char>& buffer, const CString& key, const CString& value, EncodedFormData::EncodingType encodingType, Mode mode)
{
if (encodingType == EncodedFormData::TextPlain) {
if (!buffer.isEmpty())
......@@ -188,13 +194,13 @@ void FormDataEncoder::addKeyValuePairAsFormData(Vector<char>& buffer, const CStr
} else {
if (!buffer.isEmpty())
append(buffer, '&');
encodeStringAsFormData(buffer, key);
encodeStringAsFormData(buffer, key, mode);
append(buffer, '=');
encodeStringAsFormData(buffer, value);
encodeStringAsFormData(buffer, value, mode);
}
}
void FormDataEncoder::encodeStringAsFormData(Vector<char>& buffer, const CString& string)
void FormDataEncoder::encodeStringAsFormData(Vector<char>& buffer, const CString& string, Mode mode)
{
// Same safe characters as Netscape for compatibility.
static const char safeCharacters[] = "-._*";
......@@ -204,15 +210,20 @@ void FormDataEncoder::encodeStringAsFormData(Vector<char>& buffer, const CString
for (unsigned i = 0; i < length; ++i) {
unsigned char c = string.data()[i];
if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || strchr(safeCharacters, c)) {
if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || (c != '\0' && strchr(safeCharacters, c))) {
append(buffer, c);
} else if (c == ' ') {
append(buffer, '+');
} else if (c == '\n' || (c == '\r' && (i + 1 >= length || string.data()[i + 1] != '\n'))) {
append(buffer, "%0D%0A");
} else if (c != '\r') {
append(buffer, '%');
appendByteAsHex(c, buffer);
} else {
if (mode == NormalizeCRLF) {
if (c == '\n' || (c == '\r' && (i + 1 >= length || string.data()[i + 1] != '\n'))) {
append(buffer, "%0D%0A");
} else if (c != '\r') {
appendPercentEncoded(buffer, c);
}
} else {
appendPercentEncoded(buffer, c);
}
}
}
}
......
......@@ -34,6 +34,15 @@ namespace blink {
class PLATFORM_EXPORT FormDataEncoder {
STATIC_ONLY(FormDataEncoder);
public:
// Specifies how to handle CRs and LFs. When NormalizeCRLF is passed, the
// method replaces the following characters with a CRLF pair:
// - a CR not followed by an LF
// - an LF not preceded by a CR
enum Mode {
NormalizeCRLF,
DoNotNormalizeCRLF
};
static WTF::TextEncoding encodingFromAcceptCharset(const String& acceptCharset, const WTF::TextEncoding& fallbackEncoding);
// Helper functions used by HTMLFormElement for multi-part form data
......@@ -44,9 +53,10 @@ public:
static void addContentTypeToMultiPartHeader(Vector<char>&, const CString& mimeType);
static void finishMultiPartHeader(Vector<char>&);
// Helper functions used by HTMLFormElement for non multi-part form data
static void addKeyValuePairAsFormData(Vector<char>&, const CString& key, const CString& value, EncodedFormData::EncodingType = EncodedFormData::FormURLEncoded);
static void encodeStringAsFormData(Vector<char>&, const CString&);
// Helper functions used by HTMLFormElement for non multi-part form data. Mode
// argument is not used for TextPlain type.
static void addKeyValuePairAsFormData(Vector<char>&, const CString& key, const CString& value, EncodedFormData::EncodingType = EncodedFormData::FormURLEncoded, Mode = NormalizeCRLF);
static void encodeStringAsFormData(Vector<char>&, const CString&, Mode);
};
} // namespace blink
......
......@@ -215,13 +215,13 @@ bool buildSearchString(const HTMLFormElement& form, Vector<char>* encodedString,
for (const auto& entry : formData->entries()) {
if (!encodedString->isEmpty())
encodedString->append('&');
FormDataEncoder::encodeStringAsFormData(*encodedString, entry->name());
FormDataEncoder::encodeStringAsFormData(*encodedString, entry->name(), FormDataEncoder::NormalizeCRLF);
encodedString->append('=');
if (&control == textElement) {
encodedString->append("{searchTerms}", 13);
isElementFound = true;
} else {
FormDataEncoder::encodeStringAsFormData(*encodedString, entry->value());
FormDataEncoder::encodeStringAsFormData(*encodedString, entry->value(), FormDataEncoder::NormalizeCRLF);
}
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment