Changeset 268709 in webkit


Ignore:
Timestamp:
Oct 19, 2020 7:25:16 PM (4 years ago)
Author:
Alexey Shvayka
Message:

[WebIDL] convertRecord() should handle duplicate keys for USVString records
https://bugs.webkit.org/show_bug.cgi?id=217612

Reviewed by Sam Weinig.

LayoutTests/imported/w3c:

  • web-platform-tests/url/urlsearchparams-constructor.any-expected.txt:
  • web-platform-tests/url/urlsearchparams-constructor.any.js:
  • web-platform-tests/url/urlsearchparams-constructor.any.worker-expected.txt:

Source/WebCore:

Before this patch, due to unpaired surrogates replacement in stringToUSVString(),
convertRecord() could append the same key multiple times, violating the spec [1].

This change adds duplicate handling while preserving common case performance,
and aligns WebKit with Blink and Gecko. Since a Proxy object can no longer return
duplicate keys [2], only USVString records needed to be fixed.

Test: imported/w3c/web-platform-tests/url/urlsearchparams-constructor.any.html

[1] https://heycam.github.io/webidl/#es-record (step 4.2.4 + example below)
[2] https://github.com/tc39/ecma262/pull/833

  • bindings/js/JSDOMConvertRecord.h:
Location:
trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r268686 r268709  
     12020-10-19  Alexey Shvayka  <shvaikalesh@gmail.com>
     2
     3        [WebIDL] convertRecord() should handle duplicate keys for USVString records
     4        https://bugs.webkit.org/show_bug.cgi?id=217612
     5
     6        Reviewed by Sam Weinig.
     7
     8        * web-platform-tests/url/urlsearchparams-constructor.any-expected.txt:
     9        * web-platform-tests/url/urlsearchparams-constructor.any.js:
     10        * web-platform-tests/url/urlsearchparams-constructor.any.worker-expected.txt:
     11
    1122020-10-19  Antti Koivisto  <antti@apple.com>
    213
  • trunk/LayoutTests/imported/w3c/web-platform-tests/url/urlsearchparams-constructor.any-expected.txt

    r267647 r268709  
    2323PASS Construct with object with two keys
    2424PASS Construct with array with two keys
     25PASS Construct with 2 unpaired surrogates (no trailing)
     26PASS Construct with 3 unpaired surrogates (no leading)
    2527PASS Construct with object with NULL, non-ASCII, and surrogate keys
    2628PASS Custom [Symbol.iterator]
  • trunk/LayoutTests/imported/w3c/web-platform-tests/url/urlsearchparams-constructor.any.js

    r264197 r268709  
    201201  { "input": {c: "x", a: "?"}, "output": [["c", "x"], ["a", "?"]], "name": "object with two keys" },
    202202  { "input": [["c", "x"], ["a", "?"]], "output": [["c", "x"], ["a", "?"]], "name": "array with two keys" },
     203  { "input": {"\uD835x": "1", "xx": "2", "\uD83Dx": "3"}, "output": [["\uFFFDx", "3"], ["xx", "2"]], "name": "2 unpaired surrogates (no trailing)" },
     204  { "input": {"x\uDC53": "1", "x\uDC5C": "2", "x\uDC65": "3"}, "output": [["x\uFFFD", "3"]], "name": "3 unpaired surrogates (no leading)" },
    203205  { "input": {"a\0b": "42", "c\uD83D": "23", "d\u1234": "foo"}, "output": [["a\0b", "42"], ["c\uFFFD", "23"], ["d\u1234", "foo"]], "name": "object with NULL, non-ASCII, and surrogate keys" }
    204206].forEach((val) => {
  • trunk/LayoutTests/imported/w3c/web-platform-tests/url/urlsearchparams-constructor.any.worker-expected.txt

    r267647 r268709  
    2323PASS Construct with object with two keys
    2424PASS Construct with array with two keys
     25PASS Construct with 2 unpaired surrogates (no trailing)
     26PASS Construct with 3 unpaired surrogates (no leading)
    2527PASS Construct with object with NULL, non-ASCII, and surrogate keys
    2628PASS Custom [Symbol.iterator]
  • trunk/Source/WebCore/ChangeLog

    r268704 r268709  
     12020-10-19  Alexey Shvayka  <shvaikalesh@gmail.com>
     2
     3        [WebIDL] convertRecord() should handle duplicate keys for USVString records
     4        https://bugs.webkit.org/show_bug.cgi?id=217612
     5
     6        Reviewed by Sam Weinig.
     7
     8        Before this patch, due to unpaired surrogates replacement in stringToUSVString(),
     9        convertRecord() could append the same key multiple times, violating the spec [1].
     10
     11        This change adds duplicate handling while preserving common case performance,
     12        and aligns WebKit with Blink and Gecko. Since a Proxy object can no longer return
     13        duplicate keys [2], only USVString records needed to be fixed.
     14
     15        Test: imported/w3c/web-platform-tests/url/urlsearchparams-constructor.any.html
     16
     17        [1] https://heycam.github.io/webidl/#es-record (step 4.2.4 + example below)
     18        [2] https://github.com/tc39/ecma262/pull/833
     19
     20        * bindings/js/JSDOMConvertRecord.h:
     21
    1222020-10-19  Wenson Hsieh  <wenson_hsieh@apple.com>
    223
  • trunk/Source/WebCore/bindings/js/JSDOMConvertRecord.h

    r251425 r268709  
    128128                RETURN_IF_EXCEPTION(scope, { });
    129129               
    130                 // 4. If typedKey is already a key in result, set its value to typedValue.
    131                 // Note: This can happen when O is a proxy object.
    132                 // FIXME: Handle this case.
     130                // 4. Set result[typedKey] to typedValue.
     131                // Note: It's possible that typedKey is already in result if K is USVString and key contains unpaired surrogates.
     132                if constexpr (std::is_same_v<K, IDLUSVString>) {
     133                    if (!typedKey.is8Bit()) {
     134                        auto index = result.findMatching([&](auto& entry) { return entry.key == typedKey; });
     135                        if (index != notFound) {
     136                            result[index].value = typedValue;
     137                            continue;
     138                        }
     139                    }
     140                }
    133141               
    134                 // 5. Otherwise, append to result a mapping (typedKey, typedValue).
    135142                result.append({ typedKey, typedValue });
    136143            }
Note: See TracChangeset for help on using the changeset viewer.