Changeset 203950 in webkit


Ignore:
Timestamp:
Jul 30, 2016 5:29:19 PM (8 years ago)
Author:
Chris Dumez
Message:

Enable strict type checking for Window dictionary members
https://bugs.webkit.org/show_bug.cgi?id=160356

Reviewed by Darin Adler.

LayoutTests/imported/w3c:

Rebaseline W3C test now that one more check is passing.

  • web-platform-tests/dom/events/Event-subclasses-constructors-expected.txt:

Source/WebCore:

Enable strict type checking for Window dictionary members. Technically,
we should do strict type checking of all wrapper types but this patch
focuses on Window because it is common to pass a Window dictionary
member to Event constructors.

By strict type checking, I mean that we should throw a TypeError is
the value is not null/undefined and does not implement the Window
interface:

Firefox and Chrome comply with the specification already.

No new tests, updated / rebaselined existing tests.

  • bindings/js/JSDictionary.cpp:

(WebCore::JSDictionary::convertValue):

LayoutTests:

Update existing tests to reflect behavior change.

  • fast/events/constructors/composition-event-constructor-expected.txt:
  • fast/events/constructors/composition-event-constructor.html:
  • fast/events/constructors/focus-event-constructor-expected.txt:
  • fast/events/constructors/focus-event-constructor.html:
  • fast/events/constructors/keyboard-event-constructor-expected.txt:
  • fast/events/constructors/keyboard-event-constructor.html:
  • fast/events/constructors/mouse-event-constructor.html:
  • fast/events/constructors/ui-event-constructor-expected.txt:
  • fast/events/constructors/ui-event-constructor.html:
  • fast/events/constructors/wheel-event-constructor.html:
  • platform/mac/fast/events/constructors/mouse-event-constructor-expected.txt:
  • platform/mac/fast/events/constructors/wheel-event-constructor-expected.txt:
  • resources/js-test-pre.js:

Add a shouldThrowErrorName() utility function that is similar to shouldThrow()
but only checks the error name instead of the full error message. Checking
only the error name has the benefit of working across browsers and facilitating
refactoring of error messages.

