| import WebIDL |
| |
| |
| def WebIDLTest(parser, harness): |
| parser.parse( |
| """ |
| [SecureContext] |
| interface TestSecureContextOnInterface { |
| const octet TEST_CONSTANT = 0; |
| readonly attribute byte testAttribute; |
| undefined testMethod(byte foo); |
| }; |
| partial interface TestSecureContextOnInterface { |
| const octet TEST_CONSTANT_2 = 0; |
| readonly attribute byte testAttribute2; |
| undefined testMethod2(byte foo); |
| }; |
| """ |
| ) |
| results = parser.finish() |
| harness.check( |
| len(results[0].members), |
| 6, |
| "TestSecureContextOnInterface should have six members", |
| ) |
| harness.ok( |
| results[0].getExtendedAttribute("SecureContext"), |
| "Interface should have [SecureContext] extended attribute", |
| ) |
| harness.ok( |
| results[0].members[0].getExtendedAttribute("SecureContext"), |
| "[SecureContext] should propagate from interface to constant members", |
| ) |
| harness.ok( |
| results[0].members[1].getExtendedAttribute("SecureContext"), |
| "[SecureContext] should propagate from interface to attribute members", |
| ) |
| harness.ok( |
| results[0].members[2].getExtendedAttribute("SecureContext"), |
| "[SecureContext] should propagate from interface to method members", |
| ) |
| harness.ok( |
| results[0].members[3].getExtendedAttribute("SecureContext"), |
| ( |
| "[SecureContext] should propagate from interface to " |
| "constant members from partial interface" |
| ), |
| ) |
| harness.ok( |
| results[0].members[4].getExtendedAttribute("SecureContext"), |
| ( |
| "[SecureContext] should propagate from interface to " |
| "attribute members from partial interface" |
| ), |
| ) |
| harness.ok( |
| results[0].members[5].getExtendedAttribute("SecureContext"), |
| "[SecureContext] should propagate from interface to method members from partial interface", |
| ) |
| |
| # Same thing, but with the partial interface specified first: |
| parser = parser.reset() |
| parser.parse( |
| """ |
| partial interface TestSecureContextOnInterfaceAfterPartialInterface { |
| const octet TEST_CONSTANT_2 = 0; |
| readonly attribute byte testAttribute2; |
| undefined testMethod2(byte foo); |
| }; |
| [SecureContext] |
| interface TestSecureContextOnInterfaceAfterPartialInterface { |
| const octet TEST_CONSTANT = 0; |
| readonly attribute byte testAttribute; |
| undefined testMethod(byte foo); |
| }; |
| """ |
| ) |
| results = parser.finish() |
| harness.check( |
| len(results[1].members), |
| 6, |
| "TestSecureContextOnInterfaceAfterPartialInterface should have six members", |
| ) |
| harness.ok( |
| results[1].getExtendedAttribute("SecureContext"), |
| "Interface should have [SecureContext] extended attribute", |
| ) |
| harness.ok( |
| results[1].members[0].getExtendedAttribute("SecureContext"), |
| "[SecureContext] should propagate from interface to constant members", |
| ) |
| harness.ok( |
| results[1].members[1].getExtendedAttribute("SecureContext"), |
| "[SecureContext] should propagate from interface to attribute members", |
| ) |
| harness.ok( |
| results[1].members[2].getExtendedAttribute("SecureContext"), |
| "[SecureContext] should propagate from interface to method members", |
| ) |
| harness.ok( |
| results[1].members[3].getExtendedAttribute("SecureContext"), |
| ( |
| "[SecureContext] should propagate from interface to constant members from " |
| "partial interface" |
| ), |
| ) |
| harness.ok( |
| results[1].members[4].getExtendedAttribute("SecureContext"), |
| ( |
| "[SecureContext] should propagate from interface to attribute members from " |
| "partial interface" |
| ), |
| ) |
| harness.ok( |
| results[1].members[5].getExtendedAttribute("SecureContext"), |
| ( |
| "[SecureContext] should propagate from interface to method members from partial " |
| "interface" |
| ), |
| ) |
| |
| parser = parser.reset() |
| parser.parse( |
| """ |
| interface TestSecureContextOnPartialInterface { |
| const octet TEST_CONSTANT = 0; |
| readonly attribute byte testAttribute; |
| undefined testMethod(byte foo); |
| }; |
| [SecureContext] |
| partial interface TestSecureContextOnPartialInterface { |
| const octet TEST_CONSTANT_2 = 0; |
| readonly attribute byte testAttribute2; |
| undefined testMethod2(byte foo); |
| }; |
| """ |
| ) |
| results = parser.finish() |
| harness.check( |
| len(results[0].members), |
| 6, |
| "TestSecureContextOnPartialInterface should have six members", |
| ) |
| harness.ok( |
| results[0].getExtendedAttribute("SecureContext") is None, |
| "[SecureContext] should not propagate from a partial interface to the interface", |
| ) |
| harness.ok( |
| results[0].members[0].getExtendedAttribute("SecureContext") is None, |
| ( |
| "[SecureContext] should not propagate from a partial interface to the interface's " |
| "constant members" |
| ), |
| ) |
| harness.ok( |
| results[0].members[1].getExtendedAttribute("SecureContext") is None, |
| ( |
| "[SecureContext] should not propagate from a partial interface to the interface's " |
| "attribute members" |
| ), |
| ) |
| harness.ok( |
| results[0].members[2].getExtendedAttribute("SecureContext") is None, |
| ( |
| "[SecureContext] should not propagate from a partial interface to the interface's " |
| "method members" |
| ), |
| ) |
| harness.ok( |
| results[0].members[3].getExtendedAttribute("SecureContext"), |
| "Constant members from [SecureContext] partial interface should be [SecureContext]", |
| ) |
| harness.ok( |
| results[0].members[4].getExtendedAttribute("SecureContext"), |
| "Attribute members from [SecureContext] partial interface should be [SecureContext]", |
| ) |
| harness.ok( |
| results[0].members[5].getExtendedAttribute("SecureContext"), |
| "Method members from [SecureContext] partial interface should be [SecureContext]", |
| ) |
| |
| parser = parser.reset() |
| parser.parse( |
| """ |
| interface TestSecureContextOnInterfaceMembers { |
| const octet TEST_NON_SECURE_CONSTANT_1 = 0; |
| [SecureContext] |
| const octet TEST_SECURE_CONSTANT = 1; |
| const octet TEST_NON_SECURE_CONSTANT_2 = 2; |
| readonly attribute byte testNonSecureAttribute1; |
| [SecureContext] |
| readonly attribute byte testSecureAttribute; |
| readonly attribute byte testNonSecureAttribute2; |
| undefined testNonSecureMethod1(byte foo); |
| [SecureContext] |
| undefined testSecureMethod(byte foo); |
| undefined testNonSecureMethod2(byte foo); |
| }; |
| """ |
| ) |
| results = parser.finish() |
| harness.check( |
| len(results[0].members), |
| 9, |
| "TestSecureContextOnInterfaceMembers should have nine members", |
| ) |
| harness.ok( |
| results[0].getExtendedAttribute("SecureContext") is None, |
| "[SecureContext] on members should not propagate up to the interface", |
| ) |
| harness.ok( |
| results[0].members[0].getExtendedAttribute("SecureContext") is None, |
| "Constant should not have [SecureContext] extended attribute", |
| ) |
| harness.ok( |
| results[0].members[1].getExtendedAttribute("SecureContext"), |
| "Constant should have [SecureContext] extended attribute", |
| ) |
| harness.ok( |
| results[0].members[2].getExtendedAttribute("SecureContext") is None, |
| "Constant should not have [SecureContext] extended attribute", |
| ) |
| harness.ok( |
| results[0].members[3].getExtendedAttribute("SecureContext") is None, |
| "Attribute should not have [SecureContext] extended attribute", |
| ) |
| harness.ok( |
| results[0].members[4].getExtendedAttribute("SecureContext"), |
| "Attribute should have [SecureContext] extended attribute", |
| ) |
| harness.ok( |
| results[0].members[5].getExtendedAttribute("SecureContext") is None, |
| "Attribute should not have [SecureContext] extended attribute", |
| ) |
| harness.ok( |
| results[0].members[6].getExtendedAttribute("SecureContext") is None, |
| "Method should not have [SecureContext] extended attribute", |
| ) |
| harness.ok( |
| results[0].members[7].getExtendedAttribute("SecureContext"), |
| "Method should have [SecureContext] extended attribute", |
| ) |
| harness.ok( |
| results[0].members[8].getExtendedAttribute("SecureContext") is None, |
| "Method should not have [SecureContext] extended attribute", |
| ) |
| |
| parser = parser.reset() |
| parser.parse( |
| """ |
| interface TestSecureContextOnPartialInterfaceMembers { |
| }; |
| partial interface TestSecureContextOnPartialInterfaceMembers { |
| const octet TEST_NON_SECURE_CONSTANT_1 = 0; |
| [SecureContext] |
| const octet TEST_SECURE_CONSTANT = 1; |
| const octet TEST_NON_SECURE_CONSTANT_2 = 2; |
| readonly attribute byte testNonSecureAttribute1; |
| [SecureContext] |
| readonly attribute byte testSecureAttribute; |
| readonly attribute byte testNonSecureAttribute2; |
| undefined testNonSecureMethod1(byte foo); |
| [SecureContext] |
| undefined testSecureMethod(byte foo); |
| undefined testNonSecureMethod2(byte foo); |
| }; |
| """ |
| ) |
| results = parser.finish() |
| harness.check( |
| len(results[0].members), |
| 9, |
| "TestSecureContextOnPartialInterfaceMembers should have nine members", |
| ) |
| harness.ok( |
| results[0].members[0].getExtendedAttribute("SecureContext") is None, |
| "Constant from partial interface should not have [SecureContext] extended attribute", |
| ) |
| harness.ok( |
| results[0].members[1].getExtendedAttribute("SecureContext"), |
| "Constant from partial interface should have [SecureContext] extended attribute", |
| ) |
| harness.ok( |
| results[0].members[2].getExtendedAttribute("SecureContext") is None, |
| "Constant from partial interface should not have [SecureContext] extended attribute", |
| ) |
| harness.ok( |
| results[0].members[3].getExtendedAttribute("SecureContext") is None, |
| "Attribute from partial interface should not have [SecureContext] extended attribute", |
| ) |
| harness.ok( |
| results[0].members[4].getExtendedAttribute("SecureContext"), |
| "Attribute from partial interface should have [SecureContext] extended attribute", |
| ) |
| harness.ok( |
| results[0].members[5].getExtendedAttribute("SecureContext") is None, |
| "Attribute from partial interface should not have [SecureContext] extended attribute", |
| ) |
| harness.ok( |
| results[0].members[6].getExtendedAttribute("SecureContext") is None, |
| "Method from partial interface should not have [SecureContext] extended attribute", |
| ) |
| harness.ok( |
| results[0].members[7].getExtendedAttribute("SecureContext"), |
| "Method from partial interface should have [SecureContext] extended attribute", |
| ) |
| harness.ok( |
| results[0].members[8].getExtendedAttribute("SecureContext") is None, |
| "Method from partial interface should not have [SecureContext] extended attribute", |
| ) |
| |
| parser = parser.reset() |
| threw = False |
| try: |
| parser.parse( |
| """ |
| [SecureContext=something] |
| interface TestSecureContextTakesNoValue1 { |
| const octet TEST_SECURE_CONSTANT = 0; |
| }; |
| """ |
| ) |
| results = parser.finish() |
| except WebIDL.WebIDLError: |
| threw = True |
| harness.ok(threw, "[SecureContext] must take no arguments (testing on interface)") |
| |
| parser = parser.reset() |
| threw = False |
| try: |
| parser.parse( |
| """ |
| interface TestSecureContextForOverloads1 { |
| [SecureContext] |
| undefined testSecureMethod(byte foo); |
| }; |
| partial interface TestSecureContextForOverloads1 { |
| undefined testSecureMethod(byte foo, byte bar); |
| }; |
| """ |
| ) |
| results = parser.finish() |
| except WebIDL.WebIDLError: |
| threw = True |
| harness.ok( |
| threw, |
| ( |
| "If [SecureContext] appears on an overloaded operation, then it MUST appear on all " |
| "overloads" |
| ), |
| ) |
| |
| parser = parser.reset() |
| threw = False |
| try: |
| parser.parse( |
| """ |
| interface TestSecureContextForOverloads2 { |
| [SecureContext] |
| undefined testSecureMethod(byte foo); |
| }; |
| partial interface TestSecureContextForOverloads2 { |
| [SecureContext] |
| undefined testSecureMethod(byte foo, byte bar); |
| }; |
| """ |
| ) |
| results = parser.finish() |
| except WebIDL.WebIDLError: |
| threw = True |
| harness.ok( |
| not threw, |
| "[SecureContext] can appear on an overloaded operation if it appears on all overloads", |
| ) |
| |
| parser = parser.reset() |
| threw = False |
| try: |
| parser.parse( |
| """ |
| [SecureContext] |
| interface TestSecureContextOnInterfaceAndMember { |
| [SecureContext] |
| undefined testSecureMethod(byte foo); |
| }; |
| """ |
| ) |
| results = parser.finish() |
| except WebIDL.WebIDLError: |
| threw = True |
| harness.ok( |
| threw, "[SecureContext] must not appear on an interface and interface member" |
| ) |
| |
| parser = parser.reset() |
| threw = False |
| try: |
| parser.parse( |
| """ |
| interface TestSecureContextOnPartialInterfaceAndMember { |
| }; |
| [SecureContext] |
| partial interface TestSecureContextOnPartialInterfaceAndMember { |
| [SecureContext] |
| undefined testSecureMethod(byte foo); |
| }; |
| """ |
| ) |
| results = parser.finish() |
| except WebIDL.WebIDLError: |
| threw = True |
| harness.ok( |
| threw, |
| ( |
| "[SecureContext] must not appear on a partial interface and one of the partial " |
| "interface's member's" |
| ), |
| ) |
| |
| parser = parser.reset() |
| threw = False |
| try: |
| parser.parse( |
| """ |
| [SecureContext] |
| interface TestSecureContextOnInterfaceAndPartialInterfaceMember { |
| }; |
| partial interface TestSecureContextOnInterfaceAndPartialInterfaceMember { |
| [SecureContext] |
| undefined testSecureMethod(byte foo); |
| }; |
| """ |
| ) |
| results = parser.finish() |
| except WebIDL.WebIDLError: |
| threw = True |
| harness.ok( |
| threw, |
| ( |
| "[SecureContext] must not appear on an interface and one of its partial interface's " |
| "member's" |
| ), |
| ) |
| |
| parser = parser.reset() |
| threw = False |
| try: |
| parser.parse( |
| """ |
| [SecureContext] |
| interface TestSecureContextOnInheritedInterface { |
| }; |
| interface TestSecureContextNotOnInheritingInterface : TestSecureContextOnInheritedInterface { |
| undefined testSecureMethod(byte foo); |
| }; |
| """ |
| ) |
| results = parser.finish() |
| except WebIDL.WebIDLError: |
| threw = True |
| harness.ok( |
| threw, |
| ( |
| "[SecureContext] must appear on interfaces that inherit from another [SecureContext] " |
| "interface" |
| ), |
| ) |
| |
| # Test 'includes'. |
| parser = parser.reset() |
| parser.parse( |
| """ |
| [SecureContext] |
| interface TestSecureContextInterfaceThatIncludesNonSecureContextMixin { |
| const octet TEST_CONSTANT = 0; |
| }; |
| interface mixin TestNonSecureContextMixin { |
| const octet TEST_CONSTANT_2 = 0; |
| readonly attribute byte testAttribute2; |
| undefined testMethod2(byte foo); |
| }; |
| TestSecureContextInterfaceThatIncludesNonSecureContextMixin includes TestNonSecureContextMixin; |
| """ |
| ) |
| results = parser.finish() |
| harness.check( |
| len(results[0].members), |
| 4, |
| ( |
| "TestSecureContextInterfaceThatImplementsNonSecureContextInterface should have four " |
| "members" |
| ), |
| ) |
| harness.ok( |
| results[0].getExtendedAttribute("SecureContext"), |
| "Interface should have [SecureContext] extended attribute", |
| ) |
| harness.ok( |
| results[0].members[0].getExtendedAttribute("SecureContext"), |
| ( |
| "[SecureContext] should propagate from interface to constant members even when other " |
| "members are copied from a non-[SecureContext] interface" |
| ), |
| ) |
| harness.ok( |
| results[0].members[1].getExtendedAttribute("SecureContext") is None, |
| "Constants copied from non-[SecureContext] mixin should not be [SecureContext]", |
| ) |
| harness.ok( |
| results[0].members[2].getExtendedAttribute("SecureContext") is None, |
| "Attributes copied from non-[SecureContext] mixin should not be [SecureContext]", |
| ) |
| harness.ok( |
| results[0].members[3].getExtendedAttribute("SecureContext") is None, |
| "Methods copied from non-[SecureContext] mixin should not be [SecureContext]", |
| ) |
| |
| # Test SecureContext and LegacyNoInterfaceObject |
| parser = parser.reset() |
| parser.parse( |
| """ |
| [LegacyNoInterfaceObject, SecureContext] |
| interface TestSecureContextLegacyNoInterfaceObject { |
| undefined testSecureMethod(byte foo); |
| }; |
| """ |
| ) |
| results = parser.finish() |
| harness.check( |
| len(results[0].members), |
| 1, |
| "TestSecureContextLegacyNoInterfaceObject should have only one member", |
| ) |
| harness.ok( |
| results[0].getExtendedAttribute("SecureContext"), |
| "Interface should have [SecureContext] extended attribute", |
| ) |
| harness.ok( |
| results[0].members[0].getExtendedAttribute("SecureContext"), |
| "Interface member should have [SecureContext] extended attribute", |
| ) |