tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

test_securecontext_extended_attribute.py (24178B)


      1 import WebIDL
      2 
      3 
      4 def WebIDLTest(parser, harness):
      5    parser.parse(
      6        """
      7        [SecureContext]
      8        interface TestSecureContextOnInterface {
      9          const octet TEST_CONSTANT = 0;
     10          readonly attribute byte testAttribute;
     11          undefined testMethod(byte foo);
     12        };
     13        partial interface TestSecureContextOnInterface {
     14          const octet TEST_CONSTANT_2 = 0;
     15          readonly attribute byte testAttribute2;
     16          undefined testMethod2(byte foo);
     17        };
     18    """
     19    )
     20    results = parser.finish()
     21    harness.check(
     22        len(results[0].members),
     23        6,
     24        "TestSecureContextOnInterface should have six members",
     25    )
     26    harness.ok(
     27        results[0].getExtendedAttribute("SecureContext"),
     28        "Interface should have [SecureContext] extended attribute",
     29    )
     30    harness.ok(
     31        results[0].members[0].getExtendedAttribute("SecureContext"),
     32        "[SecureContext] should propagate from interface to constant members",
     33    )
     34    harness.ok(
     35        results[0].members[1].getExtendedAttribute("SecureContext"),
     36        "[SecureContext] should propagate from interface to attribute members",
     37    )
     38    harness.ok(
     39        results[0].members[2].getExtendedAttribute("SecureContext"),
     40        "[SecureContext] should propagate from interface to method members",
     41    )
     42    harness.ok(
     43        results[0].members[3].getExtendedAttribute("SecureContext"),
     44        (
     45            "[SecureContext] should propagate from interface to "
     46            "constant members from partial interface"
     47        ),
     48    )
     49    harness.ok(
     50        results[0].members[4].getExtendedAttribute("SecureContext"),
     51        (
     52            "[SecureContext] should propagate from interface to "
     53            "attribute members from partial interface"
     54        ),
     55    )
     56    harness.ok(
     57        results[0].members[5].getExtendedAttribute("SecureContext"),
     58        "[SecureContext] should propagate from interface to method members from partial interface",
     59    )
     60 
     61    # Same thing, but with the partial interface specified first:
     62    parser = parser.reset()
     63    parser.parse(
     64        """
     65        partial interface TestSecureContextOnInterfaceAfterPartialInterface {
     66          const octet TEST_CONSTANT_2 = 0;
     67          readonly attribute byte testAttribute2;
     68          undefined testMethod2(byte foo);
     69        };
     70        [SecureContext]
     71        interface TestSecureContextOnInterfaceAfterPartialInterface {
     72          const octet TEST_CONSTANT = 0;
     73          readonly attribute byte testAttribute;
     74          undefined testMethod(byte foo);
     75        };
     76     """
     77    )
     78    results = parser.finish()
     79    harness.check(
     80        len(results[1].members),
     81        6,
     82        "TestSecureContextOnInterfaceAfterPartialInterface should have six members",
     83    )
     84    harness.ok(
     85        results[1].getExtendedAttribute("SecureContext"),
     86        "Interface should have [SecureContext] extended attribute",
     87    )
     88    harness.ok(
     89        results[1].members[0].getExtendedAttribute("SecureContext"),
     90        "[SecureContext] should propagate from interface to constant members",
     91    )
     92    harness.ok(
     93        results[1].members[1].getExtendedAttribute("SecureContext"),
     94        "[SecureContext] should propagate from interface to attribute members",
     95    )
     96    harness.ok(
     97        results[1].members[2].getExtendedAttribute("SecureContext"),
     98        "[SecureContext] should propagate from interface to method members",
     99    )
    100    harness.ok(
    101        results[1].members[3].getExtendedAttribute("SecureContext"),
    102        (
    103            "[SecureContext] should propagate from interface to constant members from "
    104            "partial interface"
    105        ),
    106    )
    107    harness.ok(
    108        results[1].members[4].getExtendedAttribute("SecureContext"),
    109        (
    110            "[SecureContext] should propagate from interface to attribute members from "
    111            "partial interface"
    112        ),
    113    )
    114    harness.ok(
    115        results[1].members[5].getExtendedAttribute("SecureContext"),
    116        (
    117            "[SecureContext] should propagate from interface to method members from partial "
    118            "interface"
    119        ),
    120    )
    121 
    122    parser = parser.reset()
    123    parser.parse(
    124        """
    125        interface TestSecureContextOnPartialInterface {
    126          const octet TEST_CONSTANT = 0;
    127          readonly attribute byte testAttribute;
    128          undefined testMethod(byte foo);
    129        };
    130        [SecureContext]
    131        partial interface TestSecureContextOnPartialInterface {
    132          const octet TEST_CONSTANT_2 = 0;
    133          readonly attribute byte testAttribute2;
    134          undefined testMethod2(byte foo);
    135        };
    136    """
    137    )
    138    results = parser.finish()
    139    harness.check(
    140        len(results[0].members),
    141        6,
    142        "TestSecureContextOnPartialInterface should have six members",
    143    )
    144    harness.ok(
    145        results[0].getExtendedAttribute("SecureContext") is None,
    146        "[SecureContext] should not propagate from a partial interface to the interface",
    147    )
    148    harness.ok(
    149        results[0].members[0].getExtendedAttribute("SecureContext") is None,
    150        (
    151            "[SecureContext] should not propagate from a partial interface to the interface's "
    152            "constant members"
    153        ),
    154    )
    155    harness.ok(
    156        results[0].members[1].getExtendedAttribute("SecureContext") is None,
    157        (
    158            "[SecureContext] should not propagate from a partial interface to the interface's "
    159            "attribute members"
    160        ),
    161    )
    162    harness.ok(
    163        results[0].members[2].getExtendedAttribute("SecureContext") is None,
    164        (
    165            "[SecureContext] should not propagate from a partial interface to the interface's "
    166            "method members"
    167        ),
    168    )
    169    harness.ok(
    170        results[0].members[3].getExtendedAttribute("SecureContext"),
    171        "Constant members from [SecureContext] partial interface should be [SecureContext]",
    172    )
    173    harness.ok(
    174        results[0].members[4].getExtendedAttribute("SecureContext"),
    175        "Attribute members from [SecureContext] partial interface should be [SecureContext]",
    176    )
    177    harness.ok(
    178        results[0].members[5].getExtendedAttribute("SecureContext"),
    179        "Method members from [SecureContext] partial interface should be [SecureContext]",
    180    )
    181 
    182    parser = parser.reset()
    183    parser.parse(
    184        """
    185        interface TestSecureContextOnInterfaceMembers {
    186          const octet TEST_NON_SECURE_CONSTANT_1 = 0;
    187          [SecureContext]
    188          const octet TEST_SECURE_CONSTANT       = 1;
    189          const octet TEST_NON_SECURE_CONSTANT_2 = 2;
    190          readonly attribute byte testNonSecureAttribute1;
    191          [SecureContext]
    192          readonly attribute byte testSecureAttribute;
    193          readonly attribute byte testNonSecureAttribute2;
    194          undefined testNonSecureMethod1(byte foo);
    195          [SecureContext]
    196          undefined testSecureMethod(byte foo);
    197          undefined testNonSecureMethod2(byte foo);
    198        };
    199    """
    200    )
    201    results = parser.finish()
    202    harness.check(
    203        len(results[0].members),
    204        9,
    205        "TestSecureContextOnInterfaceMembers should have nine members",
    206    )
    207    harness.ok(
    208        results[0].getExtendedAttribute("SecureContext") is None,
    209        "[SecureContext] on members should not propagate up to the interface",
    210    )
    211    harness.ok(
    212        results[0].members[0].getExtendedAttribute("SecureContext") is None,
    213        "Constant should not have [SecureContext] extended attribute",
    214    )
    215    harness.ok(
    216        results[0].members[1].getExtendedAttribute("SecureContext"),
    217        "Constant should have [SecureContext] extended attribute",
    218    )
    219    harness.ok(
    220        results[0].members[2].getExtendedAttribute("SecureContext") is None,
    221        "Constant should not have [SecureContext] extended attribute",
    222    )
    223    harness.ok(
    224        results[0].members[3].getExtendedAttribute("SecureContext") is None,
    225        "Attribute should not have [SecureContext] extended attribute",
    226    )
    227    harness.ok(
    228        results[0].members[4].getExtendedAttribute("SecureContext"),
    229        "Attribute should have [SecureContext] extended attribute",
    230    )
    231    harness.ok(
    232        results[0].members[5].getExtendedAttribute("SecureContext") is None,
    233        "Attribute should not have [SecureContext] extended attribute",
    234    )
    235    harness.ok(
    236        results[0].members[6].getExtendedAttribute("SecureContext") is None,
    237        "Method should not have [SecureContext] extended attribute",
    238    )
    239    harness.ok(
    240        results[0].members[7].getExtendedAttribute("SecureContext"),
    241        "Method should have [SecureContext] extended attribute",
    242    )
    243    harness.ok(
    244        results[0].members[8].getExtendedAttribute("SecureContext") is None,
    245        "Method should not have [SecureContext] extended attribute",
    246    )
    247 
    248    parser = parser.reset()
    249    parser.parse(
    250        """
    251        interface TestSecureContextOnPartialInterfaceMembers {
    252        };
    253        partial interface TestSecureContextOnPartialInterfaceMembers {
    254          const octet TEST_NON_SECURE_CONSTANT_1 = 0;
    255          [SecureContext]
    256          const octet TEST_SECURE_CONSTANT       = 1;
    257          const octet TEST_NON_SECURE_CONSTANT_2 = 2;
    258          readonly attribute byte testNonSecureAttribute1;
    259          [SecureContext]
    260          readonly attribute byte testSecureAttribute;
    261          readonly attribute byte testNonSecureAttribute2;
    262          undefined testNonSecureMethod1(byte foo);
    263          [SecureContext]
    264          undefined testSecureMethod(byte foo);
    265          undefined testNonSecureMethod2(byte foo);
    266        };
    267    """
    268    )
    269    results = parser.finish()
    270    harness.check(
    271        len(results[0].members),
    272        9,
    273        "TestSecureContextOnPartialInterfaceMembers should have nine members",
    274    )
    275    harness.ok(
    276        results[0].members[0].getExtendedAttribute("SecureContext") is None,
    277        "Constant from partial interface should not have [SecureContext] extended attribute",
    278    )
    279    harness.ok(
    280        results[0].members[1].getExtendedAttribute("SecureContext"),
    281        "Constant from partial interface should have [SecureContext] extended attribute",
    282    )
    283    harness.ok(
    284        results[0].members[2].getExtendedAttribute("SecureContext") is None,
    285        "Constant from partial interface should not have [SecureContext] extended attribute",
    286    )
    287    harness.ok(
    288        results[0].members[3].getExtendedAttribute("SecureContext") is None,
    289        "Attribute from partial interface should not have [SecureContext] extended attribute",
    290    )
    291    harness.ok(
    292        results[0].members[4].getExtendedAttribute("SecureContext"),
    293        "Attribute from partial interface should have [SecureContext] extended attribute",
    294    )
    295    harness.ok(
    296        results[0].members[5].getExtendedAttribute("SecureContext") is None,
    297        "Attribute from partial interface should not have [SecureContext] extended attribute",
    298    )
    299    harness.ok(
    300        results[0].members[6].getExtendedAttribute("SecureContext") is None,
    301        "Method from partial interface should not have [SecureContext] extended attribute",
    302    )
    303    harness.ok(
    304        results[0].members[7].getExtendedAttribute("SecureContext"),
    305        "Method from partial interface should have [SecureContext] extended attribute",
    306    )
    307    harness.ok(
    308        results[0].members[8].getExtendedAttribute("SecureContext") is None,
    309        "Method from partial interface should not have [SecureContext] extended attribute",
    310    )
    311 
    312    parser = parser.reset()
    313    threw = False
    314    try:
    315        parser.parse(
    316            """
    317            [SecureContext=something]
    318            interface TestSecureContextTakesNoValue1 {
    319              const octet TEST_SECURE_CONSTANT = 0;
    320            };
    321        """
    322        )
    323        results = parser.finish()
    324    except WebIDL.WebIDLError:
    325        threw = True
    326    harness.ok(threw, "[SecureContext] must take no arguments (testing on interface)")
    327 
    328    parser = parser.reset()
    329    threw = False
    330    try:
    331        parser.parse(
    332            """
    333            interface TestSecureContextForOverloads1 {
    334              [SecureContext]
    335              undefined testSecureMethod(byte foo);
    336            };
    337            partial interface TestSecureContextForOverloads1 {
    338              undefined testSecureMethod(byte foo, byte bar);
    339            };
    340        """
    341        )
    342        results = parser.finish()
    343    except WebIDL.WebIDLError:
    344        threw = True
    345    harness.ok(
    346        threw,
    347        (
    348            "If [SecureContext] appears on an overloaded operation, then it MUST appear on all "
    349            "overloads"
    350        ),
    351    )
    352 
    353    parser = parser.reset()
    354    threw = False
    355    try:
    356        parser.parse(
    357            """
    358            interface TestSecureContextForOverloads2 {
    359              [SecureContext]
    360              undefined testSecureMethod(byte foo);
    361            };
    362            partial interface TestSecureContextForOverloads2 {
    363              [SecureContext]
    364              undefined testSecureMethod(byte foo, byte bar);
    365            };
    366        """
    367        )
    368        results = parser.finish()
    369    except WebIDL.WebIDLError:
    370        threw = True
    371    harness.ok(
    372        not threw,
    373        "[SecureContext] can appear on an overloaded operation if it appears on all overloads",
    374    )
    375 
    376    parser = parser.reset()
    377    threw = False
    378    try:
    379        parser.parse(
    380            """
    381            [SecureContext]
    382            interface TestSecureContextOnInterfaceAndMember {
    383              [SecureContext]
    384              undefined testSecureMethod(byte foo);
    385            };
    386        """
    387        )
    388        results = parser.finish()
    389    except WebIDL.WebIDLError:
    390        threw = True
    391    harness.ok(
    392        threw, "[SecureContext] must not appear on an interface and interface member"
    393    )
    394 
    395    parser = parser.reset()
    396    threw = False
    397    try:
    398        parser.parse(
    399            """
    400            interface TestSecureContextOnPartialInterfaceAndMember {
    401            };
    402            [SecureContext]
    403            partial interface TestSecureContextOnPartialInterfaceAndMember {
    404              [SecureContext]
    405              undefined testSecureMethod(byte foo);
    406            };
    407        """
    408        )
    409        results = parser.finish()
    410    except WebIDL.WebIDLError:
    411        threw = True
    412    harness.ok(
    413        threw,
    414        (
    415            "[SecureContext] must not appear on a partial interface and one of the partial "
    416            "interface's member's"
    417        ),
    418    )
    419 
    420    parser = parser.reset()
    421    threw = False
    422    try:
    423        parser.parse(
    424            """
    425            [SecureContext]
    426            interface TestSecureContextOnInterfaceAndPartialInterfaceMember {
    427            };
    428            partial interface TestSecureContextOnInterfaceAndPartialInterfaceMember {
    429              [SecureContext]
    430              undefined testSecureMethod(byte foo);
    431            };
    432        """
    433        )
    434        results = parser.finish()
    435    except WebIDL.WebIDLError:
    436        threw = True
    437    harness.ok(
    438        threw,
    439        (
    440            "[SecureContext] must not appear on an interface and one of its partial interface's "
    441            "member's"
    442        ),
    443    )
    444 
    445    parser = parser.reset()
    446    threw = False
    447    try:
    448        parser.parse(
    449            """
    450            [SecureContext]
    451            interface TestSecureContextOnInheritedInterface {
    452            };
    453            interface TestSecureContextNotOnInheritingInterface : TestSecureContextOnInheritedInterface {
    454              undefined testSecureMethod(byte foo);
    455            };
    456        """
    457        )
    458        results = parser.finish()
    459    except WebIDL.WebIDLError:
    460        threw = True
    461    harness.ok(
    462        threw,
    463        (
    464            "[SecureContext] must appear on interfaces that inherit from another [SecureContext] "
    465            "interface"
    466        ),
    467    )
    468 
    469    # Test namespace
    470    parser = parser.reset()
    471    parser.parse(
    472        """
    473        [SecureContext]
    474        namespace TestSecureContextOnNamespace {
    475          const octet TEST_CONSTANT = 0;
    476          readonly attribute byte testAttribute;
    477          undefined testMethod(byte foo);
    478        };
    479        partial namespace TestSecureContextOnNamespace {
    480          const octet TEST_CONSTANT_2 = 0;
    481          readonly attribute byte testAttribute2;
    482          undefined testMethod2(byte foo);
    483        };
    484    """
    485    )
    486    results = parser.finish()
    487    harness.check(
    488        len(results[0].members),
    489        6,
    490        "TestSecureContextOnNamespace should have six members",
    491    )
    492    harness.ok(
    493        results[0].getExtendedAttribute("SecureContext"),
    494        "Namespace should have [SecureContext] extended attribute",
    495    )
    496    harness.ok(
    497        results[0].members[0].getExtendedAttribute("SecureContext"),
    498        "[SecureContext] should propagate from namespace to constant members",
    499    )
    500    harness.ok(
    501        results[0].members[1].getExtendedAttribute("SecureContext"),
    502        "[SecureContext] should propagate from namespace to attribute members",
    503    )
    504    harness.ok(
    505        results[0].members[2].getExtendedAttribute("SecureContext"),
    506        "[SecureContext] should propagate from namespace to method members",
    507    )
    508    harness.ok(
    509        results[0].members[3].getExtendedAttribute("SecureContext"),
    510        (
    511            "[SecureContext] should propagate from namespace to "
    512            "constant members from partial namespace"
    513        ),
    514    )
    515    harness.ok(
    516        results[0].members[4].getExtendedAttribute("SecureContext"),
    517        (
    518            "[SecureContext] should propagate from namespace to "
    519            "attribute members from partial namespace"
    520        ),
    521    )
    522    harness.ok(
    523        results[0].members[5].getExtendedAttribute("SecureContext"),
    524        "[SecureContext] should propagate from namespace to method members from partial namespace",
    525    )
    526 
    527    parser = parser.reset()
    528    parser.parse(
    529        """
    530        namespace TestSecureContextOnNamespace {
    531          const octet TEST_CONSTANT = 0;
    532          readonly attribute byte testAttribute;
    533          undefined testMethod(byte foo);
    534        };
    535        [SecureContext]
    536        partial namespace TestSecureContextOnNamespace {
    537          const octet TEST_CONSTANT_2 = 0;
    538          readonly attribute byte testAttribute2;
    539          undefined testMethod2(byte foo);
    540        };
    541    """
    542    )
    543    results = parser.finish()
    544    harness.check(
    545        len(results[0].members),
    546        6,
    547        "TestSecureContextOnNamespace should have six members",
    548    )
    549    harness.ok(
    550        results[0].getExtendedAttribute("SecureContext") is None,
    551        "Namespace should not have [SecureContext] extended attribute",
    552    )
    553    harness.ok(
    554        results[0].members[0].getExtendedAttribute("SecureContext") is None,
    555        (
    556            "[SecureContext] should not propagate from a partial namespace to the namespace's "
    557            "constant members"
    558        ),
    559    )
    560    harness.ok(
    561        results[0].members[1].getExtendedAttribute("SecureContext") is None,
    562        (
    563            "[SecureContext] should not propagate from a partial namespace to the namespace's "
    564            "attribute members"
    565        ),
    566    )
    567    harness.ok(
    568        results[0].members[2].getExtendedAttribute("SecureContext") is None,
    569        (
    570            "[SecureContext] should not propagate from a partial namespace to the namespace's "
    571            "method members"
    572        ),
    573    )
    574    harness.ok(
    575        results[0].members[3].getExtendedAttribute("SecureContext"),
    576        "Constant members from [SecureContext] partial namespace should be [SecureContext]",
    577    )
    578    harness.ok(
    579        results[0].members[4].getExtendedAttribute("SecureContext"),
    580        "Attribute members from [SecureContext] partial namespace should be [SecureContext]",
    581    )
    582    harness.ok(
    583        results[0].members[5].getExtendedAttribute("SecureContext"),
    584        "Method members from [SecureContext] partial namespace should be [SecureContext]",
    585    )
    586 
    587    # Test 'includes'.
    588    parser = parser.reset()
    589    parser.parse(
    590        """
    591        [SecureContext]
    592        interface TestSecureContextInterfaceThatIncludesNonSecureContextMixin {
    593          const octet TEST_CONSTANT = 0;
    594        };
    595        interface mixin TestNonSecureContextMixin {
    596          const octet TEST_CONSTANT_2 = 0;
    597          readonly attribute byte testAttribute2;
    598          undefined testMethod2(byte foo);
    599        };
    600        TestSecureContextInterfaceThatIncludesNonSecureContextMixin includes TestNonSecureContextMixin;
    601     """
    602    )
    603    results = parser.finish()
    604    harness.check(
    605        len(results[0].members),
    606        4,
    607        (
    608            "TestSecureContextInterfaceThatImplementsNonSecureContextInterface should have four "
    609            "members"
    610        ),
    611    )
    612    harness.ok(
    613        results[0].getExtendedAttribute("SecureContext"),
    614        "Interface should have [SecureContext] extended attribute",
    615    )
    616    harness.ok(
    617        results[0].members[0].getExtendedAttribute("SecureContext"),
    618        (
    619            "[SecureContext] should propagate from interface to constant members even when other "
    620            "members are copied from a non-[SecureContext] interface"
    621        ),
    622    )
    623    harness.ok(
    624        results[0].members[1].getExtendedAttribute("SecureContext") is None,
    625        "Constants copied from non-[SecureContext] mixin should not be [SecureContext]",
    626    )
    627    harness.ok(
    628        results[0].members[2].getExtendedAttribute("SecureContext") is None,
    629        "Attributes copied from non-[SecureContext] mixin should not be [SecureContext]",
    630    )
    631    harness.ok(
    632        results[0].members[3].getExtendedAttribute("SecureContext") is None,
    633        "Methods copied from non-[SecureContext] mixin should not be [SecureContext]",
    634    )
    635 
    636    parser = parser.reset()
    637    parser.parse(
    638        """
    639        interface TestSecureContextInterfaceThatIncludesNonSecureContextMixin {
    640          const octet TEST_CONSTANT = 0;
    641        };
    642        [SecureContext]
    643        interface mixin TestNonSecureContextMixin {
    644          const octet TEST_CONSTANT_2 = 0;
    645          readonly attribute byte testAttribute2;
    646          undefined testMethod2(byte foo);
    647        };
    648        TestSecureContextInterfaceThatIncludesNonSecureContextMixin includes TestNonSecureContextMixin;
    649     """
    650    )
    651    results = parser.finish()
    652    harness.check(
    653        len(results[0].members),
    654        4,
    655        (
    656            "TestSecureContextInterfaceThatImplementsNonSecureContextInterface should have four "
    657            "members"
    658        ),
    659    )
    660    harness.ok(
    661        results[0].getExtendedAttribute("SecureContext") is None,
    662        "Interface should not have [SecureContext] extended attribute",
    663    )
    664    harness.ok(
    665        results[0].members[0].getExtendedAttribute("SecureContext") is None,
    666        (
    667            "[SecureContext] should not propagate from interface to constant members when other "
    668            "members are copied from a [SecureContext] mixin"
    669        ),
    670    )
    671    harness.ok(
    672        results[0].members[1].getExtendedAttribute("SecureContext"),
    673        "Constants copied from [SecureContext] mixin should be [SecureContext]",
    674    )
    675    harness.ok(
    676        results[0].members[2].getExtendedAttribute("SecureContext"),
    677        "Attributes copied from [SecureContext] mixin should be [SecureContext]",
    678    )
    679    harness.ok(
    680        results[0].members[3].getExtendedAttribute("SecureContext"),
    681        "Methods copied from [SecureContext] mixin should be [SecureContext]",
    682    )
    683 
    684    # Test SecureContext and LegacyNoInterfaceObject
    685    parser = parser.reset()
    686    parser.parse(
    687        """
    688        [LegacyNoInterfaceObject, SecureContext]
    689        interface TestSecureContextLegacyNoInterfaceObject {
    690          undefined testSecureMethod(byte foo);
    691        };
    692    """
    693    )
    694    results = parser.finish()
    695    harness.check(
    696        len(results[0].members),
    697        1,
    698        "TestSecureContextLegacyNoInterfaceObject should have only one member",
    699    )
    700    harness.ok(
    701        results[0].getExtendedAttribute("SecureContext"),
    702        "Interface should have [SecureContext] extended attribute",
    703    )
    704    harness.ok(
    705        results[0].members[0].getExtendedAttribute("SecureContext"),
    706        "Interface member should have [SecureContext] extended attribute",
    707    )