Location:
trunk
Files:
18 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r203949 r203950  
     12016-07-30  Chris Dumez  <cdumez@apple.com>
     2
     3        Enable strict type checking for Window dictionary members
     4        https://bugs.webkit.org/show_bug.cgi?id=160356
     5
     6        Reviewed by Darin Adler.
     7
     8        Update existing tests to reflect behavior change.
     9
     10        * fast/events/constructors/composition-event-constructor-expected.txt:
     11        * fast/events/constructors/composition-event-constructor.html:
     12        * fast/events/constructors/focus-event-constructor-expected.txt:
     13        * fast/events/constructors/focus-event-constructor.html:
     14        * fast/events/constructors/keyboard-event-constructor-expected.txt:
     15        * fast/events/constructors/keyboard-event-constructor.html:
     16        * fast/events/constructors/mouse-event-constructor.html:
     17        * fast/events/constructors/ui-event-constructor-expected.txt:
     18        * fast/events/constructors/ui-event-constructor.html:
     19        * fast/events/constructors/wheel-event-constructor.html:
     20        * platform/mac/fast/events/constructors/mouse-event-constructor-expected.txt:
     21        * platform/mac/fast/events/constructors/wheel-event-constructor-expected.txt:
     22
     23        * resources/js-test-pre.js:
     24        Add a shouldThrowErrorName() utility function that is similar to shouldThrow()
     25        but only checks the error name instead of the full error message. Checking
     26        only the error name has the benefit of working across browsers and facilitating
     27        refactoring of error messages.
     28
    1292016-07-30  Chris Dumez  <cdumez@apple.com>
    230
  • trunk/LayoutTests/fast/events/constructors/composition-event-constructor-expected.txt

    r141386 r203950  
    1515PASS new CompositionEvent('eventType', { view: window }).view is window
    1616PASS new CompositionEvent('eventType', { view: this }).view is this
    17 PASS new CompositionEvent('eventType', { view: testObject }).view is null
    18 PASS new CompositionEvent('eventType', { view: document }).view is null
     17PASS new CompositionEvent('eventType', { view: testObject }).view threw exception TypeError: Dictionary member is not of type Window.
     18PASS new CompositionEvent('eventType', { view: document }).view threw exception TypeError: Dictionary member is not of type Window.
    1919PASS new CompositionEvent('eventType', { view: undefined }).view is null
    2020PASS new CompositionEvent('eventType', { view: null }).view is null
    21 PASS new CompositionEvent('eventType', { view: false }).view is null
    22 PASS new CompositionEvent('eventType', { view: true }).view is null
    23 PASS new CompositionEvent('eventType', { view: '' }).view is null
    24 PASS new CompositionEvent('eventType', { view: 'chocolate' }).view is null
    25 PASS new CompositionEvent('eventType', { view: 12345 }).view is null
    26 PASS new CompositionEvent('eventType', { view: 18446744073709551615 }).view is null
    27 PASS new CompositionEvent('eventType', { view: NaN }).view is null
    28 PASS new CompositionEvent('eventType', { view: {valueOf: function () { return window; } } }).view == window is false
    29 PASS new CompositionEvent('eventType', { get view() { return 123; } }).view is null
     21PASS new CompositionEvent('eventType', { view: false }).view threw exception TypeError: Dictionary member is not of type Window.
     22PASS new CompositionEvent('eventType', { view: true }).view threw exception TypeError: Dictionary member is not of type Window.
     23PASS new CompositionEvent('eventType', { view: '' }).view threw exception TypeError: Dictionary member is not of type Window.
     24PASS new CompositionEvent('eventType', { view: 'chocolate' }).view threw exception TypeError: Dictionary member is not of type Window.
     25PASS new CompositionEvent('eventType', { view: 12345 }).view threw exception TypeError: Dictionary member is not of type Window.
     26PASS new CompositionEvent('eventType', { view: 18446744073709551615 }).view threw exception TypeError: Dictionary member is not of type Window.
     27PASS new CompositionEvent('eventType', { view: NaN }).view threw exception TypeError: Dictionary member is not of type Window.
     28PASS new CompositionEvent('eventType', { view: {valueOf: function () { return window; } } }).view threw exception TypeError: Dictionary member is not of type Window.
     29PASS new CompositionEvent('eventType', { get view() { return 123; } }).view threw exception TypeError: Dictionary member is not of type Window.
    3030PASS new CompositionEvent('eventType', { get view() { throw 'CompositionEvent Error'; } }) threw exception CompositionEvent Error.
    3131PASS new CompositionEvent('eventType', { data: 'koakuma' }).data is "koakuma"
  • trunk/LayoutTests/fast/events/constructors/composition-event-constructor.html

    r155267 r203950  
    3232
    3333// Non-window objects.
    34 shouldBe("new CompositionEvent('eventType', { view: testObject }).view", "null");
    35 shouldBe("new CompositionEvent('eventType', { view: document }).view", "null");
    36 shouldBe("new CompositionEvent('eventType', { view: undefined }).view", "null");
    37 shouldBe("new CompositionEvent('eventType', { view: null }).view", "null");
    38 shouldBe("new CompositionEvent('eventType', { view: false }).view", "null");
    39 shouldBe("new CompositionEvent('eventType', { view: true }).view", "null");
    40 shouldBe("new CompositionEvent('eventType', { view: '' }).view", "null");
    41 shouldBe("new CompositionEvent('eventType', { view: 'chocolate' }).view", "null");
    42 shouldBe("new CompositionEvent('eventType', { view: 12345 }).view", "null");
    43 shouldBe("new CompositionEvent('eventType', { view: 18446744073709551615 }).view", "null");
    44 shouldBe("new CompositionEvent('eventType', { view: NaN }).view", "null");
     34shouldThrowErrorName("new CompositionEvent('eventType', { view: testObject }).view", "TypeError");
     35shouldThrowErrorName("new CompositionEvent('eventType', { view: document }).view", "TypeError");
     36shouldBeNull("new CompositionEvent('eventType', { view: undefined }).view");
     37shouldBeNull("new CompositionEvent('eventType', { view: null }).view");
     38shouldThrowErrorName("new CompositionEvent('eventType', { view: false }).view", "TypeError");
     39shouldThrowErrorName("new CompositionEvent('eventType', { view: true }).view", "TypeError");
     40shouldThrowErrorName("new CompositionEvent('eventType', { view: '' }).view", "TypeError");
     41shouldThrowErrorName("new CompositionEvent('eventType', { view: 'chocolate' }).view", "TypeError");
     42shouldThrowErrorName("new CompositionEvent('eventType', { view: 12345 }).view", "TypeError");
     43shouldThrowErrorName("new CompositionEvent('eventType', { view: 18446744073709551615 }).view", "TypeError");
     44shouldThrowErrorName("new CompositionEvent('eventType', { view: NaN }).view", "TypeError");
    4545// Note that valueOf() is not called, when the left hand side is evaluated.
    46 shouldBeFalse("new CompositionEvent('eventType', { view: {valueOf: function () { return window; } } }).view == window");
    47 shouldBe("new CompositionEvent('eventType', { get view() { return 123; } }).view", "null");
     46shouldThrowErrorName("new CompositionEvent('eventType', { view: {valueOf: function () { return window; } } }).view", "TypeError");
     47shouldThrowErrorName("new CompositionEvent('eventType', { get view() { return 123; } }).view", "TypeError");
    4848shouldThrow("new CompositionEvent('eventType', { get view() { throw 'CompositionEvent Error'; } })");
    4949
  • trunk/LayoutTests/fast/events/constructors/focus-event-constructor-expected.txt

    r142205 r203950  
    1515PASS new FocusEvent('eventType', { view: window }).view is window
    1616PASS new FocusEvent('eventType', { view: this }).view is this
    17 PASS new FocusEvent('eventType', { view: testObject }).view is null
    18 PASS new FocusEvent('eventType', { view: document }).view is null
     17PASS new FocusEvent('eventType', { view: testObject }).view threw exception TypeError: Dictionary member is not of type Window.
     18PASS new FocusEvent('eventType', { view: document }).view threw exception TypeError: Dictionary member is not of type Window.
    1919PASS new FocusEvent('eventType', { view: undefined }).view is null
    2020PASS new FocusEvent('eventType', { view: null }).view is null
    21 PASS new FocusEvent('eventType', { view: false }).view is null
    22 PASS new FocusEvent('eventType', { view: true }).view is null
    23 PASS new FocusEvent('eventType', { view: '' }).view is null
    24 PASS new FocusEvent('eventType', { view: 'chocolate' }).view is null
    25 PASS new FocusEvent('eventType', { view: 12345 }).view is null
    26 PASS new FocusEvent('eventType', { view: 18446744073709551615 }).view is null
    27 PASS new FocusEvent('eventType', { view: NaN }).view is null
    28 PASS new FocusEvent('eventType', { view: {valueOf: function () { return window; } } }).view == window is false
    29 PASS new FocusEvent('eventType', { get view() { return 123; } }).view is null
     21PASS new FocusEvent('eventType', { view: false }).view threw exception TypeError: Dictionary member is not of type Window.
     22PASS new FocusEvent('eventType', { view: true }).view threw exception TypeError: Dictionary member is not of type Window.
     23PASS new FocusEvent('eventType', { view: '' }).view threw exception TypeError: Dictionary member is not of type Window.
     24PASS new FocusEvent('eventType', { view: 'chocolate' }).view threw exception TypeError: Dictionary member is not of type Window.
     25PASS new FocusEvent('eventType', { view: 12345 }).view threw exception TypeError: Dictionary member is not of type Window.
     26PASS new FocusEvent('eventType', { view: 18446744073709551615 }).view threw exception TypeError: Dictionary member is not of type Window.
     27PASS new FocusEvent('eventType', { view: NaN }).view threw exception TypeError: Dictionary member is not of type Window.
     28PASS new FocusEvent('eventType', { view: {valueOf: function () { return window; } } }).view threw exception TypeError: Dictionary member is not of type Window.
     29PASS new FocusEvent('eventType', { get view() { return 123; } }).view threw exception TypeError: Dictionary member is not of type Window.
    3030PASS new FocusEvent('eventType', { get view() { throw 'FocusEvent Error'; } }) threw exception FocusEvent Error.
    3131PASS new FocusEvent('eventType', { relatedTarget: testDiv }).relatedTarget is testDiv
  • trunk/LayoutTests/fast/events/constructors/focus-event-constructor.html

    r155267 r203950  
    3434
    3535// Non-window objects.
    36 shouldBe("new FocusEvent('eventType', { view: testObject }).view", "null");
    37 shouldBe("new FocusEvent('eventType', { view: document }).view", "null");
    38 shouldBe("new FocusEvent('eventType', { view: undefined }).view", "null");
    39 shouldBe("new FocusEvent('eventType', { view: null }).view", "null");
    40 shouldBe("new FocusEvent('eventType', { view: false }).view", "null");
    41 shouldBe("new FocusEvent('eventType', { view: true }).view", "null");
    42 shouldBe("new FocusEvent('eventType', { view: '' }).view", "null");
    43 shouldBe("new FocusEvent('eventType', { view: 'chocolate' }).view", "null");
    44 shouldBe("new FocusEvent('eventType', { view: 12345 }).view", "null");
    45 shouldBe("new FocusEvent('eventType', { view: 18446744073709551615 }).view", "null");
    46 shouldBe("new FocusEvent('eventType', { view: NaN }).view", "null");
     36shouldThrowErrorName("new FocusEvent('eventType', { view: testObject }).view", "TypeError");
     37shouldThrowErrorName("new FocusEvent('eventType', { view: document }).view", "TypeError");
     38shouldBeNull("new FocusEvent('eventType', { view: undefined }).view");
     39shouldBeNull("new FocusEvent('eventType', { view: null }).view");
     40shouldThrowErrorName("new FocusEvent('eventType', { view: false }).view", "TypeError");
     41shouldThrowErrorName("new FocusEvent('eventType', { view: true }).view", "TypeError");
     42shouldThrowErrorName("new FocusEvent('eventType', { view: '' }).view", "TypeError");
     43shouldThrowErrorName("new FocusEvent('eventType', { view: 'chocolate' }).view", "TypeError");
     44shouldThrowErrorName("new FocusEvent('eventType', { view: 12345 }).view", "TypeError");
     45shouldThrowErrorName("new FocusEvent('eventType', { view: 18446744073709551615 }).view", "TypeError");
     46shouldThrowErrorName("new FocusEvent('eventType', { view: NaN }).view", "TypeError");
    4747// Note that valueOf() is not called, when the left hand side is evaluated.
    48 shouldBeFalse("new FocusEvent('eventType', { view: {valueOf: function () { return window; } } }).view == window");
    49 shouldBe("new FocusEvent('eventType', { get view() { return 123; } }).view", "null");
     48shouldThrowErrorName("new FocusEvent('eventType', { view: {valueOf: function () { return window; } } }).view", "TypeError");
     49shouldThrowErrorName("new FocusEvent('eventType', { get view() { return 123; } }).view", "TypeError");
    5050shouldThrow("new FocusEvent('eventType', { get view() { throw 'FocusEvent Error'; } })");
    5151
  • trunk/LayoutTests/fast/events/constructors/keyboard-event-constructor-expected.txt

    r153955 r203950  
    2020PASS new KeyboardEvent('eventType', { view: window }).view is window
    2121PASS new KeyboardEvent('eventType', { view: this }).view is this
    22 PASS new KeyboardEvent('eventType', { view: testObject }).view is null
    23 PASS new KeyboardEvent('eventType', { view: document }).view is null
     22PASS new KeyboardEvent('eventType', { view: testObject }).view threw exception TypeError: Dictionary member is not of type Window.
     23PASS new KeyboardEvent('eventType', { view: document }).view threw exception TypeError: Dictionary member is not of type Window.
    2424PASS new KeyboardEvent('eventType', { view: undefined }).view is null
    2525PASS new KeyboardEvent('eventType', { view: null }).view is null
    26 PASS new KeyboardEvent('eventType', { view: false }).view is null
    27 PASS new KeyboardEvent('eventType', { view: true }).view is null
    28 PASS new KeyboardEvent('eventType', { view: '' }).view is null
    29 PASS new KeyboardEvent('eventType', { view: 'chocolate' }).view is null
    30 PASS new KeyboardEvent('eventType', { view: 12345 }).view is null
    31 PASS new KeyboardEvent('eventType', { view: 18446744073709551615 }).view is null
    32 PASS new KeyboardEvent('eventType', { view: NaN }).view is null
    33 PASS new KeyboardEvent('eventType', { view: {valueOf: function () { return window; } } }).view == window is false
    34 PASS new KeyboardEvent('eventType', { get view() { return 123; } }).view is null
     26PASS new KeyboardEvent('eventType', { view: false }).view threw exception TypeError: Dictionary member is not of type Window.
     27PASS new KeyboardEvent('eventType', { view: true }).view threw exception TypeError: Dictionary member is not of type Window.
     28PASS new KeyboardEvent('eventType', { view: '' }).view threw exception TypeError: Dictionary member is not of type Window.
     29PASS new KeyboardEvent('eventType', { view: 'chocolate' }).view threw exception TypeError: Dictionary member is not of type Window.
     30PASS new KeyboardEvent('eventType', { view: 12345 }).view threw exception TypeError: Dictionary member is not of type Window.
     31PASS new KeyboardEvent('eventType', { view: 18446744073709551615 }).view threw exception TypeError: Dictionary member is not of type Window.
     32PASS new KeyboardEvent('eventType', { view: NaN }).view threw exception TypeError: Dictionary member is not of type Window.
     33PASS new KeyboardEvent('eventType', { view: {valueOf: function () { return window; } } }).view threw exception TypeError: Dictionary member is not of type Window.
     34PASS new KeyboardEvent('eventType', { get view() { return 123; } }).view threw exception TypeError: Dictionary member is not of type Window.
    3535PASS new KeyboardEvent('eventType', { get view() { throw 'KeyboardEvent Error'; } }) threw exception KeyboardEvent Error.
    3636PASS new KeyboardEvent('eventType', { keyIdentifier: 'koakuma' }).keyIdentifier is "koakuma"
  • trunk/LayoutTests/fast/events/constructors/keyboard-event-constructor.html

    r155267 r203950  
    3737
    3838// Non-window objects.
    39 shouldBe("new KeyboardEvent('eventType', { view: testObject }).view", "null");
    40 shouldBe("new KeyboardEvent('eventType', { view: document }).view", "null");
    41 shouldBe("new KeyboardEvent('eventType', { view: undefined }).view", "null");
    42 shouldBe("new KeyboardEvent('eventType', { view: null }).view", "null");
    43 shouldBe("new KeyboardEvent('eventType', { view: false }).view", "null");
    44 shouldBe("new KeyboardEvent('eventType', { view: true }).view", "null");
    45 shouldBe("new KeyboardEvent('eventType', { view: '' }).view", "null");
    46 shouldBe("new KeyboardEvent('eventType', { view: 'chocolate' }).view", "null");
    47 shouldBe("new KeyboardEvent('eventType', { view: 12345 }).view", "null");
    48 shouldBe("new KeyboardEvent('eventType', { view: 18446744073709551615 }).view", "null");
    49 shouldBe("new KeyboardEvent('eventType', { view: NaN }).view", "null");
     39shouldThrowErrorName("new KeyboardEvent('eventType', { view: testObject }).view", "TypeError");
     40shouldThrowErrorName("new KeyboardEvent('eventType', { view: document }).view", "TypeError");
     41shouldBeNull("new KeyboardEvent('eventType', { view: undefined }).view");
     42shouldBeNull("new KeyboardEvent('eventType', { view: null }).view");
     43shouldThrowErrorName("new KeyboardEvent('eventType', { view: false }).view", "TypeError");
     44shouldThrowErrorName("new KeyboardEvent('eventType', { view: true }).view", "TypeError");
     45shouldThrowErrorName("new KeyboardEvent('eventType', { view: '' }).view", "TypeError");
     46shouldThrowErrorName("new KeyboardEvent('eventType', { view: 'chocolate' }).view", "TypeError");
     47shouldThrowErrorName("new KeyboardEvent('eventType', { view: 12345 }).view", "TypeError");
     48shouldThrowErrorName("new KeyboardEvent('eventType', { view: 18446744073709551615 }).view", "TypeError");
     49shouldThrowErrorName("new KeyboardEvent('eventType', { view: NaN }).view", "TypeError");
    5050// Note that valueOf() is not called, when the left hand side is evaluated.
    51 shouldBeFalse("new KeyboardEvent('eventType', { view: {valueOf: function () { return window; } } }).view == window");
    52 shouldBe("new KeyboardEvent('eventType', { get view() { return 123; } }).view", "null");
     51shouldThrowErrorName("new KeyboardEvent('eventType', { view: {valueOf: function () { return window; } } }).view", "TypeError");
     52shouldThrowErrorName("new KeyboardEvent('eventType', { get view() { return 123; } }).view", "TypeError");
    5353shouldThrow("new KeyboardEvent('eventType', { get view() { throw 'KeyboardEvent Error'; } })");
    5454
  • trunk/LayoutTests/fast/events/constructors/mouse-event-constructor.html

    r155267 r203950  
    4343
    4444// Non-window objects.
    45 shouldBe("new MouseEvent('eventType', { view: testObject }).view", "null");
    46 shouldBe("new MouseEvent('eventType', { view: document }).view", "null");
    47 shouldBe("new MouseEvent('eventType', { view: undefined }).view", "null");
    48 shouldBe("new MouseEvent('eventType', { view: null }).view", "null");
    49 shouldBe("new MouseEvent('eventType', { view: false }).view", "null");
    50 shouldBe("new MouseEvent('eventType', { view: true }).view", "null");
    51 shouldBe("new MouseEvent('eventType', { view: '' }).view", "null");
    52 shouldBe("new MouseEvent('eventType', { view: 'chocolate' }).view", "null");
    53 shouldBe("new MouseEvent('eventType', { view: 12345 }).view", "null");
    54 shouldBe("new MouseEvent('eventType', { view: 18446744073709551615 }).view", "null");
    55 shouldBe("new MouseEvent('eventType', { view: NaN }).view", "null");
     45shouldThrowErrorName("new MouseEvent('eventType', { view: testObject }).view", "TypeError");
     46shouldThrowErrorName("new MouseEvent('eventType', { view: document }).view", "TypeError");
     47shouldBeNull("new MouseEvent('eventType', { view: undefined }).view");
     48shouldBeNull("new MouseEvent('eventType', { view: null }).view");
     49shouldThrowErrorName("new MouseEvent('eventType', { view: false }).view", "TypeError");
     50shouldThrowErrorName("new MouseEvent('eventType', { view: true }).view", "TypeError");
     51shouldThrowErrorName("new MouseEvent('eventType', { view: '' }).view", "TypeError");
     52shouldThrowErrorName("new MouseEvent('eventType', { view: 'chocolate' }).view", "TypeError");
     53shouldThrowErrorName("new MouseEvent('eventType', { view: 12345 }).view", "TypeError");
     54shouldThrowErrorName("new MouseEvent('eventType', { view: 18446744073709551615 }).view", "TypeError");
     55shouldThrowErrorName("new MouseEvent('eventType', { view: NaN }).view", "TypeError");
    5656// Note that valueOf() is not called, when the left hand side is evaluated.
    57 shouldBeFalse("new MouseEvent('eventType', { view: {valueOf: function () { return window; } } }).view == window");
    58 shouldBe("new MouseEvent('eventType', { get view() { return 123; } }).view", "null");
     57shouldThrowErrorName("new MouseEvent('eventType', { view: {valueOf: function () { return window; } } }).view", "TypeError");
     58shouldThrowErrorName("new MouseEvent('eventType', { get view() { return 123; } }).view", "TypeError");
    5959shouldThrow("new MouseEvent('eventType', { get view() { throw 'MouseEvent Error'; } })");
    6060
  • trunk/LayoutTests/fast/events/constructors/ui-event-constructor-expected.txt

    r140493 r203950  
    1414PASS new UIEvent('eventType', { view: window }).view is window
    1515PASS new UIEvent('eventType', { view: this }).view is this
    16 PASS new UIEvent('eventType', { view: testObject }).view is null
    17 PASS new UIEvent('eventType', { view: document }).view is null
     16PASS new UIEvent('eventType', { view: testObject }).view threw exception TypeError: Dictionary member is not of type Window.
     17PASS new UIEvent('eventType', { view: document }).view threw exception TypeError: Dictionary member is not of type Window.
    1818PASS new UIEvent('eventType', { view: undefined }).view is null
    1919PASS new UIEvent('eventType', { view: null }).view is null
    20 PASS new UIEvent('eventType', { view: false }).view is null
    21 PASS new UIEvent('eventType', { view: true }).view is null
    22 PASS new UIEvent('eventType', { view: '' }).view is null
    23 PASS new UIEvent('eventType', { view: 'chocolate' }).view is null
    24 PASS new UIEvent('eventType', { view: 12345 }).view is null
    25 PASS new UIEvent('eventType', { view: 18446744073709551615 }).view is null
    26 PASS new UIEvent('eventType', { view: NaN }).view is null
    27 PASS new UIEvent('eventType', { view: {valueOf: function () { return window; } } }).view == window is false
    28 PASS new UIEvent('eventType', { get view() { return 123; } }).view is null
     20PASS new UIEvent('eventType', { view: false }).view threw exception TypeError: Dictionary member is not of type Window.
     21PASS new UIEvent('eventType', { view: true }).view threw exception TypeError: Dictionary member is not of type Window.
     22PASS new UIEvent('eventType', { view: '' }).view threw exception TypeError: Dictionary member is not of type Window.
     23PASS new UIEvent('eventType', { view: 'chocolate' }).view threw exception TypeError: Dictionary member is not of type Window.
     24PASS new UIEvent('eventType', { view: 12345 }).view threw exception TypeError: Dictionary member is not of type Window.
     25PASS new UIEvent('eventType', { view: 18446744073709551615 }).view threw exception TypeError: Dictionary member is not of type Window.
     26PASS new UIEvent('eventType', { view: NaN }).view threw exception TypeError: Dictionary member is not of type Window.
     27PASS new UIEvent('eventType', { view: {valueOf: function () { return window; } } }).view threw exception TypeError: Dictionary member is not of type Window.
     28PASS new UIEvent('eventType', { get view() { return 123; } }).view threw exception TypeError: Dictionary member is not of type Window.
    2929PASS new UIEvent('eventType', { get view() { throw 'UIEvent Error'; } }) threw exception UIEvent Error.
    3030PASS new UIEvent('eventType', { detail: 0 }).detail is 0
  • trunk/LayoutTests/fast/events/constructors/ui-event-constructor.html

    r155267 r203950  
    3131
    3232// Non-window objects.
    33 shouldBe("new UIEvent('eventType', { view: testObject }).view", "null");
    34 shouldBe("new UIEvent('eventType', { view: document }).view", "null");
    35 shouldBe("new UIEvent('eventType', { view: undefined }).view", "null");
    36 shouldBe("new UIEvent('eventType', { view: null }).view", "null");
    37 shouldBe("new UIEvent('eventType', { view: false }).view", "null");
    38 shouldBe("new UIEvent('eventType', { view: true }).view", "null");
    39 shouldBe("new UIEvent('eventType', { view: '' }).view", "null");
    40 shouldBe("new UIEvent('eventType', { view: 'chocolate' }).view", "null");
    41 shouldBe("new UIEvent('eventType', { view: 12345 }).view", "null");
    42 shouldBe("new UIEvent('eventType', { view: 18446744073709551615 }).view", "null");
    43 shouldBe("new UIEvent('eventType', { view: NaN }).view", "null");
     33shouldThrowErrorName("new UIEvent('eventType', { view: testObject }).view", "TypeError");
     34shouldThrowErrorName("new UIEvent('eventType', { view: document }).view", "TypeError");
     35shouldBeNull("new UIEvent('eventType', { view: undefined }).view");
     36shouldBeNull("new UIEvent('eventType', { view: null }).view");
     37shouldThrowErrorName("new UIEvent('eventType', { view: false }).view", "TypeError");
     38shouldThrowErrorName("new UIEvent('eventType', { view: true }).view", "TypeError");
     39shouldThrowErrorName("new UIEvent('eventType', { view: '' }).view", "TypeError");
     40shouldThrowErrorName("new UIEvent('eventType', { view: 'chocolate' }).view", "TypeError");
     41shouldThrowErrorName("new UIEvent('eventType', { view: 12345 }).view", "TypeError");
     42shouldThrowErrorName("new UIEvent('eventType', { view: 18446744073709551615 }).view", "TypeError");
     43shouldThrowErrorName("new UIEvent('eventType', { view: NaN }).view", "TypeError");
    4444// Note that valueOf() is not called, when the left hand side is evaluated.
    45 shouldBeFalse("new UIEvent('eventType', { view: {valueOf: function () { return window; } } }).view == window");
    46 shouldBe("new UIEvent('eventType', { get view() { return 123; } }).view", "null");
     45shouldThrowErrorName("new UIEvent('eventType', { view: {valueOf: function () { return window; } } }).view", "TypeError");
     46shouldThrowErrorName("new UIEvent('eventType', { get view() { return 123; } }).view", "TypeError");
    4747shouldThrow("new UIEvent('eventType', { get view() { throw 'UIEvent Error'; } })");
    4848
  • trunk/LayoutTests/fast/events/constructors/wheel-event-constructor.html

    r155267 r203950  
    4646
    4747// Non-window objects.
    48 shouldBe("new WheelEvent('eventType', { view: testObject }).view", "null");
    49 shouldBe("new WheelEvent('eventType', { view: document }).view", "null");
    50 shouldBe("new WheelEvent('eventType', { view: undefined }).view", "null");
    51 shouldBe("new WheelEvent('eventType', { view: null }).view", "null");
    52 shouldBe("new WheelEvent('eventType', { view: false }).view", "null");
    53 shouldBe("new WheelEvent('eventType', { view: true }).view", "null");
    54 shouldBe("new WheelEvent('eventType', { view: '' }).view", "null");
    55 shouldBe("new WheelEvent('eventType', { view: 'chocolate' }).view", "null");
    56 shouldBe("new WheelEvent('eventType', { view: 12345 }).view", "null");
    57 shouldBe("new WheelEvent('eventType', { view: 18446744073709551615 }).view", "null");
    58 shouldBe("new WheelEvent('eventType', { view: NaN }).view", "null");
     48shouldThrowErrorName("new WheelEvent('eventType', { view: testObject }).view", "TypeError");
     49shouldThrowErrorName("new WheelEvent('eventType', { view: document }).view", "TypeError");
     50shouldBeNull("new WheelEvent('eventType', { view: undefined }).view");
     51shouldBeNull("new WheelEvent('eventType', { view: null }).view");
     52shouldThrowErrorName("new WheelEvent('eventType', { view: false }).view", "TypeError");
     53shouldThrowErrorName("new WheelEvent('eventType', { view: true }).view", "TypeError");
     54shouldThrowErrorName("new WheelEvent('eventType', { view: '' }).view", "TypeError");
     55shouldThrowErrorName("new WheelEvent('eventType', { view: 'chocolate' }).view", "TypeError");
     56shouldThrowErrorName("new WheelEvent('eventType', { view: 12345 }).view", "TypeError");
     57shouldThrowErrorName("new WheelEvent('eventType', { view: 18446744073709551615 }).view", "TypeError");
     58shouldThrowErrorName("new WheelEvent('eventType', { view: NaN }).view", "TypeError");
    5959// Note that valueOf() is not called, when the left hand side is evaluated.
    60 shouldBeFalse("new WheelEvent('eventType', { view: {valueOf: function () { return window; } } }).view == window");
    61 shouldBe("new WheelEvent('eventType', { get view() { return 123; } }).view", "null");
     60shouldThrowErrorName("new WheelEvent('eventType', { view: {valueOf: function () { return window; } } }).view", "TypeError");
     61shouldThrowErrorName("new WheelEvent('eventType', { get view() { return 123; } }).view", "TypeError");
    6262shouldThrow("new WheelEvent('eventType', { get view() { throw 'WheelEvent Error'; } })");
    6363
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r203941 r203950  
     12016-07-30  Chris Dumez  <cdumez@apple.com>
     2
     3        Enable strict type checking for Window dictionary members
     4        https://bugs.webkit.org/show_bug.cgi?id=160356
     5
     6        Reviewed by Darin Adler.
     7
     8        Rebaseline W3C test now that one more check is passing.
     9
     10        * web-platform-tests/dom/events/Event-subclasses-constructors-expected.txt:
     11
    1122016-07-30  Chris Dumez  <cdumez@apple.com>
    213
  • trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-subclasses-constructors-expected.txt

    r203164 r203950  
    4242PASS CompositionEvent constructor (argument with default values)
    4343PASS CompositionEvent constructor (argument with non-default values)
    44 FAIL UIEvent constructor (view argument with wrong type) assert_throws: function "function () {
    45     new UIEvent("x", { view: 7 })
    46   }" did not throw
     44PASS UIEvent constructor (view argument with wrong type)
    4745
  • trunk/LayoutTests/platform/mac/fast/events/constructors/mouse-event-constructor-expected.txt

    r174745 r203950  
    2424PASS new MouseEvent('eventType', { view: window }).view is window
    2525PASS new MouseEvent('eventType', { view: this }).view is this
    26 PASS new MouseEvent('eventType', { view: testObject }).view is null
    27 PASS new MouseEvent('eventType', { view: document }).view is null
     26PASS new MouseEvent('eventType', { view: testObject }).view threw exception TypeError: Dictionary member is not of type Window.
     27PASS new MouseEvent('eventType', { view: document }).view threw exception TypeError: Dictionary member is not of type Window.
    2828PASS new MouseEvent('eventType', { view: undefined }).view is null
    2929PASS new MouseEvent('eventType', { view: null }).view is null
    30 PASS new MouseEvent('eventType', { view: false }).view is null
    31 PASS new MouseEvent('eventType', { view: true }).view is null
    32 PASS new MouseEvent('eventType', { view: '' }).view is null
    33 PASS new MouseEvent('eventType', { view: 'chocolate' }).view is null
    34 PASS new MouseEvent('eventType', { view: 12345 }).view is null
    35 PASS new MouseEvent('eventType', { view: 18446744073709551615 }).view is null
    36 PASS new MouseEvent('eventType', { view: NaN }).view is null
    37 PASS new MouseEvent('eventType', { view: {valueOf: function () { return window; } } }).view == window is false
    38 PASS new MouseEvent('eventType', { get view() { return 123; } }).view is null
     30PASS new MouseEvent('eventType', { view: false }).view threw exception TypeError: Dictionary member is not of type Window.
     31PASS new MouseEvent('eventType', { view: true }).view threw exception TypeError: Dictionary member is not of type Window.
     32PASS new MouseEvent('eventType', { view: '' }).view threw exception TypeError: Dictionary member is not of type Window.
     33PASS new MouseEvent('eventType', { view: 'chocolate' }).view threw exception TypeError: Dictionary member is not of type Window.
     34PASS new MouseEvent('eventType', { view: 12345 }).view threw exception TypeError: Dictionary member is not of type Window.
     35PASS new MouseEvent('eventType', { view: 18446744073709551615 }).view threw exception TypeError: Dictionary member is not of type Window.
     36PASS new MouseEvent('eventType', { view: NaN }).view threw exception TypeError: Dictionary member is not of type Window.
     37PASS new MouseEvent('eventType', { view: {valueOf: function () { return window; } } }).view threw exception TypeError: Dictionary member is not of type Window.
     38PASS new MouseEvent('eventType', { get view() { return 123; } }).view threw exception TypeError: Dictionary member is not of type Window.
    3939PASS new MouseEvent('eventType', { get view() { throw 'MouseEvent Error'; } }) threw exception MouseEvent Error.
    4040PASS new MouseEvent('eventType', { detail: 0 }).detail is 0
  • trunk/LayoutTests/platform/mac/fast/events/constructors/wheel-event-constructor-expected.txt

    r174745 r203950  
    2727PASS new WheelEvent('eventType', { view: window }).view is window
    2828PASS new WheelEvent('eventType', { view: this }).view is this
    29 PASS new WheelEvent('eventType', { view: testObject }).view is null
    30 PASS new WheelEvent('eventType', { view: document }).view is null
     29PASS new WheelEvent('eventType', { view: testObject }).view threw exception TypeError: Dictionary member is not of type Window.
     30PASS new WheelEvent('eventType', { view: document }).view threw exception TypeError: Dictionary member is not of type Window.
    3131PASS new WheelEvent('eventType', { view: undefined }).view is null
    3232PASS new WheelEvent('eventType', { view: null }).view is null
    33 PASS new WheelEvent('eventType', { view: false }).view is null
    34 PASS new WheelEvent('eventType', { view: true }).view is null
    35 PASS new WheelEvent('eventType', { view: '' }).view is null
    36 PASS new WheelEvent('eventType', { view: 'chocolate' }).view is null
    37 PASS new WheelEvent('eventType', { view: 12345 }).view is null
    38 PASS new WheelEvent('eventType', { view: 18446744073709551615 }).view is null
    39 PASS new WheelEvent('eventType', { view: NaN }).view is null
    40 PASS new WheelEvent('eventType', { view: {valueOf: function () { return window; } } }).view == window is false
    41 PASS new WheelEvent('eventType', { get view() { return 123; } }).view is null
     33PASS new WheelEvent('eventType', { view: false }).view threw exception TypeError: Dictionary member is not of type Window.
     34PASS new WheelEvent('eventType', { view: true }).view threw exception TypeError: Dictionary member is not of type Window.
     35PASS new WheelEvent('eventType', { view: '' }).view threw exception TypeError: Dictionary member is not of type Window.
     36PASS new WheelEvent('eventType', { view: 'chocolate' }).view threw exception TypeError: Dictionary member is not of type Window.
     37PASS new WheelEvent('eventType', { view: 12345 }).view threw exception TypeError: Dictionary member is not of type Window.
     38PASS new WheelEvent('eventType', { view: 18446744073709551615 }).view threw exception TypeError: Dictionary member is not of type Window.
     39PASS new WheelEvent('eventType', { view: NaN }).view threw exception TypeError: Dictionary member is not of type Window.
     40PASS new WheelEvent('eventType', { view: {valueOf: function () { return window; } } }).view threw exception TypeError: Dictionary member is not of type Window.
     41PASS new WheelEvent('eventType', { get view() { return 123; } }).view threw exception TypeError: Dictionary member is not of type Window.
    4242PASS new WheelEvent('eventType', { get view() { throw 'WheelEvent Error'; } }) threw exception WheelEvent Error.
    4343PASS new WheelEvent('eventType', { detail: 0 }).detail is 0
  • trunk/LayoutTests/resources/js-test-pre.js

    r202609 r203950  
    616616    else
    617617        testFailed((_message ? _message : _a) + " should throw " + (typeof _e == "undefined" ? "an exception" : _ev) + ". Was " + _av + ".");
     618}
     619
     620function shouldThrowErrorName(_a, _name)
     621{
     622    var _exception;
     623    try {
     624        typeof _a == "function" ? _a() : eval(_a);
     625    } catch (e) {
     626        _exception = e;
     627    }
     628
     629    if (_exception) {
     630        if (_exception.name == _name)
     631            testPassed(_a + " threw exception " + _exception + ".");
     632        else
     633            testFailed(_a + " should throw a " + _name + ". Threw a " + _exception.name + ".");
     634    } else
     635        testFailed(_a + " should throw a " + _name + ". Did not throw.");
    618636}
    619637
  • trunk/Source/WebCore/ChangeLog

    r203949 r203950  
     12016-07-30  Chris Dumez  <cdumez@apple.com>
     2
     3        Enable strict type checking for Window dictionary members
     4        https://bugs.webkit.org/show_bug.cgi?id=160356
     5
     6        Reviewed by Darin Adler.
     7
     8        Enable strict type checking for Window dictionary members. Technically,
     9        we should do strict type checking of all wrapper types but this patch
     10        focuses on Window because it is common to pass a Window dictionary
     11        member to Event constructors.
     12
     13        By strict type checking, I mean that we should throw a TypeError is
     14        the value is not null/undefined and does not implement the Window
     15        interface:
     16        - http://heycam.github.io/webidl/#es-interface
     17
     18        Firefox and Chrome comply with the specification already.
     19
     20        No new tests, updated / rebaselined existing tests.
     21
     22        * bindings/js/JSDictionary.cpp:
     23        (WebCore::JSDictionary::convertValue):
     24
    1252016-07-30  Chris Dumez  <cdumez@apple.com>
    226
  • trunk/Source/WebCore/bindings/js/JSDictionary.cpp

    r203065 r203950  
    179179void JSDictionary::convertValue(ExecState* state, JSValue value, RefPtr<DOMWindow>& result)
    180180{
    181     result = JSDOMWindow::toWrapped(*state, value);
     181    auto* window = JSDOMWindow::toWrapped(*state, value);
     182    if (UNLIKELY(!window) && !value.isUndefinedOrNull()) {
     183        throwVMTypeError(state, "Dictionary member is not of type Window");
     184        return;
     185    }
     186    result = window;
    182187}
    183188
Note: See TracChangeset for help on using the changeset viewer.