зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1680478 [wpt PR 26740] - Add test cases for newline handling in form payloads, a=testonly
Automatic update from web-platform-tests Add test cases for newline handling in form payloads -- wpt-commits: 9353d550f0d49f5fd090dc276b60528c642b80d0 wpt-pr: 26740
This commit is contained in:
Родитель
c4de0fa719
Коммит
3aae1c3908
|
@ -1,10 +1,6 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8" />
|
||||
<title>FormData: Upload files named using controls (tentative)</title>
|
||||
<!--
|
||||
NOTE: This test is tentative because encoding for filename
|
||||
control characters is not yet standardized.
|
||||
-->
|
||||
<title>FormData: Upload files named using controls</title>
|
||||
<link
|
||||
rel="help"
|
||||
href="https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#multipart-form-data"
|
|
@ -1,10 +1,6 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8" />
|
||||
<title>FormData: Upload files named using punctuation (tentative)</title>
|
||||
<!--
|
||||
NOTE: This test is tentative because encoding for filename
|
||||
punctuation characters is not yet standardized.
|
||||
-->
|
||||
<title>FormData: Upload files named using punctuation</title>
|
||||
<link
|
||||
rel="help"
|
||||
href="https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#multipart-form-data"
|
|
@ -70,19 +70,21 @@ const formDataPostFileUploadTest = ({
|
|||
}`,
|
||||
);
|
||||
|
||||
const asName = fileBaseName.replace(/[\r\n"]/g, encodeURIComponent);
|
||||
const asValue = fileBaseName.replace(/\r\n?|\n/g, "\r\n");
|
||||
const asName = asValue.replace(/[\r\n"]/g, encodeURIComponent);
|
||||
const asFilename = fileBaseName.replace(/[\r\n"]/g, encodeURIComponent);
|
||||
const expectedText = [
|
||||
boundary,
|
||||
'Content-Disposition: form-data; name="filename"',
|
||||
"",
|
||||
fileBaseName,
|
||||
asValue,
|
||||
boundary,
|
||||
`Content-Disposition: form-data; name="${asName}"`,
|
||||
"",
|
||||
"filename",
|
||||
boundary,
|
||||
`Content-Disposition: form-data; name="file"; ` +
|
||||
`filename="${asName}"`,
|
||||
`filename="${asFilename}"`,
|
||||
"Content-Type: text/plain",
|
||||
"",
|
||||
kTestChars,
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<div id="container"></div>
|
||||
|
@ -30,32 +31,85 @@ class MyControl extends HTMLElement {
|
|||
customElements.define('my-control', MyControl);
|
||||
const $ = document.querySelector.bind(document);
|
||||
|
||||
function submitPromise(t) {
|
||||
function submitPromise(t, extractFromIframe) {
|
||||
if (!extractFromIframe) {
|
||||
extractFromIframe = (iframe) => iframe.contentWindow.location.search;
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
const iframe = $('iframe');
|
||||
iframe.onload = () => resolve(iframe.contentWindow.location.search);
|
||||
iframe.onload = () => resolve(extractFromIframe(iframe));
|
||||
iframe.onerror = () => reject(new Error('iframe onerror fired'));
|
||||
$('form').submit();
|
||||
});
|
||||
}
|
||||
|
||||
function testSerializedEntry({name, expectedName, value, expectedValue, description}) {
|
||||
promise_test(async t => {
|
||||
$('#container').innerHTML = '<form action="/common/blank.html" target="if1">' +
|
||||
'<my-control></my-control>' +
|
||||
'</form>' +
|
||||
'<iframe name="if1"></iframe>';
|
||||
if (name !== undefined) {
|
||||
$('my-control').setAttribute("name", name);
|
||||
}
|
||||
if (Array.isArray(value)) {
|
||||
$('my-control').setValues(value);
|
||||
} else {
|
||||
$('my-control').value = value;
|
||||
}
|
||||
const query = await submitPromise(t);
|
||||
assert_equals(query, `?${expectedName}=${expectedValue}`);
|
||||
}, description);
|
||||
function testSerializedEntry({name, value, expected, description}) {
|
||||
// urlencoded
|
||||
{
|
||||
const {name: expectedName, value: expectedValue} = expected.urlencoded;
|
||||
promise_test(async t => {
|
||||
$('#container').innerHTML = '<form action="/common/blank.html" target="if1">' +
|
||||
'<my-control></my-control>' +
|
||||
'</form>' +
|
||||
'<iframe name="if1"></iframe>';
|
||||
if (name !== undefined) {
|
||||
$('my-control').setAttribute("name", name);
|
||||
}
|
||||
if (Array.isArray(value)) {
|
||||
$('my-control').setValues(value);
|
||||
} else {
|
||||
$('my-control').value = value;
|
||||
}
|
||||
const query = await submitPromise(t);
|
||||
assert_equals(query, `?${expectedName}=${expectedValue}`);
|
||||
}, `${description} (urlencoded)`);
|
||||
}
|
||||
|
||||
// formdata
|
||||
{
|
||||
const {name: expectedName, filename: expectedFilename, value: expectedValue} = expected.formdata;
|
||||
promise_test(async t => {
|
||||
$('#container').innerHTML =
|
||||
'<form action="/FileAPI/file/resources/echo-content-escaped.py" method="post" enctype="multipart/form-data" target="if1">' +
|
||||
'<my-control></my-control>' +
|
||||
'</form>' +
|
||||
'<iframe name="if1"></iframe>';
|
||||
if (name !== undefined) {
|
||||
$('my-control').setAttribute("name", name);
|
||||
}
|
||||
if (Array.isArray(value)) {
|
||||
$('my-control').setValues(value);
|
||||
} else {
|
||||
$('my-control').value = value;
|
||||
}
|
||||
const escaped = await submitPromise(t, iframe => iframe.contentDocument.body.textContent);
|
||||
const formdata = escaped
|
||||
.replace(/\r\n?|\n/g, "\r\n")
|
||||
.replace(
|
||||
/\\x[0-9A-Fa-f]{2}/g,
|
||||
escape => String.fromCodePoint(parseInt(escape.substring(2), 16))
|
||||
);
|
||||
const boundary = formdata.split("\r\n")[0];
|
||||
const expected = [
|
||||
boundary,
|
||||
...(() => {
|
||||
if (expectedFilename === undefined) {
|
||||
return [`Content-Disposition: form-data; name="${expectedName}"`];
|
||||
} else {
|
||||
return [
|
||||
`Content-Disposition: form-data; name="${expectedName}"; filename="${expectedFilename}"`,
|
||||
"Content-Type: text/plain"
|
||||
];
|
||||
}
|
||||
})(),
|
||||
"",
|
||||
expectedValue,
|
||||
boundary + "--",
|
||||
""
|
||||
].join("\r\n");
|
||||
assert_equals(formdata, expected);
|
||||
}, `${description} (formdata)`);
|
||||
}
|
||||
}
|
||||
|
||||
promise_test(t => {
|
||||
|
@ -145,152 +199,380 @@ promise_test(t => {
|
|||
testSerializedEntry({
|
||||
name: 'a\nb',
|
||||
value: 'c',
|
||||
expectedName: 'a%0D%0Ab',
|
||||
expectedValue: 'c',
|
||||
expected: {
|
||||
urlencoded: {
|
||||
name: 'a%0D%0Ab',
|
||||
value: 'c'
|
||||
},
|
||||
formdata: {
|
||||
name: 'a%0D%0Ab',
|
||||
value: 'c'
|
||||
}
|
||||
},
|
||||
description: 'Newline normalization - \\n in name'
|
||||
});
|
||||
|
||||
testSerializedEntry({
|
||||
name: 'a\rb',
|
||||
value: 'c',
|
||||
expectedName: 'a%0D%0Ab',
|
||||
expectedValue: 'c',
|
||||
expected: {
|
||||
urlencoded: {
|
||||
name: 'a%0D%0Ab',
|
||||
value: 'c'
|
||||
},
|
||||
formdata: {
|
||||
name: 'a%0D%0Ab',
|
||||
value: 'c'
|
||||
}
|
||||
},
|
||||
description: 'Newline normalization - \\r in name'
|
||||
});
|
||||
|
||||
testSerializedEntry({
|
||||
name: 'a\r\nb',
|
||||
value: 'c',
|
||||
expectedName: 'a%0D%0Ab',
|
||||
expectedValue: 'c',
|
||||
expected: {
|
||||
urlencoded: {
|
||||
name: 'a%0D%0Ab',
|
||||
value: 'c'
|
||||
},
|
||||
formdata: {
|
||||
name: 'a%0D%0Ab',
|
||||
value: 'c'
|
||||
}
|
||||
},
|
||||
description: 'Newline normalization - \\r\\n in name'
|
||||
});
|
||||
|
||||
testSerializedEntry({
|
||||
name: 'a\n\rb',
|
||||
value: 'c',
|
||||
expectedName: 'a%0D%0A%0D%0Ab',
|
||||
expectedValue: 'c',
|
||||
expected: {
|
||||
urlencoded: {
|
||||
name: 'a%0D%0A%0D%0Ab',
|
||||
value: 'c'
|
||||
},
|
||||
formdata: {
|
||||
name: 'a%0D%0A%0D%0Ab',
|
||||
value: 'c'
|
||||
}
|
||||
},
|
||||
description: 'Newline normalization - \\n\\r in name'
|
||||
});
|
||||
|
||||
testSerializedEntry({
|
||||
name: 'a',
|
||||
value: 'b\nc',
|
||||
expectedName: 'a',
|
||||
expectedValue: 'b%0D%0Ac',
|
||||
expected: {
|
||||
urlencoded: {
|
||||
name: 'a',
|
||||
value: 'b%0D%0Ac'
|
||||
},
|
||||
formdata: {
|
||||
name: 'a',
|
||||
value: 'b\r\nc'
|
||||
}
|
||||
},
|
||||
description: 'Newline normalization - \\n in value'
|
||||
});
|
||||
|
||||
testSerializedEntry({
|
||||
name: 'a',
|
||||
value: 'b\rc',
|
||||
expectedName: 'a',
|
||||
expectedValue: 'b%0D%0Ac',
|
||||
expected: {
|
||||
urlencoded: {
|
||||
name: 'a',
|
||||
value: 'b%0D%0Ac'
|
||||
},
|
||||
formdata: {
|
||||
name: 'a',
|
||||
value: 'b\r\nc'
|
||||
}
|
||||
},
|
||||
description: 'Newline normalization - \\r in value'
|
||||
});
|
||||
|
||||
testSerializedEntry({
|
||||
name: 'a',
|
||||
value: 'b\r\nc',
|
||||
expectedName: 'a',
|
||||
expectedValue: 'b%0D%0Ac',
|
||||
expected: {
|
||||
urlencoded: {
|
||||
name: 'a',
|
||||
value: 'b%0D%0Ac'
|
||||
},
|
||||
formdata: {
|
||||
name: 'a',
|
||||
value: 'b\r\nc'
|
||||
}
|
||||
},
|
||||
description: 'Newline normalization - \\r\\n in value'
|
||||
});
|
||||
|
||||
testSerializedEntry({
|
||||
name: 'a',
|
||||
value: 'b\n\rc',
|
||||
expectedName: 'a',
|
||||
expectedValue: 'b%0D%0A%0D%0Ac',
|
||||
expected: {
|
||||
urlencoded: {
|
||||
name: 'a',
|
||||
value: 'b%0D%0A%0D%0Ac'
|
||||
},
|
||||
formdata: {
|
||||
name: 'a',
|
||||
value: 'b\r\n\r\nc'
|
||||
}
|
||||
},
|
||||
description: 'Newline normalization - \\n\\r in value'
|
||||
});
|
||||
|
||||
testSerializedEntry({
|
||||
name: 'a',
|
||||
value: new File([], "b\nc"),
|
||||
expectedName: 'a',
|
||||
expectedValue: 'b%0D%0Ac',
|
||||
value: new File([], "b\nc", {type: "text/plain"}),
|
||||
expected: {
|
||||
urlencoded: {
|
||||
name: 'a',
|
||||
value: 'b%0D%0Ac'
|
||||
},
|
||||
formdata: {
|
||||
name: 'a',
|
||||
filename: 'b%0Ac',
|
||||
value: ''
|
||||
}
|
||||
},
|
||||
description: 'Newline normalization - \\n in filename'
|
||||
});
|
||||
|
||||
testSerializedEntry({
|
||||
name: 'a',
|
||||
value: new File([], "b\rc"),
|
||||
expectedName: 'a',
|
||||
expectedValue: 'b%0D%0Ac',
|
||||
value: new File([], "b\rc", {type: "text/plain"}),
|
||||
expected: {
|
||||
urlencoded: {
|
||||
name: 'a',
|
||||
value: 'b%0D%0Ac'
|
||||
},
|
||||
formdata: {
|
||||
name: 'a',
|
||||
filename: 'b%0Dc',
|
||||
value: ''
|
||||
}
|
||||
},
|
||||
description: 'Newline normalization - \\r in filename'
|
||||
});
|
||||
|
||||
testSerializedEntry({
|
||||
name: 'a',
|
||||
value: new File([], "b\r\nc"),
|
||||
expectedName: 'a',
|
||||
expectedValue: 'b%0D%0Ac',
|
||||
value: new File([], "b\r\nc", {type: "text/plain"}),
|
||||
expected: {
|
||||
urlencoded: {
|
||||
name: 'a',
|
||||
value: 'b%0D%0Ac'
|
||||
},
|
||||
formdata: {
|
||||
name: 'a',
|
||||
filename: 'b%0D%0Ac',
|
||||
value: ''
|
||||
}
|
||||
},
|
||||
description: 'Newline normalization - \\r\\n in filename'
|
||||
});
|
||||
|
||||
testSerializedEntry({
|
||||
name: 'a',
|
||||
value: new File([], "b\n\rc"),
|
||||
expectedName: 'a',
|
||||
expectedValue: 'b%0D%0A%0D%0Ac',
|
||||
value: new File([], "b\n\rc", {type: "text/plain"}),
|
||||
expected: {
|
||||
urlencoded: {
|
||||
name: 'a',
|
||||
value: 'b%0D%0A%0D%0Ac'
|
||||
},
|
||||
formdata: {
|
||||
name: 'a',
|
||||
filename: 'b%0A%0Dc',
|
||||
value: ''
|
||||
}
|
||||
},
|
||||
description: 'Newline normalization - \\n\\r in filename'
|
||||
});
|
||||
|
||||
testSerializedEntry({
|
||||
value: [['a\nb', 'c']],
|
||||
expectedName: 'a%0Ab',
|
||||
expectedValue: 'c',
|
||||
expected: {
|
||||
urlencoded: {
|
||||
name: 'a%0D%0Ab',
|
||||
value: 'c'
|
||||
},
|
||||
formdata: {
|
||||
name: 'a%0D%0Ab',
|
||||
value: 'c'
|
||||
}
|
||||
},
|
||||
description: 'Newline normalization - \\n in FormData name'
|
||||
});
|
||||
|
||||
testSerializedEntry({
|
||||
value: [['a\rb', 'c']],
|
||||
expectedName: 'a%0Db',
|
||||
expectedValue: 'c',
|
||||
expected: {
|
||||
urlencoded: {
|
||||
name: 'a%0D%0Ab',
|
||||
value: 'c'
|
||||
},
|
||||
formdata: {
|
||||
name: 'a%0D%0Ab',
|
||||
value: 'c'
|
||||
}
|
||||
},
|
||||
description: 'Newline normalization - \\r in FormData name'
|
||||
});
|
||||
|
||||
testSerializedEntry({
|
||||
value: [['a\r\nb', 'c']],
|
||||
expectedName: 'a%0D%0Ab',
|
||||
expectedValue: 'c',
|
||||
expected: {
|
||||
urlencoded: {
|
||||
name: 'a%0D%0Ab',
|
||||
value: 'c'
|
||||
},
|
||||
formdata: {
|
||||
name: 'a%0D%0Ab',
|
||||
value: 'c'
|
||||
}
|
||||
},
|
||||
description: 'Newline normalization - \\r\\n in FormData name'
|
||||
});
|
||||
|
||||
testSerializedEntry({
|
||||
value: [['a\n\rb', 'c']],
|
||||
expectedName: 'a%0A%0Db',
|
||||
expectedValue: 'c',
|
||||
expected: {
|
||||
urlencoded: {
|
||||
name: 'a%0D%0A%0D%0Ab',
|
||||
value: 'c'
|
||||
},
|
||||
formdata: {
|
||||
name: 'a%0D%0A%0D%0Ab',
|
||||
value: 'c'
|
||||
}
|
||||
},
|
||||
description: 'Newline normalization - \\n\\r in FormData name'
|
||||
});
|
||||
|
||||
testSerializedEntry({
|
||||
value: [['a', 'b\nc']],
|
||||
expectedName: 'a',
|
||||
expectedValue: 'b%0Ac',
|
||||
expected: {
|
||||
urlencoded: {
|
||||
name: 'a',
|
||||
value: 'b%0D%0Ac'
|
||||
},
|
||||
formdata: {
|
||||
name: 'a',
|
||||
value: 'b\r\nc'
|
||||
}
|
||||
},
|
||||
description: 'Newline normalization - \\n in FormData value'
|
||||
});
|
||||
|
||||
testSerializedEntry({
|
||||
value: [['a', 'b\rc']],
|
||||
expectedName: 'a',
|
||||
expectedValue: 'b%0Dc',
|
||||
expected: {
|
||||
urlencoded: {
|
||||
name: 'a',
|
||||
value: 'b%0D%0Ac'
|
||||
},
|
||||
formdata: {
|
||||
name: 'a',
|
||||
value: 'b\r\nc'
|
||||
}
|
||||
},
|
||||
description: 'Newline normalization - \\r in FormData value'
|
||||
});
|
||||
|
||||
testSerializedEntry({
|
||||
value: [['a', 'b\r\nc']],
|
||||
expectedName: 'a',
|
||||
expectedValue: 'b%0D%0Ac',
|
||||
expected: {
|
||||
urlencoded: {
|
||||
name: 'a',
|
||||
value: 'b%0D%0Ac'
|
||||
},
|
||||
formdata: {
|
||||
name: 'a',
|
||||
value: 'b\r\nc'
|
||||
}
|
||||
},
|
||||
description: 'Newline normalization - \\r\\n in FormData value'
|
||||
});
|
||||
|
||||
testSerializedEntry({
|
||||
value: [['a', 'b\n\rc']],
|
||||
expectedName: 'a',
|
||||
expectedValue: 'b%0A%0Dc',
|
||||
expected: {
|
||||
urlencoded: {
|
||||
name: 'a',
|
||||
value: 'b%0D%0A%0D%0Ac'
|
||||
},
|
||||
formdata: {
|
||||
name: 'a',
|
||||
value: 'b\r\n\r\nc'
|
||||
}
|
||||
},
|
||||
description: 'Newline normalization - \\n\\r in FormData value'
|
||||
});
|
||||
|
||||
testSerializedEntry({
|
||||
value: [['a', new File([], 'b\nc', {type: "text/plain"})]],
|
||||
expected: {
|
||||
urlencoded: {
|
||||
name: 'a',
|
||||
value: 'b%0D%0Ac'
|
||||
},
|
||||
formdata: {
|
||||
name: 'a',
|
||||
filename: 'b%0Ac',
|
||||
value: ''
|
||||
}
|
||||
},
|
||||
description: 'Newline normalization - \\n in FormData filename'
|
||||
});
|
||||
|
||||
testSerializedEntry({
|
||||
value: [['a', new File([], 'b\rc', {type: "text/plain"})]],
|
||||
expected: {
|
||||
urlencoded: {
|
||||
name: 'a',
|
||||
value: 'b%0D%0Ac'
|
||||
},
|
||||
formdata: {
|
||||
name: 'a',
|
||||
filename: 'b%0Dc',
|
||||
value: ''
|
||||
}
|
||||
},
|
||||
description: 'Newline normalization - \\r in FormData filename'
|
||||
});
|
||||
|
||||
testSerializedEntry({
|
||||
value: [['a', new File([], 'b\r\nc', {type: "text/plain"})]],
|
||||
expected: {
|
||||
urlencoded: {
|
||||
name: 'a',
|
||||
value: 'b%0D%0Ac'
|
||||
},
|
||||
formdata: {
|
||||
name: 'a',
|
||||
filename: 'b%0D%0Ac',
|
||||
value: ''
|
||||
}
|
||||
},
|
||||
description: 'Newline normalization - \\r\\n in FormData filename'
|
||||
});
|
||||
|
||||
testSerializedEntry({
|
||||
value: [['a', new File([], 'b\n\rc', {type: "text/plain"})]],
|
||||
expected: {
|
||||
urlencoded: {
|
||||
name: 'a',
|
||||
value: 'b%0D%0A%0D%0Ac'
|
||||
},
|
||||
formdata: {
|
||||
name: 'a',
|
||||
filename: 'b%0A%0Dc',
|
||||
value: ''
|
||||
}
|
||||
},
|
||||
description: 'Newline normalization - \\n\\r in FormData filename'
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -114,6 +114,17 @@ t1.step(() => {
|
|||
form.submit();
|
||||
});
|
||||
|
||||
test(() => {
|
||||
const form = populateForm('');
|
||||
form.addEventListener('formdata', e => {
|
||||
e.formData.append('a\nb', 'c\rd');
|
||||
});
|
||||
const formData = new FormData(form);
|
||||
const [name, value] = [...formData][0];
|
||||
assert_equals(name, 'a\nb');
|
||||
assert_equals(value, 'c\rd');
|
||||
}, 'Entries added to the "formdata" IDL attribute shouldn\'t be newline normalized in the resulting FormData');
|
||||
|
||||
test(() => {
|
||||
let form = populateForm('<input name=n1 value=v1><button type=submit name=n2 value=v2></button>');
|
||||
let formDataInEvent = null;
|
||||
|
|
|
@ -0,0 +1,138 @@
|
|||
(() => {
|
||||
// Using echo-content-escaped.py rather than
|
||||
// /fetch/api/resources/echo-content.py to work around WebKit not
|
||||
// percent-encoding \x00, which causes the response to be detected as
|
||||
// a binary file and served as a download.
|
||||
const ACTION_URL = "/FileAPI/file/resources/echo-content-escaped.py";
|
||||
|
||||
const IFRAME_NAME = "formtargetframe";
|
||||
|
||||
// Undoes the escapes from /fetch/api/resources/echo-content.py
|
||||
function unescape(str) {
|
||||
return str
|
||||
.replace(/\r\n?|\n/g, "\r\n")
|
||||
.replace(
|
||||
/\\x[0-9A-Fa-f]{2}/g,
|
||||
(escape) => String.fromCodePoint(parseInt(escape.substring(2), 16)),
|
||||
)
|
||||
.replace(/\\\\/g, "\\");
|
||||
}
|
||||
|
||||
// `expectedBuilder` is a function that takes in the actual form body
|
||||
// (necessary to get the multipart/form-data payload) and returns the form
|
||||
// body that should be expected.
|
||||
// If `testFormData` is false, the form entry will be submitted in for
|
||||
// controls. If it is true, it will submitted by modifying the entry list
|
||||
// during the `formdata` event.
|
||||
async function formSubmissionTest({
|
||||
name,
|
||||
value,
|
||||
expectedBuilder,
|
||||
enctype,
|
||||
formEncoding,
|
||||
testFormData = false,
|
||||
testCase,
|
||||
}) {
|
||||
if (document.readyState !== "complete") {
|
||||
await new Promise((resolve) => addEventListener("load", resolve));
|
||||
}
|
||||
|
||||
const formTargetFrame = Object.assign(document.createElement("iframe"), {
|
||||
name: IFRAME_NAME,
|
||||
});
|
||||
document.body.append(formTargetFrame);
|
||||
testCase.add_cleanup(() => {
|
||||
document.body.removeChild(formTargetFrame);
|
||||
});
|
||||
|
||||
const form = Object.assign(document.createElement("form"), {
|
||||
acceptCharset: formEncoding,
|
||||
action: ACTION_URL,
|
||||
method: "POST",
|
||||
enctype,
|
||||
target: IFRAME_NAME,
|
||||
});
|
||||
document.body.append(form);
|
||||
testCase.add_cleanup(() => {
|
||||
document.body.removeChild(form);
|
||||
});
|
||||
|
||||
if (!testFormData) {
|
||||
const input = document.createElement("input");
|
||||
input.name = name;
|
||||
if (value instanceof File) {
|
||||
input.type = "file";
|
||||
const dataTransfer = new DataTransfer();
|
||||
dataTransfer.items.add(value);
|
||||
input.files = dataTransfer.files;
|
||||
} else {
|
||||
input.type = "hidden";
|
||||
input.value = value;
|
||||
}
|
||||
form.append(input);
|
||||
} else {
|
||||
form.addEventListener("formdata", (evt) => {
|
||||
evt.formData.append(name, value);
|
||||
});
|
||||
}
|
||||
|
||||
await new Promise((resolve) => {
|
||||
form.submit();
|
||||
formTargetFrame.onload = resolve;
|
||||
});
|
||||
|
||||
const serialized = unescape(
|
||||
formTargetFrame.contentDocument.body.textContent,
|
||||
);
|
||||
const expected = expectedBuilder(serialized);
|
||||
assert_equals(serialized, expected);
|
||||
}
|
||||
|
||||
// This function returns a function to add individual form tests corresponding
|
||||
// to some enctype.
|
||||
// `expectedBuilder` is a function that takes two parameters: `expected` (the
|
||||
// `expected` value of a test) and `serialized` (the actual form body
|
||||
// submitted by the browser), and returns the correct form body that should
|
||||
// have been submitted. This is necessary in order to account for th
|
||||
// multipart/form-data boundary.
|
||||
window.formSubmissionTemplate = (enctype, expectedBuilder) => {
|
||||
function form({
|
||||
name,
|
||||
value,
|
||||
expected,
|
||||
formEncoding = "utf-8",
|
||||
description,
|
||||
}) {
|
||||
const commonParams = {
|
||||
name,
|
||||
value,
|
||||
expectedBuilder: expectedBuilder.bind(null, expected),
|
||||
enctype,
|
||||
formEncoding,
|
||||
};
|
||||
|
||||
// Normal form
|
||||
promise_test(
|
||||
(testCase) =>
|
||||
formSubmissionTest({
|
||||
...commonParams,
|
||||
testCase,
|
||||
}),
|
||||
`${enctype}: ${description} (normal form)`,
|
||||
);
|
||||
|
||||
// formdata event
|
||||
promise_test(
|
||||
(testCase) =>
|
||||
formSubmissionTest({
|
||||
...commonParams,
|
||||
testFormData: true,
|
||||
testCase,
|
||||
}),
|
||||
`${enctype}: ${description} (formdata event)`,
|
||||
);
|
||||
}
|
||||
|
||||
return form;
|
||||
};
|
||||
})();
|
|
@ -0,0 +1,343 @@
|
|||
// META: script=enctypes-helper.js
|
||||
|
||||
// Form submissions in multipart/form-data are also tested in
|
||||
// /FileAPI/file/send-file*
|
||||
|
||||
const form = formSubmissionTemplate(
|
||||
"multipart/form-data",
|
||||
({ name, filename, value }, serialized) => {
|
||||
let headers;
|
||||
if (filename === undefined) {
|
||||
headers = [`Content-Disposition: form-data; name="${name}"`];
|
||||
} else {
|
||||
headers = [
|
||||
`Content-Disposition: form-data; name="${name}"; filename="${filename}"`,
|
||||
"Content-Type: text/plain",
|
||||
];
|
||||
}
|
||||
|
||||
const boundary = serialized.split("\r\n")[0];
|
||||
|
||||
return [
|
||||
boundary,
|
||||
...headers,
|
||||
"",
|
||||
value,
|
||||
boundary + "--",
|
||||
"",
|
||||
].join("\r\n");
|
||||
},
|
||||
);
|
||||
|
||||
form({
|
||||
name: "basic",
|
||||
value: "test",
|
||||
expected: {
|
||||
name: "basic",
|
||||
value: "test",
|
||||
},
|
||||
description: "Basic test",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "basic",
|
||||
value: new File([], "file-test.txt", { type: "text/plain" }),
|
||||
expected: {
|
||||
name: "basic",
|
||||
filename: "file-test.txt",
|
||||
value: "",
|
||||
},
|
||||
description: "Basic File test",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a\0b",
|
||||
value: "c",
|
||||
expected: {
|
||||
name: "a\0b",
|
||||
value: "c",
|
||||
},
|
||||
description: "0x00 in name",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a",
|
||||
value: "b\0c",
|
||||
expected: {
|
||||
name: "a",
|
||||
value: "b\0c",
|
||||
},
|
||||
description: "0x00 in value",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a",
|
||||
value: new File([], "b\0c", { type: "text/plain" }),
|
||||
expected: {
|
||||
name: "a",
|
||||
filename: "b\0c",
|
||||
value: "",
|
||||
},
|
||||
description: "0x00 in filename",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a\nb",
|
||||
value: "c",
|
||||
expected: {
|
||||
name: "a%0D%0Ab",
|
||||
value: "c",
|
||||
},
|
||||
description: "\\n in name",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a\rb",
|
||||
value: "c",
|
||||
expected: {
|
||||
name: "a%0D%0Ab",
|
||||
value: "c",
|
||||
},
|
||||
description: "\\r in name",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a\r\nb",
|
||||
value: "c",
|
||||
expected: {
|
||||
name: "a%0D%0Ab",
|
||||
value: "c",
|
||||
},
|
||||
description: "\\r\\n in name",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a\n\rb",
|
||||
value: "c",
|
||||
expected: {
|
||||
name: "a%0D%0A%0D%0Ab",
|
||||
value: "c",
|
||||
},
|
||||
description: "\\n\\r in name",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a",
|
||||
value: "b\nc",
|
||||
expected: {
|
||||
name: "a",
|
||||
value: "b\r\nc",
|
||||
},
|
||||
description: "\\n in value",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a",
|
||||
value: "b\rc",
|
||||
expected: {
|
||||
name: "a",
|
||||
value: "b\r\nc",
|
||||
},
|
||||
description: "\\r in value",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a",
|
||||
value: "b\r\nc",
|
||||
expected: {
|
||||
name: "a",
|
||||
value: "b\r\nc",
|
||||
},
|
||||
description: "\\r\\n in value",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a",
|
||||
value: "b\n\rc",
|
||||
expected: {
|
||||
name: "a",
|
||||
value: "b\r\n\r\nc",
|
||||
},
|
||||
description: "\\n\\r in value",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a",
|
||||
value: new File([], "b\nc", { type: "text/plain" }),
|
||||
expected: {
|
||||
name: "a",
|
||||
filename: "b%0Ac",
|
||||
value: "",
|
||||
},
|
||||
description: "\\n in filename",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a",
|
||||
value: new File([], "b\rc", { type: "text/plain" }),
|
||||
expected: {
|
||||
name: "a",
|
||||
filename: "b%0Dc",
|
||||
value: "",
|
||||
},
|
||||
description: "\\r in filename",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a",
|
||||
value: new File([], "b\r\nc", { type: "text/plain" }),
|
||||
expected: {
|
||||
name: "a",
|
||||
filename: "b%0D%0Ac",
|
||||
value: "",
|
||||
},
|
||||
description: "\\r\\n in filename",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a",
|
||||
value: new File([], "b\n\rc", { type: "text/plain" }),
|
||||
expected: {
|
||||
name: "a",
|
||||
filename: "b%0A%0Dc",
|
||||
value: "",
|
||||
},
|
||||
description: "\\n\\r in filename",
|
||||
});
|
||||
|
||||
form({
|
||||
name: 'a"b',
|
||||
value: "c",
|
||||
expected: {
|
||||
name: "a%22b",
|
||||
value: "c",
|
||||
},
|
||||
description: "double quote in name",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a",
|
||||
value: 'b"c',
|
||||
expected: {
|
||||
name: "a",
|
||||
value: 'b"c',
|
||||
},
|
||||
description: "double quote in value",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a",
|
||||
value: new File([], 'b"c', { type: "text/plain" }),
|
||||
expected: {
|
||||
name: "a",
|
||||
filename: "b%22c",
|
||||
value: "",
|
||||
},
|
||||
description: "double quote in filename",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a'b",
|
||||
value: "c",
|
||||
expected: {
|
||||
name: "a'b",
|
||||
value: "c",
|
||||
},
|
||||
description: "single quote in name",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a",
|
||||
value: "b'c",
|
||||
expected: {
|
||||
name: "a",
|
||||
value: "b'c",
|
||||
},
|
||||
description: "single quote in value",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a",
|
||||
value: new File([], "b'c", { type: "text/plain" }),
|
||||
expected: {
|
||||
name: "a",
|
||||
filename: "b'c",
|
||||
value: "",
|
||||
},
|
||||
description: "single quote in filename",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a\\b",
|
||||
value: "c",
|
||||
expected: {
|
||||
name: "a\\b",
|
||||
value: "c",
|
||||
},
|
||||
description: "backslash in name",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a",
|
||||
value: "b\\c",
|
||||
expected: {
|
||||
name: "a",
|
||||
value: "b\\c",
|
||||
},
|
||||
description: "backslash in value",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a",
|
||||
value: new File([], "b\\c", { type: "text/plain" }),
|
||||
expected: {
|
||||
name: "a",
|
||||
filename: "b\\c",
|
||||
value: "",
|
||||
},
|
||||
description: "backslash in filename",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "áb",
|
||||
value: "ç",
|
||||
expected: {
|
||||
name: "\xC3\xA1b",
|
||||
value: "\xC3\xA7",
|
||||
},
|
||||
description: "non-ASCII in name and value",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a",
|
||||
value: new File([], "ə.txt", { type: "text/plain" }),
|
||||
expected: {
|
||||
name: "a",
|
||||
filename: "\xC9\x99.txt",
|
||||
value: "",
|
||||
},
|
||||
description: "non-ASCII in filename",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "aəb",
|
||||
value: "c\uFFFDd",
|
||||
formEncoding: "windows-1252",
|
||||
expected: {
|
||||
name: "aəb",
|
||||
value: "c�d",
|
||||
},
|
||||
description: "characters not in encoding in name and value",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "á",
|
||||
value: new File([], "💩", { type: "text/plain" }),
|
||||
formEncoding: "windows-1252",
|
||||
expected: {
|
||||
name: "\xE1",
|
||||
filename: "💩",
|
||||
value: "",
|
||||
},
|
||||
description: "character not in encoding in filename",
|
||||
});
|
|
@ -0,0 +1,218 @@
|
|||
// META: script=enctypes-helper.js
|
||||
|
||||
const form = formSubmissionTemplate(
|
||||
"text/plain",
|
||||
(expected) => expected,
|
||||
);
|
||||
|
||||
form({
|
||||
name: "basic",
|
||||
value: "test",
|
||||
expected: "basic=test\r\n",
|
||||
description: "Basic test",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "basic",
|
||||
value: new File([], "file-test.txt"),
|
||||
expected: "basic=file-test.txt\r\n",
|
||||
description: "Basic File test",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a\0b",
|
||||
value: "c",
|
||||
expected: "a\0b=c\r\n",
|
||||
description: "0x00 in name",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a",
|
||||
value: "b\0c",
|
||||
expected: "a=b\0c\r\n",
|
||||
description: "0x00 in value",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a",
|
||||
value: new File([], "b\0c"),
|
||||
expected: "a=b\0c\r\n",
|
||||
description: "0x00 in filename",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a\nb",
|
||||
value: "c",
|
||||
expected: "a\r\nb=c\r\n",
|
||||
description: "\\n in name",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a\rb",
|
||||
value: "c",
|
||||
expected: "a\r\nb=c\r\n",
|
||||
description: "\\r in name",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a\r\nb",
|
||||
value: "c",
|
||||
expected: "a\r\nb=c\r\n",
|
||||
description: "\\r\\n in name",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a\n\rb",
|
||||
value: "c",
|
||||
expected: "a\r\n\r\nb=c\r\n",
|
||||
description: "\\n\\r in name",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a",
|
||||
value: "b\nc",
|
||||
expected: "a=b\r\nc\r\n",
|
||||
description: "\\n in value",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a",
|
||||
value: "b\rc",
|
||||
expected: "a=b\r\nc\r\n",
|
||||
description: "\\r in value",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a",
|
||||
value: "b\r\nc",
|
||||
expected: "a=b\r\nc\r\n",
|
||||
description: "\\r\\n in value",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a",
|
||||
value: "b\n\rc",
|
||||
expected: "a=b\r\n\r\nc\r\n",
|
||||
description: "\\n\\r in value",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a",
|
||||
value: new File([], "b\nc"),
|
||||
expected: "a=b\r\nc\r\n",
|
||||
description: "\\n in filename",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a",
|
||||
value: new File([], "b\rc"),
|
||||
expected: "a=b\r\nc\r\n",
|
||||
description: "\\r in filename",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a",
|
||||
value: new File([], "b\r\nc"),
|
||||
expected: "a=b\r\nc\r\n",
|
||||
description: "\\r\\n in filename",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a",
|
||||
value: new File([], "b\n\rc"),
|
||||
expected: "a=b\r\n\r\nc\r\n",
|
||||
description: "\\n\\r in filename",
|
||||
});
|
||||
|
||||
form({
|
||||
name: 'a"b',
|
||||
value: "c",
|
||||
expected: 'a"b=c\r\n',
|
||||
description: "double quote in name",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a",
|
||||
value: 'b"c',
|
||||
expected: 'a=b"c\r\n',
|
||||
description: "double quote in value",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a",
|
||||
value: new File([], 'b"c'),
|
||||
expected: 'a=b"c\r\n',
|
||||
description: "double quote in filename",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a'b",
|
||||
value: "c",
|
||||
expected: "a'b=c\r\n",
|
||||
description: "single quote in name",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a",
|
||||
value: "b'c",
|
||||
expected: "a=b'c\r\n",
|
||||
description: "single quote in value",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a",
|
||||
value: new File([], "b'c"),
|
||||
expected: "a=b'c\r\n",
|
||||
description: "single quote in filename",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a\\b",
|
||||
value: "c",
|
||||
expected: "a\\b=c\r\n",
|
||||
description: "backslash in name",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a",
|
||||
value: "b\\c",
|
||||
expected: "a=b\\c\r\n",
|
||||
description: "backslash in value",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a",
|
||||
value: new File([], "b\\c"),
|
||||
expected: "a=b\\c\r\n",
|
||||
description: "backslash in filename",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "áb",
|
||||
value: "ç",
|
||||
expected: "\xC3\xA1b=\xC3\xA7\r\n",
|
||||
description: "non-ASCII in name and value",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a",
|
||||
value: new File([], "ə.txt"),
|
||||
expected: "a=\xC9\x99.txt\r\n",
|
||||
description: "non-ASCII in filename",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "aəb",
|
||||
value: "c\uFFFDd",
|
||||
formEncoding: "windows-1252",
|
||||
expected: "aəb=c�d\r\n",
|
||||
description: "characters not in encoding in name and value",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "á",
|
||||
value: new File([], "💩"),
|
||||
formEncoding: "windows-1252",
|
||||
expected: "\xE1=💩\r\n",
|
||||
description: "character not in encoding in filename",
|
||||
});
|
|
@ -0,0 +1,218 @@
|
|||
// META: script=enctypes-helper.js
|
||||
|
||||
const form = formSubmissionTemplate(
|
||||
"application/x-www-form-urlencoded",
|
||||
(expected) => expected,
|
||||
);
|
||||
|
||||
form({
|
||||
name: "basic",
|
||||
value: "test",
|
||||
expected: "basic=test",
|
||||
description: "Basic test",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "basic",
|
||||
value: new File([], "file-test.txt"),
|
||||
expected: "basic=file-test.txt",
|
||||
description: "Basic File test",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a\0b",
|
||||
value: "c",
|
||||
expected: "a%00b=c",
|
||||
description: "0x00 in name",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a",
|
||||
value: "b\0c",
|
||||
expected: "a=b%00c",
|
||||
description: "0x00 in value",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a",
|
||||
value: new File([], "b\0c"),
|
||||
expected: "a=b%00c",
|
||||
description: "0x00 in filename",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a\nb",
|
||||
value: "c",
|
||||
expected: "a%0D%0Ab=c",
|
||||
description: "\\n in name",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a\rb",
|
||||
value: "c",
|
||||
expected: "a%0D%0Ab=c",
|
||||
description: "\\r in name",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a\r\nb",
|
||||
value: "c",
|
||||
expected: "a%0D%0Ab=c",
|
||||
description: "\\r\\n in name",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a\n\rb",
|
||||
value: "c",
|
||||
expected: "a%0D%0A%0D%0Ab=c",
|
||||
description: "\\n\\r in name",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a",
|
||||
value: "b\nc",
|
||||
expected: "a=b%0D%0Ac",
|
||||
description: "\\n in value",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a",
|
||||
value: "b\rc",
|
||||
expected: "a=b%0D%0Ac",
|
||||
description: "\\r in value",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a",
|
||||
value: "b\r\nc",
|
||||
expected: "a=b%0D%0Ac",
|
||||
description: "\\r\\n in value",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a",
|
||||
value: "b\n\rc",
|
||||
expected: "a=b%0D%0A%0D%0Ac",
|
||||
description: "\\n\\r in value",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a",
|
||||
value: new File([], "b\nc"),
|
||||
expected: "a=b%0D%0Ac",
|
||||
description: "\\n in filename",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a",
|
||||
value: new File([], "b\rc"),
|
||||
expected: "a=b%0D%0Ac",
|
||||
description: "\\r in filename",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a",
|
||||
value: new File([], "b\r\nc"),
|
||||
expected: "a=b%0D%0Ac",
|
||||
description: "\\r\\n in filename",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a",
|
||||
value: new File([], "b\n\rc"),
|
||||
expected: "a=b%0D%0A%0D%0Ac",
|
||||
description: "\\n\\r in filename",
|
||||
});
|
||||
|
||||
form({
|
||||
name: 'a"b',
|
||||
value: "c",
|
||||
expected: "a%22b=c",
|
||||
description: "double quote in name",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a",
|
||||
value: 'b"c',
|
||||
expected: "a=b%22c",
|
||||
description: "double quote in value",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a",
|
||||
value: new File([], 'b"c'),
|
||||
expected: "a=b%22c",
|
||||
description: "double quote in filename",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a'b",
|
||||
value: "c",
|
||||
expected: "a%27b=c",
|
||||
description: "single quote in name",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a",
|
||||
value: "b'c",
|
||||
expected: "a=b%27c",
|
||||
description: "single quote in value",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a",
|
||||
value: new File([], "b'c"),
|
||||
expected: "a=b%27c",
|
||||
description: "single quote in filename",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a\\b",
|
||||
value: "c",
|
||||
expected: "a%5Cb=c",
|
||||
description: "backslash in name",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a",
|
||||
value: "b\\c",
|
||||
expected: "a=b%5Cc",
|
||||
description: "backslash in value",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a",
|
||||
value: new File([], "b\\c"),
|
||||
expected: "a=b%5Cc",
|
||||
description: "backslash in filename",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "áb",
|
||||
value: "ç",
|
||||
expected: "%C3%A1b=%C3%A7",
|
||||
description: "non-ASCII in name and value",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "a",
|
||||
value: new File([], "ə.txt"),
|
||||
expected: "a=%C9%99.txt",
|
||||
description: "non-ASCII in filename",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "aəb",
|
||||
value: "c\uFFFDd",
|
||||
formEncoding: "windows-1252",
|
||||
expected: "a%26%23601%3Bb=c%26%2365533%3Bd",
|
||||
description: "characters not in encoding in name and value",
|
||||
});
|
||||
|
||||
form({
|
||||
name: "á",
|
||||
value: new File([], "💩"),
|
||||
formEncoding: "windows-1252",
|
||||
expected: "%E1=%26%23128169%3B",
|
||||
description: "character not in encoding in filename",
|
||||
});
|
|
@ -133,3 +133,13 @@ test(() => {
|
|||
assert_equals(url.toString(), 'http://www.example.com/?a=b%2Cc&x=y');
|
||||
assert_equals(params.toString(), 'a=b%2Cc&x=y');
|
||||
}, 'URLSearchParams connected to URL');
|
||||
|
||||
test(() => {
|
||||
const url = new URL('http://www.example.com/');
|
||||
const params = url.searchParams;
|
||||
|
||||
params.append('a\nb', 'c\rd');
|
||||
params.append('e\n\rf', 'g\r\nh');
|
||||
|
||||
assert_equals(params.toString(), "a%0Ab=c%0Dd&e%0A%0Df=g%0D%0Ah");
|
||||
}, 'URLSearchParams must not do newline normalization');
|
||||
|
|
Загрузка…
Ссылка в новой задаче