Diff
Modified: trunk/LayoutTests/imported/w3c/ChangeLog (221838 => 221839)
--- trunk/LayoutTests/imported/w3c/ChangeLog 2017-09-10 22:17:59 UTC (rev 221838)
+++ trunk/LayoutTests/imported/w3c/ChangeLog 2017-09-10 22:56:58 UTC (rev 221839)
@@ -1,3 +1,20 @@
+2017-09-09 Sam Weinig <s...@webkit.org>
+
+ Finish off the FormData implementation
+ https://bugs.webkit.org/show_bug.cgi?id=176659
+
+ Reviewed by Darin Adler.
+
+ * web-platform-tests/XMLHttpRequest/FormData-append-expected.txt:
+ * web-platform-tests/XMLHttpRequest/formdata-delete-expected.txt:
+ * web-platform-tests/XMLHttpRequest/formdata-foreach-expected.txt:
+ * web-platform-tests/XMLHttpRequest/formdata-get-expected.txt:
+ * web-platform-tests/XMLHttpRequest/formdata-has-expected.txt:
+ * web-platform-tests/XMLHttpRequest/formdata-set-expected.txt:
+ * web-platform-tests/XMLHttpRequest/interfaces-expected.txt:
+
+ Update results.
+
2017-09-08 Antti Koivisto <an...@apple.com>
Remove support for >> descendant combinator syntax
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/XMLHttpRequest/FormData-append-expected.txt (221838 => 221839)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/XMLHttpRequest/FormData-append-expected.txt 2017-09-10 22:17:59 UTC (rev 221838)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/XMLHttpRequest/FormData-append-expected.txt 2017-09-10 22:56:58 UTC (rev 221839)
@@ -1,16 +1,16 @@
PASS Passing a String object to FormData.append should work.
-FAIL testFormDataAppend1 create_formdata(['key', 'value1']).get is not a function. (In 'create_formdata(['key', 'value1']).get('key')', 'create_formdata(['key', 'value1']).get' is undefined)
-FAIL testFormDataAppend2 create_formdata(['key', 'value2'], ['key', 'value1']).get is not a function. (In 'create_formdata(['key', 'value2'], ['key', 'value1']).get('key')', 'create_formdata(['key', 'value2'], ['key', 'value1']).get' is undefined)
-FAIL testFormDataAppendUndefined1 create_formdata(['key', undefined]).get is not a function. (In 'create_formdata(['key', undefined]).get('key')', 'create_formdata(['key', undefined]).get' is undefined)
-FAIL testFormDataAppendUndefined2 create_formdata(['key', undefined], ['key', 'value1']).get is not a function. (In 'create_formdata(['key', undefined], ['key', 'value1']).get('key')', 'create_formdata(['key', undefined], ['key', 'value1']).get' is undefined)
-FAIL testFormDataAppendNull1 create_formdata(['key', null]).get is not a function. (In 'create_formdata(['key', null]).get('key')', 'create_formdata(['key', null]).get' is undefined)
-FAIL testFormDataAppendNull2 create_formdata(['key', null], ['key', 'value1']).get is not a function. (In 'create_formdata(['key', null], ['key', 'value1']).get('key')', 'create_formdata(['key', null], ['key', 'value1']).get' is undefined)
-FAIL testFormDataAppendToForm1 fd.get is not a function. (In 'fd.get('key')', 'fd.get' is undefined)
-FAIL testFormDataAppendToForm2 fd.get is not a function. (In 'fd.get('key')', 'fd.get' is undefined)
-FAIL testFormDataAppendToFormUndefined1 fd.get is not a function. (In 'fd.get('key')', 'fd.get' is undefined)
-FAIL testFormDataAppendToFormUndefined2 fd.get is not a function. (In 'fd.get('key')', 'fd.get' is undefined)
-FAIL testFormDataAppendToFormNull1 fd.get is not a function. (In 'fd.get('key')', 'fd.get' is undefined)
-FAIL testFormDataAppendToFormNull2 fd.get is not a function. (In 'fd.get('key')', 'fd.get' is undefined)
-FAIL testFormDataAppendEmptyBlob create_formdata(['key', new Blob(), 'blank.txt']).get is not a function. (In 'create_formdata(['key', new Blob(), 'blank.txt']).get('key')', 'create_formdata(['key', new Blob(), 'blank.txt']).get' is undefined)
+PASS testFormDataAppend1
+PASS testFormDataAppend2
+PASS testFormDataAppendUndefined1
+PASS testFormDataAppendUndefined2
+PASS testFormDataAppendNull1
+PASS testFormDataAppendNull2
+PASS testFormDataAppendToForm1
+PASS testFormDataAppendToForm2
+PASS testFormDataAppendToFormUndefined1
+PASS testFormDataAppendToFormUndefined2
+PASS testFormDataAppendToFormNull1
+PASS testFormDataAppendToFormNull2
+PASS testFormDataAppendEmptyBlob
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/XMLHttpRequest/formdata-delete-expected.txt (221838 => 221839)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/XMLHttpRequest/formdata-delete-expected.txt 2017-09-10 22:17:59 UTC (rev 221838)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/XMLHttpRequest/formdata-delete-expected.txt 2017-09-10 22:56:58 UTC (rev 221839)
@@ -1,9 +1,9 @@
-FAIL testFormDataDelete fd.delete is not a function. (In 'fd.delete('key')', 'fd.delete' is undefined)
-FAIL testFormDataDeleteFromForm fd.delete is not a function. (In 'fd.delete('key')', 'fd.delete' is undefined)
-FAIL testFormDataDeleteFromFormNonExistentKey fd.delete is not a function. (In 'fd.delete('nil')', 'fd.delete' is undefined)
-FAIL testFormDataDeleteFromFormOtherKey fd.delete is not a function. (In 'fd.delete('key1')', 'fd.delete' is undefined)
-FAIL testFormDataDeleteFromEmptyForm fd.delete is not a function. (In 'fd.delete('key')', 'fd.delete' is undefined)
-FAIL testFormDataDeleteNonExistentKey fd.delete is not a function. (In 'fd.delete('nil')', 'fd.delete' is undefined)
-FAIL testFormDataDeleteOtherKey fd.delete is not a function. (In 'fd.delete('key1')', 'fd.delete' is undefined)
+PASS testFormDataDelete
+PASS testFormDataDeleteFromForm
+PASS testFormDataDeleteFromFormNonExistentKey
+PASS testFormDataDeleteFromFormOtherKey
+PASS testFormDataDeleteFromEmptyForm
+PASS testFormDataDeleteNonExistentKey
+PASS testFormDataDeleteOtherKey
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/XMLHttpRequest/formdata-foreach-expected.txt (221838 => 221839)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/XMLHttpRequest/formdata-foreach-expected.txt 2017-09-10 22:17:59 UTC (rev 221838)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/XMLHttpRequest/formdata-foreach-expected.txt 2017-09-10 22:56:58 UTC (rev 221839)
@@ -1,4 +1,6 @@
-CONSOLE MESSAGE: line 16: TypeError: fd.delete is not a function. (In 'fd.delete('n2')', 'fd.delete' is undefined)
-FAIL FormData: foreach TypeError: fd.delete is not a function. (In 'fd.delete('n2')', 'fd.delete' is undefined)
+PASS Iterator should return duplicate keys and non-deleted values
+PASS Entries iterator should return duplicate keys and non-deleted values
+PASS Keys iterator should return duplicates
+PASS Values iterator should return non-deleted values
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/XMLHttpRequest/formdata-get-expected.txt (221838 => 221839)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/XMLHttpRequest/formdata-get-expected.txt 2017-09-10 22:17:59 UTC (rev 221838)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/XMLHttpRequest/formdata-get-expected.txt 2017-09-10 22:56:58 UTC (rev 221839)
@@ -1,14 +1,14 @@
-FAIL testFormDataGet create_formdata(['key', 'value1'], ['key', 'value2']).get is not a function. (In 'create_formdata(['key', 'value1'], ['key', 'value2']).get('key')', 'create_formdata(['key', 'value1'], ['key', 'value2']).get' is undefined)
-FAIL testFormDataGetFromForm new FormData(document.getElementById('form')).get is not a function. (In 'new FormData(document.getElementById('form')).get('key')', 'new FormData(document.getElementById('form')).get' is undefined)
-FAIL testFormDataGetFromFormNull new FormData(document.getElementById('form')).get is not a function. (In 'new FormData(document.getElementById('form')).get('nil')', 'new FormData(document.getElementById('form')).get' is undefined)
-FAIL testFormDataGetFromEmptyForm new FormData(document.getElementById('empty-form')).get is not a function. (In 'new FormData(document.getElementById('empty-form')).get('key')', 'new FormData(document.getElementById('empty-form')).get' is undefined)
-FAIL testFormDataGetNull1 create_formdata(['key', 'value1'], ['key', 'value2']).get is not a function. (In 'create_formdata(['key', 'value1'], ['key', 'value2']).get('nil')', 'create_formdata(['key', 'value1'], ['key', 'value2']).get' is undefined)
-FAIL testFormDataGetNull2 create_formdata().get is not a function. (In 'create_formdata().get('key')', 'create_formdata().get' is undefined)
-FAIL testFormDataGetAll create_formdata(['key', 'value1'], ['key', 'value2']).getAll is not a function. (In 'create_formdata(['key', 'value1'], ['key', 'value2']).getAll('key')', 'create_formdata(['key', 'value1'], ['key', 'value2']).getAll' is undefined)
-FAIL testFormDataGetAllEmpty1 create_formdata(['key', 'value1'], ['key', 'value2']).getAll is not a function. (In 'create_formdata(['key', 'value1'], ['key', 'value2']).getAll('nil')', 'create_formdata(['key', 'value1'], ['key', 'value2']).getAll' is undefined)
-FAIL testFormDataGetAllEmpty2 create_formdata().getAll is not a function. (In 'create_formdata().getAll('key')', 'create_formdata().getAll' is undefined)
-FAIL testFormDataGetAllFromForm new FormData(document.getElementById('form')).getAll is not a function. (In 'new FormData(document.getElementById('form')).getAll('key')', 'new FormData(document.getElementById('form')).getAll' is undefined)
-FAIL testFormDataGetAllFromFormNull new FormData(document.getElementById('form')).getAll is not a function. (In 'new FormData(document.getElementById('form')).getAll('nil')', 'new FormData(document.getElementById('form')).getAll' is undefined)
-FAIL testFormDataGetAllFromEmptyForm new FormData(document.getElementById('empty-form')).getAll is not a function. (In 'new FormData(document.getElementById('empty-form')).getAll('key')', 'new FormData(document.getElementById('empty-form')).getAll' is undefined)
+PASS testFormDataGet
+PASS testFormDataGetFromForm
+PASS testFormDataGetFromFormNull
+PASS testFormDataGetFromEmptyForm
+PASS testFormDataGetNull1
+PASS testFormDataGetNull2
+PASS testFormDataGetAll
+PASS testFormDataGetAllEmpty1
+PASS testFormDataGetAllEmpty2
+PASS testFormDataGetAllFromForm
+PASS testFormDataGetAllFromFormNull
+PASS testFormDataGetAllFromEmptyForm
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/XMLHttpRequest/formdata-has-expected.txt (221838 => 221839)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/XMLHttpRequest/formdata-has-expected.txt 2017-09-10 22:17:59 UTC (rev 221838)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/XMLHttpRequest/formdata-has-expected.txt 2017-09-10 22:56:58 UTC (rev 221839)
@@ -1,8 +1,8 @@
-FAIL testFormDataHas create_formdata(['key', 'value1'], ['key', 'value2']).has is not a function. (In 'create_formdata(['key', 'value1'], ['key', 'value2']).has('key')', 'create_formdata(['key', 'value1'], ['key', 'value2']).has' is undefined)
-FAIL testFormDataHasFromForm new FormData(document.getElementById('form')).has is not a function. (In 'new FormData(document.getElementById('form')).has('key')', 'new FormData(document.getElementById('form')).has' is undefined)
-FAIL testFormDataHasFromFormNull new FormData(document.getElementById('form')).has is not a function. (In 'new FormData(document.getElementById('form')).has('nil')', 'new FormData(document.getElementById('form')).has' is undefined)
-FAIL testFormDataHasFromEmptyForm new FormData(document.getElementById('empty-form')).has is not a function. (In 'new FormData(document.getElementById('empty-form')).has('key')', 'new FormData(document.getElementById('empty-form')).has' is undefined)
-FAIL testFormDataHasEmpty1 create_formdata(['key', 'value1'], ['key', 'value2']).has is not a function. (In 'create_formdata(['key', 'value1'], ['key', 'value2']).has('nil')', 'create_formdata(['key', 'value1'], ['key', 'value2']).has' is undefined)
-FAIL testFormDataHasEmpty2 create_formdata().has is not a function. (In 'create_formdata().has('key')', 'create_formdata().has' is undefined)
+PASS testFormDataHas
+PASS testFormDataHasFromForm
+PASS testFormDataHasFromFormNull
+PASS testFormDataHasFromEmptyForm
+PASS testFormDataHasEmpty1
+PASS testFormDataHasEmpty2
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/XMLHttpRequest/formdata-set-expected.txt (221838 => 221839)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/XMLHttpRequest/formdata-set-expected.txt 2017-09-10 22:17:59 UTC (rev 221838)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/XMLHttpRequest/formdata-set-expected.txt 2017-09-10 22:56:58 UTC (rev 221839)
@@ -1,16 +1,16 @@
-FAIL Passing a String object to FormData.set should work fd.set is not a function. (In 'fd.set("name", new String("value"))', 'fd.set' is undefined)
-FAIL testFormDataSet1 undefined is not an object (evaluating 'fd.set.apply')
-FAIL testFormDataSet2 undefined is not an object (evaluating 'fd.set.apply')
-FAIL testFormDataSetUndefined1 undefined is not an object (evaluating 'fd.set.apply')
-FAIL testFormDataSetUndefined2 undefined is not an object (evaluating 'fd.set.apply')
-FAIL testFormDataSetNull1 undefined is not an object (evaluating 'fd.set.apply')
-FAIL testFormDataSetNull2 undefined is not an object (evaluating 'fd.set.apply')
-FAIL testFormDataSetToForm1 fd.set is not a function. (In 'fd.set('key', 'value1')', 'fd.set' is undefined)
-FAIL testFormDataSetToForm2 fd.set is not a function. (In 'fd.set('key', 'value2')', 'fd.set' is undefined)
-FAIL testFormDataSetToFormUndefined1 fd.set is not a function. (In 'fd.set('key', undefined)', 'fd.set' is undefined)
-FAIL testFormDataSetToFormUndefined2 fd.set is not a function. (In 'fd.set('key', undefined)', 'fd.set' is undefined)
-FAIL testFormDataSetToFormNull1 fd.set is not a function. (In 'fd.set('key', null)', 'fd.set' is undefined)
-FAIL testFormDataSetToFormNull2 fd.set is not a function. (In 'fd.set('key', null)', 'fd.set' is undefined)
-FAIL testFormDataSetEmptyBlob fd.set is not a function. (In 'fd.set('key', new Blob([]), 'blank.txt')', 'fd.set' is undefined)
+PASS Passing a String object to FormData.set should work
+PASS testFormDataSet1
+PASS testFormDataSet2
+PASS testFormDataSetUndefined1
+PASS testFormDataSetUndefined2
+PASS testFormDataSetNull1
+PASS testFormDataSetNull2
+PASS testFormDataSetToForm1
+PASS testFormDataSetToForm2
+PASS testFormDataSetToFormUndefined1
+PASS testFormDataSetToFormUndefined2
+PASS testFormDataSetToFormNull1
+PASS testFormDataSetToFormNull2
+PASS testFormDataSetEmptyBlob
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/XMLHttpRequest/interfaces-expected.txt (221838 => 221839)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/XMLHttpRequest/interfaces-expected.txt 2017-09-10 22:17:59 UTC (rev 221838)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/XMLHttpRequest/interfaces-expected.txt 2017-09-10 22:56:58 UTC (rev 221839)
@@ -108,44 +108,44 @@
PASS FormData interface: existence and properties of interface prototype object's "constructor" property
PASS FormData interface: operation append(USVString,Blob,USVString)
PASS FormData interface: operation append(USVString,USVString)
-FAIL FormData interface: operation delete(USVString) assert_own_property: interface prototype object missing non-static operation expected property "delete" missing
-FAIL FormData interface: operation get(USVString) assert_own_property: interface prototype object missing non-static operation expected property "get" missing
-FAIL FormData interface: operation getAll(USVString) assert_own_property: interface prototype object missing non-static operation expected property "getAll" missing
-FAIL FormData interface: operation has(USVString) assert_own_property: interface prototype object missing non-static operation expected property "has" missing
-FAIL FormData interface: operation set(USVString,Blob,USVString) assert_own_property: interface prototype object missing non-static operation expected property "set" missing
-FAIL FormData interface: operation set(USVString,USVString) assert_own_property: interface prototype object missing non-static operation expected property "set" missing
+PASS FormData interface: operation delete(USVString)
+PASS FormData interface: operation get(USVString)
+PASS FormData interface: operation getAll(USVString)
+PASS FormData interface: operation has(USVString)
+PASS FormData interface: operation set(USVString,Blob,USVString)
+PASS FormData interface: operation set(USVString,USVString)
PASS FormData interface: new FormData() must inherit property "append" with the proper type (0)
PASS FormData interface: calling append(USVString,Blob,USVString) on new FormData() with too few arguments must throw TypeError
PASS FormData interface: new FormData() must inherit property "append" with the proper type (1)
PASS FormData interface: calling append(USVString,USVString) on new FormData() with too few arguments must throw TypeError
-FAIL FormData interface: new FormData() must inherit property "delete" with the proper type (2) assert_inherits: property "delete" not found in prototype chain
-FAIL FormData interface: calling delete(USVString) on new FormData() with too few arguments must throw TypeError assert_inherits: property "delete" not found in prototype chain
-FAIL FormData interface: new FormData() must inherit property "get" with the proper type (3) assert_inherits: property "get" not found in prototype chain
-FAIL FormData interface: calling get(USVString) on new FormData() with too few arguments must throw TypeError assert_inherits: property "get" not found in prototype chain
-FAIL FormData interface: new FormData() must inherit property "getAll" with the proper type (4) assert_inherits: property "getAll" not found in prototype chain
-FAIL FormData interface: calling getAll(USVString) on new FormData() with too few arguments must throw TypeError assert_inherits: property "getAll" not found in prototype chain
-FAIL FormData interface: new FormData() must inherit property "has" with the proper type (5) assert_inherits: property "has" not found in prototype chain
-FAIL FormData interface: calling has(USVString) on new FormData() with too few arguments must throw TypeError assert_inherits: property "has" not found in prototype chain
-FAIL FormData interface: new FormData() must inherit property "set" with the proper type (6) assert_inherits: property "set" not found in prototype chain
-FAIL FormData interface: calling set(USVString,Blob,USVString) on new FormData() with too few arguments must throw TypeError assert_inherits: property "set" not found in prototype chain
-FAIL FormData interface: new FormData() must inherit property "set" with the proper type (7) assert_inherits: property "set" not found in prototype chain
-FAIL FormData interface: calling set(USVString,USVString) on new FormData() with too few arguments must throw TypeError assert_inherits: property "set" not found in prototype chain
+PASS FormData interface: new FormData() must inherit property "delete" with the proper type (2)
+PASS FormData interface: calling delete(USVString) on new FormData() with too few arguments must throw TypeError
+PASS FormData interface: new FormData() must inherit property "get" with the proper type (3)
+PASS FormData interface: calling get(USVString) on new FormData() with too few arguments must throw TypeError
+PASS FormData interface: new FormData() must inherit property "getAll" with the proper type (4)
+PASS FormData interface: calling getAll(USVString) on new FormData() with too few arguments must throw TypeError
+PASS FormData interface: new FormData() must inherit property "has" with the proper type (5)
+PASS FormData interface: calling has(USVString) on new FormData() with too few arguments must throw TypeError
+PASS FormData interface: new FormData() must inherit property "set" with the proper type (6)
+PASS FormData interface: calling set(USVString,Blob,USVString) on new FormData() with too few arguments must throw TypeError
+PASS FormData interface: new FormData() must inherit property "set" with the proper type (7)
+PASS FormData interface: calling set(USVString,USVString) on new FormData() with too few arguments must throw TypeError
PASS FormData interface: new FormData(form) must inherit property "append" with the proper type (0)
PASS FormData interface: calling append(USVString,Blob,USVString) on new FormData(form) with too few arguments must throw TypeError
PASS FormData interface: new FormData(form) must inherit property "append" with the proper type (1)
PASS FormData interface: calling append(USVString,USVString) on new FormData(form) with too few arguments must throw TypeError
-FAIL FormData interface: new FormData(form) must inherit property "delete" with the proper type (2) assert_inherits: property "delete" not found in prototype chain
-FAIL FormData interface: calling delete(USVString) on new FormData(form) with too few arguments must throw TypeError assert_inherits: property "delete" not found in prototype chain
-FAIL FormData interface: new FormData(form) must inherit property "get" with the proper type (3) assert_inherits: property "get" not found in prototype chain
-FAIL FormData interface: calling get(USVString) on new FormData(form) with too few arguments must throw TypeError assert_inherits: property "get" not found in prototype chain
-FAIL FormData interface: new FormData(form) must inherit property "getAll" with the proper type (4) assert_inherits: property "getAll" not found in prototype chain
-FAIL FormData interface: calling getAll(USVString) on new FormData(form) with too few arguments must throw TypeError assert_inherits: property "getAll" not found in prototype chain
-FAIL FormData interface: new FormData(form) must inherit property "has" with the proper type (5) assert_inherits: property "has" not found in prototype chain
-FAIL FormData interface: calling has(USVString) on new FormData(form) with too few arguments must throw TypeError assert_inherits: property "has" not found in prototype chain
-FAIL FormData interface: new FormData(form) must inherit property "set" with the proper type (6) assert_inherits: property "set" not found in prototype chain
-FAIL FormData interface: calling set(USVString,Blob,USVString) on new FormData(form) with too few arguments must throw TypeError assert_inherits: property "set" not found in prototype chain
-FAIL FormData interface: new FormData(form) must inherit property "set" with the proper type (7) assert_inherits: property "set" not found in prototype chain
-FAIL FormData interface: calling set(USVString,USVString) on new FormData(form) with too few arguments must throw TypeError assert_inherits: property "set" not found in prototype chain
+PASS FormData interface: new FormData(form) must inherit property "delete" with the proper type (2)
+PASS FormData interface: calling delete(USVString) on new FormData(form) with too few arguments must throw TypeError
+PASS FormData interface: new FormData(form) must inherit property "get" with the proper type (3)
+PASS FormData interface: calling get(USVString) on new FormData(form) with too few arguments must throw TypeError
+PASS FormData interface: new FormData(form) must inherit property "getAll" with the proper type (4)
+PASS FormData interface: calling getAll(USVString) on new FormData(form) with too few arguments must throw TypeError
+PASS FormData interface: new FormData(form) must inherit property "has" with the proper type (5)
+PASS FormData interface: calling has(USVString) on new FormData(form) with too few arguments must throw TypeError
+PASS FormData interface: new FormData(form) must inherit property "set" with the proper type (6)
+PASS FormData interface: calling set(USVString,Blob,USVString) on new FormData(form) with too few arguments must throw TypeError
+PASS FormData interface: new FormData(form) must inherit property "set" with the proper type (7)
+PASS FormData interface: calling set(USVString,USVString) on new FormData(form) with too few arguments must throw TypeError
PASS ProgressEvent interface: existence and properties of interface object
PASS ProgressEvent interface object length
PASS ProgressEvent interface object name
Modified: trunk/Source/WebCore/ChangeLog (221838 => 221839)
--- trunk/Source/WebCore/ChangeLog 2017-09-10 22:17:59 UTC (rev 221838)
+++ trunk/Source/WebCore/ChangeLog 2017-09-10 22:56:58 UTC (rev 221839)
@@ -1,3 +1,86 @@
+2017-09-09 Sam Weinig <s...@webkit.org>
+
+ Finish off the FormData implementation
+ https://bugs.webkit.org/show_bug.cgi?id=176659
+
+ Reviewed by Darin Adler.
+
+ * fileapi/Blob.cpp:
+ * fileapi/Blob.h:
+ * fileapi/File.cpp:
+ * fileapi/File.h:
+
+ Add constructors / create functions for making File objects
+ from an existing Blob or File with an override name.
+
+ * html/DOMFormData.cpp:
+ * html/DOMFormData.h:
+
+ Add missing operations and iterator implementation
+ and bring append up to spec by no ignoring empty names.
+
+ * html/DOMFormData.idl:
+
+ Bring IDL up to spec. Leave its exposure to just the window for
+ now, as FormData currently depends on the Document/Page for replace
+ file generation and therefore cannot operate in a worker.
+
+ * html/FormDataList.cpp:
+ * html/FormDataList.h:
+
+ Changes FormDataList::Item to a String key and Variant<RefPtr<File>, String>
+ data, matching spec concepts more cleanly. Normalization / encoding has also
+ been made lazy, and now does not happen until creating a FormData from the
+ FormDataList.
+
+ Since we now store Files, rather than Blobs, we follow the spec's 'create an
+ entry' algorithm to convert Blobs into Files with the same backing bytes. This
+ was previously done as part of FormData::appendKeyValuePairItems.
+
+ * html/HTMLKeygenElement.cpp:
+ (WebCore::HTMLKeygenElement::appendFormData):
+
+ Remove unnecessary conversion to utf8, the data is base64 encoded, allowing
+ us to remove an overload of appendData that took a CString.
+
+ * inspector/InspectorNetworkAgent.cpp:
+ (WebCore::buildObjectForResourceRequest):
+
+ Update for new signature of FormData::flatten() which now
+ returns a Vector, rather than takes one in.
+
+ * platform/network/FormData.h:
+ * platform/network/FormData.cpp:
+ (WebCore::FormData::FormData):
+ (WebCore::FormData::create):
+ (WebCore::FormData::createMultiPart):
+
+ Cleanup redundancy by using auto.
+
+ (WebCore::FormData::appendKeyValuePairItems):
+
+ Updated to handle new FormDataList item format (e.g. pairs of key / data) allowing
+ us to remove two-by-two iteration. Some complexity was removed around Blobs, as
+ FormDataList now always creates File.
+
+ Since FormDataList no longer eagerly encodes / normalizes the keys and string data
+ values, we now perform those operations here.
+
+ (WebCore::FormData::expandDataStore):
+ (WebCore::appendBlobResolved):
+ (WebCore::FormData::resolveBlobReferences):
+ (WebCore::FormData::generateFiles):
+ (WebCore::FormData::hasGeneratedFiles const):
+ (WebCore::FormData::hasOwnedGeneratedFiles const):
+ (WebCore::FormData::removeGeneratedFilesIfNeeded):
+
+ Adopt auto and modern for-in loops.
+
+ (WebCore::FormData::flatten const):
+ (WebCore::FormData::flattenToString const):
+
+ Update flatten to return a Vector, rather than take it in.
+
2017-09-10 Darin Adler <da...@apple.com>
Refactor Document::updateTitleElement to use traits instead of function pointers
Modified: trunk/Source/WebCore/fileapi/Blob.cpp (221838 => 221839)
--- trunk/Source/WebCore/fileapi/Blob.cpp 2017-09-10 22:17:59 UTC (rev 221838)
+++ trunk/Source/WebCore/fileapi/Blob.cpp 2017-09-10 22:56:58 UTC (rev 221839)
@@ -79,6 +79,14 @@
ThreadableBlobRegistry::registerBlobURL(m_internalURL, { }, { });
}
+Blob::Blob(const Blob& blob)
+ : m_internalURL(BlobURL::createInternalURL())
+ , m_type(blob.type())
+ , m_size(blob.size())
+{
+ ThreadableBlobRegistry::registerBlobURL(m_internalURL, { BlobPart(blob.url()) } , m_type);
+}
+
Blob::Blob(Vector<BlobPartVariant>&& blobPartVariants, const BlobPropertyBag& propertyBag)
: m_internalURL(BlobURL::createInternalURL())
, m_type(normalizedContentType(propertyBag.type))
Modified: trunk/Source/WebCore/fileapi/Blob.h (221838 => 221839)
--- trunk/Source/WebCore/fileapi/Blob.h 2017-09-10 22:17:59 UTC (rev 221838)
+++ trunk/Source/WebCore/fileapi/Blob.h 2017-09-10 22:56:58 UTC (rev 221839)
@@ -98,6 +98,7 @@
protected:
Blob();
+ Blob(const Blob&);
Blob(Vector<BlobPartVariant>&&, const BlobPropertyBag&);
Blob(Vector<uint8_t>&&, const String& contentType);
Modified: trunk/Source/WebCore/fileapi/File.cpp (221838 => 221839)
--- trunk/Source/WebCore/fileapi/File.cpp 2017-09-10 22:17:59 UTC (rev 221838)
+++ trunk/Source/WebCore/fileapi/File.cpp 2017-09-10 22:56:58 UTC (rev 221839)
@@ -85,6 +85,23 @@
{
}
+File::File(const Blob& blob, const String& name)
+ : Blob(blob)
+ , m_name(name)
+{
+ ASSERT(!blob.isFile());
+}
+
+File::File(const File& file, const String& name)
+ : Blob(file)
+ , m_path(file.path())
+ , m_relativePath(file.relativePath())
+ , m_name(!name.isNull() ? name : file.name())
+ , m_overrideLastModifiedDate(file.m_overrideLastModifiedDate)
+ , m_isDirectory(file.isDirectory())
+{
+}
+
double File::lastModified() const
{
if (m_overrideLastModifiedDate)
Modified: trunk/Source/WebCore/fileapi/File.h (221838 => 221839)
--- trunk/Source/WebCore/fileapi/File.h 2017-09-10 22:17:59 UTC (rev 221838)
+++ trunk/Source/WebCore/fileapi/File.h 2017-09-10 22:56:58 UTC (rev 221839)
@@ -65,6 +65,16 @@
return adoptRef(*new File(path, nameOverride));
}
+ static Ref<File> create(const Blob& blob, const String& name)
+ {
+ return adoptRef(*new File(blob, name));
+ }
+
+ static Ref<File> create(const File& file, const String& name)
+ {
+ return adoptRef(*new File(file, name));
+ }
+
static Ref<File> createWithRelativePath(const String& path, const String& relativePath);
bool isFile() const override { return true; }
@@ -87,6 +97,8 @@
WEBCORE_EXPORT explicit File(const String& path);
File(const String& path, const String& nameOverride);
File(Vector<BlobPartVariant>&& blobPartVariants, const String& filename, const PropertyBag&);
+ File(const Blob&, const String& name);
+ File(const File&, const String& name);
File(DeserializationContructor, const String& path, const URL& srcURL, const String& type, const String& name);
Modified: trunk/Source/WebCore/html/DOMFormData.cpp (221838 => 221839)
--- trunk/Source/WebCore/html/DOMFormData.cpp 2017-09-10 22:17:59 UTC (rev 221838)
+++ trunk/Source/WebCore/html/DOMFormData.cpp 2017-09-10 22:56:58 UTC (rev 221839)
@@ -55,14 +55,76 @@
void DOMFormData::append(const String& name, const String& value)
{
- if (!name.isEmpty())
- appendData(name, value);
+ appendData(name, value);
}
void DOMFormData::append(const String& name, Blob& blob, const String& filename)
{
- if (!name.isEmpty())
- appendBlob(name, blob, filename);
+ appendBlob(name, blob, filename);
}
+void DOMFormData::remove(const String& name)
+{
+ m_items.removeAllMatching([&name] (const auto& item) {
+ return item.name == name;
+ });
+}
+
+auto DOMFormData::get(const String& name) -> std::optional<FormDataEntryValue>
+{
+ for (auto& item : m_items) {
+ if (item.name == name)
+ return item.data;
+ }
+
+ return std::nullopt;
+}
+
+auto DOMFormData::getAll(const String& name) -> Vector<FormDataEntryValue>
+{
+ Vector<FormDataEntryValue> result;
+
+ for (auto& item : m_items) {
+ if (item.name == name)
+ result.append(item.data);
+ }
+
+ return result;
+}
+
+bool DOMFormData::has(const String& name)
+{
+ for (auto& item : m_items) {
+ if (item.name == name)
+ return true;
+ }
+
+ return false;
+}
+
+void DOMFormData::set(const String& name, const String& value)
+{
+ setData(name, value);
+}
+
+void DOMFormData::set(const String& name, Blob& blob, const String& filename)
+{
+ setBlob(name, blob, filename);
+}
+
+DOMFormData::Iterator::Iterator(DOMFormData& target)
+ : m_target(target)
+{
+}
+
+std::optional<WTF::KeyValuePair<String, DOMFormData::FormDataEntryValue>> DOMFormData::Iterator::next()
+{
+ auto& items = m_target->items();
+ if (m_index >= items.size())
+ return std::nullopt;
+
+ auto& item = items[m_index++];
+ return WTF::KeyValuePair<String, FormDataEntryValue> { item.name, item.data };
+}
+
} // namespace WebCore
Modified: trunk/Source/WebCore/html/DOMFormData.h (221838 => 221839)
--- trunk/Source/WebCore/html/DOMFormData.h 2017-09-10 22:17:59 UTC (rev 221838)
+++ trunk/Source/WebCore/html/DOMFormData.h 2017-09-10 22:56:58 UTC (rev 221839)
@@ -32,6 +32,7 @@
#include "FormDataList.h"
#include <wtf/Forward.h>
+#include <wtf/Optional.h>
#include <wtf/RefCounted.h>
namespace WebCore {
@@ -40,14 +41,34 @@
class HTMLFormElement;
class TextEncoding;
+// FIXME: Do we need to have separate DOMFormData and FormDataList classes?
class DOMFormData : public FormDataList, public RefCounted<DOMFormData> {
public:
static Ref<DOMFormData> create(HTMLFormElement* form) { return adoptRef(*new DOMFormData(form)); }
static Ref<DOMFormData> create(const TextEncoding& encoding) { return adoptRef(*new DOMFormData(encoding)); }
+ using FormDataEntryValue = Item::Data;
+
void append(const String& name, const String& value);
- void append(const String& name, Blob&, const String& filename = String());
+ void append(const String& name, Blob&, const String& filename = { });
+ void remove(const String& name);
+ std::optional<FormDataEntryValue> get(const String& name);
+ Vector<FormDataEntryValue> getAll(const String& name);
+ bool has(const String& name);
+ void set(const String& name, const String& value);
+ void set(const String& name, Blob&, const String& filename = { });
+ class Iterator {
+ public:
+ explicit Iterator(DOMFormData&);
+ std::optional<WTF::KeyValuePair<String, FormDataEntryValue>> next();
+
+ private:
+ Ref<DOMFormData> m_target;
+ size_t m_index { 0 };
+ };
+ Iterator createIterator() { return Iterator { *this }; }
+
private:
explicit DOMFormData(const TextEncoding&);
explicit DOMFormData(HTMLFormElement*);
Modified: trunk/Source/WebCore/html/DOMFormData.idl (221838 => 221839)
--- trunk/Source/WebCore/html/DOMFormData.idl 2017-09-10 22:17:59 UTC (rev 221838)
+++ trunk/Source/WebCore/html/DOMFormData.idl 2017-09-10 22:56:58 UTC (rev 221839)
@@ -28,6 +28,12 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+typedef (File or USVString) FormDataEntryValue;
+
+// FIXME: Should be Exposed=(Window,Worker) It is not currently possible to do this due to
+// Fetch and XMLHttpRequest expecting to have Document when processing DOMFormData to perform
+// file replacement (https://webkit.org/b/176674).
+
[
Constructor(optional HTMLFormElement? form),
JSGenerateToNativeObject,
@@ -36,6 +42,13 @@
ImplementationLacksVTable,
] interface DOMFormData {
void append(USVString name, USVString value);
- void append(USVString name, Blob value, optional USVString filename);
+ void append(USVString name, Blob blobValue, optional USVString filename);
+ [ImplementedAs=remove] void delete(USVString name);
+ FormDataEntryValue? get(USVString name);
+ sequence<FormDataEntryValue> getAll(USVString name);
+ boolean has(USVString name);
+ void set(USVString name, USVString value);
+ void set(USVString name, Blob blobValue, optional USVString filename);
+
+ iterable<USVString, FormDataEntryValue>;
};
-
Modified: trunk/Source/WebCore/html/FormDataList.cpp (221838 => 221839)
--- trunk/Source/WebCore/html/FormDataList.cpp 2017-09-10 22:17:59 UTC (rev 221838)
+++ trunk/Source/WebCore/html/FormDataList.cpp 2017-09-10 22:56:58 UTC (rev 221839)
@@ -22,29 +22,79 @@
#include "FormDataList.h"
#include "LineEnding.h"
-#include <wtf/text/StringView.h>
+#include <wtf/text/CString.h>
namespace WebCore {
-FormDataList::FormDataList(const TextEncoding& c)
- : m_encoding(c)
+FormDataList::FormDataList(const TextEncoding& encoding)
+ : m_encoding(encoding)
{
}
-void FormDataList::appendString(const String& s)
+CString FormDataList::normalizeString(const String& value) const
{
- CString cstr = m_encoding.encode(s, EntitiesForUnencodables);
- m_items.append(normalizeLineEndingsToCRLF(cstr));
+ return normalizeLineEndingsToCRLF(m_encoding.encode(value, EntitiesForUnencodables));
}
-void FormDataList::appendString(const CString& s)
+// https://xhr.spec.whatwg.org/#create-an-entry
+auto FormDataList::createFileEntry(const String& name, Ref<Blob>&& blob, const String& filename) -> Item
{
- m_items.append(s);
+ if (!blob->isFile())
+ return { name, File::create(blob.get(), filename.isNull() ? ASCIILiteral("blob") : filename) };
+
+ if (!filename.isNull())
+ return { name, File::create(downcast<File>(blob.get()), filename) };
+
+ return { name, static_reference_cast<File>(WTFMove(blob)) };
}
-void FormDataList::appendBlob(Ref<Blob>&& blob, const String& filename)
+void FormDataList::appendData(const String& name, const String& value)
{
- m_items.append(Item(WTFMove(blob), filename));
+ m_items.append({ name, value });
}
-} // namespace
+void FormDataList::appendData(const String& name, int value)
+{
+ m_items.append({ name, String::number(value) });
+}
+
+void FormDataList::appendBlob(const String& name, Ref<Blob>&& blob, const String& filename)
+{
+ m_items.append(createFileEntry(name, WTFMove(blob), filename));
+}
+
+void FormDataList::set(const String& name, Item&& item)
+{
+ std::optional<size_t> initialMatchLocation;
+
+ // Find location of the first item with a matching name.
+ for (size_t i = 0; i < m_items.size(); ++i) {
+ if (name == m_items[i].name) {
+ initialMatchLocation = i;
+ break;
+ }
+ }
+
+ if (initialMatchLocation) {
+ m_items[*initialMatchLocation] = WTFMove(item);
+
+ m_items.removeAllMatching([&name] (const auto& item) {
+ return item.name == name;
+ }, *initialMatchLocation + 1);
+ return;
+ }
+
+ m_items.append(WTFMove(item));
+}
+
+void FormDataList::setData(const String& name, const String& value)
+{
+ set(name, { name, value });
+}
+
+void FormDataList::setBlob(const String& name, Ref<Blob>&& blob, const String& filename)
+{
+ set(name, createFileEntry(name, WTFMove(blob), filename));
+}
+
+}
Modified: trunk/Source/WebCore/html/FormDataList.h (221838 => 221839)
--- trunk/Source/WebCore/html/FormDataList.h 2017-09-10 22:17:59 UTC (rev 221838)
+++ trunk/Source/WebCore/html/FormDataList.h 2017-09-10 22:56:58 UTC (rev 221839)
@@ -20,65 +20,39 @@
#pragma once
-#include "Blob.h"
+#include "File.h"
#include "TextEncoding.h"
#include <wtf/Forward.h>
-#include <wtf/text/CString.h>
+#include <wtf/Variant.h>
namespace WebCore {
class FormDataList {
public:
- class Item {
- public:
- Item() { }
- Item(const WTF::CString& data) : m_data(data) { }
- Item(Ref<Blob>&& blob, const String& filename)
- : m_blob(WTFMove(blob))
- , m_filename(filename)
- { }
+ struct Item {
+ using Data = "" String>;
- const WTF::CString& data() const { return m_data; }
- Blob* blob() const { return m_blob.get(); }
- const String& filename() const { return m_filename; }
-
- private:
- WTF::CString m_data;
- RefPtr<Blob> m_blob;
- String m_filename;
+ String name;
+ Data data;
};
- FormDataList(const TextEncoding&);
+ void appendData(const String& name, const String& value);
+ void appendData(const String& name, int value);
+ void appendBlob(const String& name, Ref<Blob>&&, const String& filename = { });
+ void setData(const String& name, const String& value);
+ void setBlob(const String& name, Ref<Blob>&&, const String& filename = { });
- void appendData(const String& key, const String& value)
- {
- appendString(key);
- appendString(value);
- }
- void appendData(const String& key, const CString& value)
- {
- appendString(key);
- appendString(value);
- }
- void appendData(const String& key, int value)
- {
- appendString(key);
- appendString(String::number(value));
- }
- void appendBlob(const String& key, Ref<Blob>&& blob, const String& filename = String())
- {
- appendString(key);
- appendBlob(WTFMove(blob), filename);
- }
-
const Vector<Item>& items() const { return m_items; }
const TextEncoding& encoding() const { return m_encoding; }
-private:
- void appendString(const CString&);
- void appendString(const String&);
- void appendBlob(Ref<Blob>&&, const String& filename);
+ CString normalizeString(const String&) const;
+protected:
+ FormDataList(const TextEncoding&);
+
+ Item createFileEntry(const String& name, Ref<Blob>&&, const String& filename);
+ void set(const String& name, Item&&);
+
TextEncoding m_encoding;
Vector<Item> m_items;
};
Modified: trunk/Source/WebCore/html/HTMLKeygenElement.cpp (221838 => 221839)
--- trunk/Source/WebCore/html/HTMLKeygenElement.cpp 2017-09-10 22:17:59 UTC (rev 221838)
+++ trunk/Source/WebCore/html/HTMLKeygenElement.cpp 2017-09-10 22:56:58 UTC (rev 221839)
@@ -123,7 +123,7 @@
String value = signedPublicKeyAndChallengeString(shadowSelect()->selectedIndex(), attributeWithoutSynchronization(challengeAttr), document().baseURL());
if (value.isNull())
return false;
- encoded_values.appendData(name(), value.utf8());
+ encoded_values.appendData(name(), value);
return true;
}
Modified: trunk/Source/WebCore/inspector/InspectorNetworkAgent.cpp (221838 => 221839)
--- trunk/Source/WebCore/inspector/InspectorNetworkAgent.cpp 2017-09-10 22:17:59 UTC (rev 221838)
+++ trunk/Source/WebCore/inspector/InspectorNetworkAgent.cpp 2017-09-10 22:56:58 UTC (rev 221839)
@@ -256,8 +256,7 @@
.setHeaders(buildObjectForHeaders(request.httpHeaderFields()))
.release();
if (request.httpBody() && !request.httpBody()->isEmpty()) {
- Vector<char> bytes;
- request.httpBody()->flatten(bytes);
+ auto bytes = request.httpBody()->flatten();
requestObject->setPostData(String::fromUTF8WithLatin1Fallback(bytes.data(), bytes.size()));
}
return requestObject;
Modified: trunk/Source/WebCore/platform/network/FormData.cpp (221838 => 221839)
--- trunk/Source/WebCore/platform/network/FormData.cpp 2017-09-10 22:17:59 UTC (rev 221838)
+++ trunk/Source/WebCore/platform/network/FormData.cpp 2017-09-10 22:56:58 UTC (rev 221839)
@@ -50,7 +50,7 @@
{
// We shouldn't be copying FormData that hasn't already removed its generated files
// but just in case, make sure the new FormData is ready to generate its own files.
- for (FormDataElement& element : m_elements) {
+ for (auto& element : m_elements) {
if (element.m_type == FormDataElement::Type::EncodedFile) {
element.m_generatedFilename = String();
element.m_ownsGeneratedFile = false;
@@ -73,7 +73,7 @@
Ref<FormData> FormData::create(const void* data, size_t size)
{
- Ref<FormData> result = create();
+ auto result = create();
result->appendData(data, size);
return result;
}
@@ -80,7 +80,7 @@
Ref<FormData> FormData::create(const CString& string)
{
- Ref<FormData> result = create();
+ auto result = create();
result->appendData(string.data(), string.length());
return result;
}
@@ -87,7 +87,7 @@
Ref<FormData> FormData::create(const Vector<char>& vector)
{
- Ref<FormData> result = create();
+ auto result = create();
result->appendData(vector.data(), vector.size());
return result;
}
@@ -94,14 +94,14 @@
Ref<FormData> FormData::create(const FormDataList& list, const TextEncoding& encoding, EncodingType encodingType)
{
- Ref<FormData> result = create();
- result->appendKeyValuePairItems(list, encoding, false, 0, encodingType);
+ auto result = create();
+ result->appendKeyValuePairItems(list, encoding, false, nullptr, encodingType);
return result;
}
Ref<FormData> FormData::createMultiPart(const FormDataList& list, const TextEncoding& encoding, Document* document)
{
- Ref<FormData> result = create();
+ auto result = create();
result->appendKeyValuePairItems(list, encoding, true, document);
return result;
}
@@ -188,45 +188,29 @@
m_boundary = FormDataBuilder::generateUniqueBoundaryString();
Vector<char> encodedData;
-
- const Vector<FormDataList::Item>& items = list.items();
- size_t formDataListSize = items.size();
- ASSERT(!(formDataListSize % 2));
- for (size_t i = 0; i < formDataListSize; i += 2) {
- const FormDataList::Item& key = items[i];
- const FormDataList::Item& value = items[i + 1];
+ for (const auto& item : list.items()) {
+ auto normalizedName = list.normalizeString(item.name);
+
if (isMultiPartForm) {
Vector<char> header;
- FormDataBuilder::beginMultiPartHeader(header, m_boundary.data(), key.data());
+ FormDataBuilder::beginMultiPartHeader(header, m_boundary.data(), normalizedName);
bool shouldGenerateFile = false;
- // If the current type is blob, then we also need to include the filename
- if (value.blob()) {
- String name;
- if (is<File>(*value.blob())) {
- File& file = downcast<File>(*value.blob());
- name = file.name();
- // Let the application specify a filename if it's going to generate a replacement file for the upload.
- const String& path = file.path();
- if (!path.isEmpty()) {
- if (Page* page = document->page()) {
- String generatedFileName;
- shouldGenerateFile = page->chrome().client().shouldReplaceWithGeneratedFileForUpload(path, generatedFileName);
- if (shouldGenerateFile)
- name = generatedFileName;
- }
+ if (WTF::holds_alternative<RefPtr<File>>(item.data)) {
+ // If the current type is a file, then we also need to include the filename
+ auto& file = *WTF::get<RefPtr<File>>(item.data);
+ auto name = file.name();
+
+ // Let the application specify a filename if it's going to generate a replacement file for the upload.
+ const auto& path = file.path();
+ if (!path.isEmpty()) {
+ if (Page* page = document->page()) {
+ String generatedFileName;
+ shouldGenerateFile = page->chrome().client().shouldReplaceWithGeneratedFileForUpload(path, generatedFileName);
+ if (shouldGenerateFile)
+ name = generatedFileName;
}
-
- // If a filename is passed in FormData.append(), use it instead of the file blob's name.
- if (!value.filename().isNull())
- name = value.filename();
- } else {
- // For non-file blob, use the filename if it is passed in FormData.append().
- if (!value.filename().isNull())
- name = value.filename();
- else
- name = "blob";
}
// We have to include the filename=".." part in the header, even if the filename is empty
@@ -233,7 +217,7 @@
FormDataBuilder::addFilenameToMultiPartHeader(header, encoding, name);
// Add the content type if available, or "application/octet-stream" otherwise (RFC 1867).
- String contentType = value.blob()->type();
+ auto contentType = file.type();
if (contentType.isEmpty())
contentType = "application/octet-stream";
ASSERT(Blob::isNormalizedContentType(contentType));
@@ -242,22 +226,26 @@
FormDataBuilder::finishMultiPartHeader(header);
- // Append body
appendData(header.data(), header.size());
- if (value.blob()) {
- if (is<File>(*value.blob())) {
- File& file = downcast<File>(*value.blob());
- // Do not add the file if the path is empty.
- if (!file.path().isEmpty())
- appendFile(file.path(), shouldGenerateFile);
- }
+
+ if (WTF::holds_alternative<RefPtr<File>>(item.data)) {
+ auto& file = *WTF::get<RefPtr<File>>(item.data);
+ if (!file.path().isEmpty())
+ appendFile(file.path(), shouldGenerateFile);
else
- appendBlob(value.blob()->url());
- } else
- appendData(value.data().data(), value.data().length());
+ appendBlob(file.url());
+ } else {
+ auto normalizedStringData = list.normalizeString(WTF::get<String>(item.data));
+ appendData(normalizedStringData.data(), normalizedStringData.length());
+ }
+
appendData("\r\n", 2);
- } else
- FormDataBuilder::addKeyValuePairAsFormData(encodedData, key.data(), value.data(), encodingType);
+ } else {
+ ASSERT(WTF::holds_alternative<String>(item.data));
+
+ auto normalizedStringData = list.normalizeString(WTF::get<String>(item.data));
+ FormDataBuilder::addKeyValuePairAsFormData(encodedData, normalizedName, normalizedStringData, encodingType);
+ }
}
if (isMultiPartForm)
@@ -270,29 +258,31 @@
{
m_lengthInBytes = std::nullopt;
if (m_elements.isEmpty() || m_elements.last().m_type != FormDataElement::Type::Data)
- m_elements.append(FormDataElement());
- FormDataElement& e = m_elements.last();
- size_t oldSize = e.m_data.size();
- e.m_data.grow(oldSize + size);
- return e.m_data.data() + oldSize;
+ m_elements.append({ });
+
+ auto& lastElement = m_elements.last();
+ size_t oldSize = lastElement.m_data.size();
+
+ auto newSize = Checked<size_t>(oldSize) + size;
+
+ lastElement.m_data.grow(newSize.unsafeGet());
+ return lastElement.m_data.data() + oldSize;
}
-void FormData::flatten(Vector<char>& data) const
+Vector<char> FormData::flatten() const
{
// Concatenate all the byte arrays, but omit any files.
- data.clear();
- size_t n = m_elements.size();
- for (size_t i = 0; i < n; ++i) {
- const FormDataElement& e = m_elements[i];
- if (e.m_type == FormDataElement::Type::Data)
- data.append(e.m_data.data(), static_cast<size_t>(e.m_data.size()));
+ Vector<char> data;
+ for (auto& element : m_elements) {
+ if (element.m_type == FormDataElement::Type::Data)
+ data.append(element.m_data.data(), static_cast<size_t>(element.m_data.size()));
}
+ return data;
}
String FormData::flattenToString() const
{
- Vector<char> bytes;
- flatten(bytes);
+ auto bytes = flatten();
return Latin1Encoding().decode(reinterpret_cast<const char*>(bytes.data()), bytes.size());
}
@@ -302,6 +292,7 @@
LOG_ERROR("Tried to resolve a blob without a usable registry");
return;
}
+
BlobData* blobData = static_cast<BlobRegistryImpl&>(blobRegistry()).getBlobDataFromURL(url);
if (!blobData) {
LOG_ERROR("Could not get blob data from a registry");
@@ -308,10 +299,7 @@
return;
}
- BlobDataItemList::const_iterator it = blobData->items().begin();
- const BlobDataItemList::const_iterator itend = blobData->items().end();
- for (; it != itend; ++it) {
- const BlobDataItem& blobItem = *it;
+ for (const auto& blobItem : blobData->items()) {
if (blobItem.type() == BlobDataItem::Type::Data) {
ASSERT(blobItem.data().data());
formData->appendData(blobItem.data().data()->data() + static_cast<int>(blobItem.offset()), static_cast<int>(blobItem.length()));
@@ -326,10 +314,8 @@
{
// First check if any blobs needs to be resolved, or we can take the fast path.
bool hasBlob = false;
- Vector<FormDataElement>::const_iterator it = elements().begin();
- const Vector<FormDataElement>::const_iterator itend = elements().end();
- for (; it != itend; ++it) {
- if (it->m_type == FormDataElement::Type::EncodedBlob) {
+ for (auto& element : m_elements) {
+ if (element.m_type == FormDataElement::Type::EncodedBlob) {
hasBlob = true;
break;
}
@@ -339,12 +325,11 @@
return *this;
// Create a copy to append the result into.
- Ref<FormData> newFormData = FormData::create();
+ auto newFormData = FormData::create();
newFormData->setAlwaysStream(alwaysStream());
newFormData->setIdentifier(identifier());
- it = elements().begin();
- for (; it != itend; ++it) {
- const FormDataElement& element = *it;
+
+ for (auto& element : m_elements) {
if (element.m_type == FormDataElement::Type::Data)
newFormData->appendData(element.m_data.data(), element.m_data.size());
else if (element.m_type == FormDataElement::Type::EncodedFile)
@@ -363,7 +348,7 @@
if (!page)
return;
- for (FormDataElement& element : m_elements) {
+ for (auto& element : m_elements) {
if (element.m_type == FormDataElement::Type::EncodedFile && element.m_shouldGenerateFile) {
ASSERT(!element.m_ownsGeneratedFile);
ASSERT(element.m_generatedFilename.isEmpty());
@@ -378,7 +363,7 @@
bool FormData::hasGeneratedFiles() const
{
- for (const FormDataElement& element : m_elements) {
+ for (auto& element : m_elements) {
if (element.m_type == FormDataElement::Type::EncodedFile && !element.m_generatedFilename.isEmpty())
return true;
}
@@ -387,7 +372,7 @@
bool FormData::hasOwnedGeneratedFiles() const
{
- for (const FormDataElement& element : m_elements) {
+ for (auto& element : m_elements) {
if (element.m_type == FormDataElement::Type::EncodedFile && element.m_ownsGeneratedFile) {
ASSERT(!element.m_generatedFilename.isEmpty());
return true;
@@ -398,7 +383,7 @@
void FormData::removeGeneratedFilesIfNeeded()
{
- for (FormDataElement& element : m_elements) {
+ for (auto& element : m_elements) {
if (element.m_type == FormDataElement::Type::EncodedFile && element.m_ownsGeneratedFile) {
ASSERT(!element.m_generatedFilename.isEmpty());
ASSERT(element.m_shouldGenerateFile);
Modified: trunk/Source/WebCore/platform/network/FormData.h (221838 => 221839)
--- trunk/Source/WebCore/platform/network/FormData.h 2017-09-10 22:17:59 UTC (rev 221838)
+++ trunk/Source/WebCore/platform/network/FormData.h 2017-09-10 22:56:58 UTC (rev 221839)
@@ -222,7 +222,7 @@
WEBCORE_EXPORT void appendBlob(const URL& blobURL);
char* expandDataStore(size_t);
- void flatten(Vector<char>&) const; // omits files
+ Vector<char> flatten() const; // omits files
String flattenToString() const; // omits files
// Resolve all blob references so we only have file and data.