Skip to content
Permalink
Browse files
Constructing a FormData from a form can lead to entries with lone sur…
…rogates

https://bugs.webkit.org/show_bug.cgi?id=225299

Patch by Andreu Botella <andreu@andreubotella.com> on 2021-11-30
Reviewed by Chris Dumez.

LayoutTests/imported/w3c:

* web-platform-tests/html/semantics/forms/form-submission-0/form-data-set-usv-expected.txt:

Source/WebCore:

According to the HTML specification, names and non-file values in a form's entry list are
scalar value strings. While this is enforced through WebIDL when the entries are added
through the FormData web API, entries that come directly from form controls can contain lone
surrogates. What's more, when a form payload is created from such an entry list, those lone
surrogates can end up encoded as invalid UTF-8.

Since names and non-file values being scalar value strings is an invariant of entry lists,
this change modifies the createFileEntry function in DOMFormData.cpp to replace lone
surrogates in the entry name, and adds a corresponding createStringEntry function, in order
to ensure that every item of the entry list fulfills this invariant.

Tests: imported/w3c/web-platform-tests/html/semantics/forms/form-submission-0/form-data-set-usv.html

* html/DOMFormData.cpp:
(WebCore::createStringEntry): Added to mirror createFileEntry. Replaces lone surrogates in
the name and value.
(WebCore::createFileEntry): Moved from DOMFormData::createFileEntry, and changed to replace
lone surrogates in the entry name.
(WebCore::DOMFormData::append): Changed to use createStringEntry.
(WebCore::DOMFormData::createFileEntry): Moved to createFileEntry.
* html/DOMFormData.h:


Canonical link: https://commits.webkit.org/244669@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@286310 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
andreubotella authored and webkit-commit-queue committed Nov 30, 2021
1 parent c0dc3d6 commit 40afb84594cdddcefe002a50e8d6bf385042e37e
Showing 5 changed files with 58 additions and 10 deletions.
@@ -1,3 +1,12 @@
2021-11-30 Andreu Botella <andreu@andreubotella.com>

Constructing a FormData from a form can lead to entries with lone surrogates
https://bugs.webkit.org/show_bug.cgi?id=225299

Reviewed by Chris Dumez.

* web-platform-tests/html/semantics/forms/form-submission-0/form-data-set-usv-expected.txt:

2021-11-30 Martin Robinson <mrobinson@webkit.org>

Transition from perspective(500px) to 'none' is probably wrong
@@ -1,5 +1,5 @@


FAIL Strings from form controls should be converted to Unicode scalar values in form submission assert_equals: expected "69 6e 70 75 74 31 ef bf bd 3d 69 6e 70 75 74 31 ef bf bd 0d 0a 69 6e 70 75 74 32 ef bf bd 3d 69 6e 70 75 74 32 ef bf bd 0d 0a 69 6e 70 75 74 33 ef bf bd 3d 69 6e 70 75 74 33 ef bf bd 0d 0a 69 6e 70 75 74 34 ef bf bd 3d 69 6e 70 75 74 34 ef bf bd 0d 0a" but got "69 6e 70 75 74 31 ed b0 81 3d 69 6e 70 75 74 31 ed b0 81 0d 0a 69 6e 70 75 74 32 ed b0 81 3d 69 6e 70 75 74 32 ed b0 81 0d 0a 69 6e 70 75 74 33 ed b0 81 3d 69 6e 70 75 74 33 ed b0 81 0d 0a 69 6e 70 75 74 34 ed b0 81 3d 69 6e 70 75 74 34 ed b0 81 0d 0a"
FAIL Strings from form controls should be converted to Unicode scalar values in FormData assert_equals: expected (string) "input1\ufffd" but got (object) null
PASS Strings from form controls should be converted to Unicode scalar values in form submission
PASS Strings from form controls should be converted to Unicode scalar values in FormData

@@ -1,3 +1,32 @@
2021-11-30 Andreu Botella <andreu@andreubotella.com>

Constructing a FormData from a form can lead to entries with lone surrogates
https://bugs.webkit.org/show_bug.cgi?id=225299

Reviewed by Chris Dumez.

According to the HTML specification, names and non-file values in a form's entry list are
scalar value strings. While this is enforced through WebIDL when the entries are added
through the FormData web API, entries that come directly from form controls can contain lone
surrogates. What's more, when a form payload is created from such an entry list, those lone
surrogates can end up encoded as invalid UTF-8.

Since names and non-file values being scalar value strings is an invariant of entry lists,
this change modifies the createFileEntry function in DOMFormData.cpp to replace lone
surrogates in the entry name, and adds a corresponding createStringEntry function, in order
to ensure that every item of the entry list fulfills this invariant.

Tests: imported/w3c/web-platform-tests/html/semantics/forms/form-submission-0/form-data-set-usv.html

* html/DOMFormData.cpp:
(WebCore::createStringEntry): Added to mirror createFileEntry. Replaces lone surrogates in
the name and value.
(WebCore::createFileEntry): Moved from DOMFormData::createFileEntry, and changed to replace
lone surrogates in the entry name.
(WebCore::DOMFormData::append): Changed to use createStringEntry.
(WebCore::DOMFormData::createFileEntry): Moved to createFileEntry.
* html/DOMFormData.h:

2021-11-30 Gabriel Nava Marino <gnavamarino@apple.com>

Use scriptDisallowedScope in FrameSelection::updateAppearance
@@ -69,21 +69,32 @@ Ref<DOMFormData> DOMFormData::clone() const
return newFormData;
}

// https://xhr.spec.whatwg.org/#create-an-entry
auto DOMFormData::createFileEntry(const String& name, Blob& blob, const String& filename) -> Item
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#create-an-entry
static auto createStringEntry(const String& name, const String& value) -> DOMFormData::Item
{
return {
replaceUnpairedSurrogatesWithReplacementCharacter(String(name)),
replaceUnpairedSurrogatesWithReplacementCharacter(String(value)),
};
}

// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#create-an-entry
static auto createFileEntry(const String& name, Blob& blob, const String& filename) -> DOMFormData::Item
{
auto usvName = replaceUnpairedSurrogatesWithReplacementCharacter(String(name));

if (!blob.isFile())
return { name, File::create(blob.scriptExecutionContext(), blob, filename.isNull() ? "blob"_s : filename) };
return { usvName, File::create(blob.scriptExecutionContext(), blob, filename.isNull() ? "blob"_s : filename) };

if (!filename.isNull())
return { name, File::create(blob.scriptExecutionContext(), downcast<File>(blob), filename) };
return { usvName, File::create(blob.scriptExecutionContext(), downcast<File>(blob), filename) };

return { name, RefPtr<File> { &downcast<File>(blob) } };
return { usvName, RefPtr<File> { &downcast<File>(blob) } };
}

void DOMFormData::append(const String& name, const String& value)
{
m_items.append({ name, value });
m_items.append(createStringEntry(name, value));
}

void DOMFormData::append(const String& name, Blob& blob, const String& filename)
@@ -80,7 +80,6 @@ class DOMFormData : public RefCounted<DOMFormData> {
private:
explicit DOMFormData(const TextEncoding& = UTF8Encoding());

Item createFileEntry(const String& name, Blob&, const String& filename);
void set(const String& name, Item&&);

TextEncoding m_encoding;

0 comments on commit 40afb84

Please sign in to comment.