tor-browser

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

test_dictionary.py (20105B)


      1 import WebIDL
      2 
      3 
      4 def WebIDLTest(parser, harness):
      5    parser.parse(
      6        """
      7      dictionary Dict2 : Dict1 {
      8        long child = 5;
      9        Dict1 aaandAnother;
     10      };
     11      dictionary Dict1 {
     12        long parent;
     13        double otherParent;
     14      };
     15    """
     16    )
     17    results = parser.finish()
     18 
     19    dict1 = results[1]
     20    dict2 = results[0]
     21 
     22    harness.check(len(dict1.members), 2, "Dict1 has two members")
     23    harness.check(len(dict2.members), 2, "Dict2 has four members")
     24 
     25    harness.check(
     26        dict1.members[0].identifier.name, "otherParent", "'o' comes before 'p'"
     27    )
     28    harness.check(
     29        dict1.members[1].identifier.name, "parent", "'o' really comes before 'p'"
     30    )
     31    harness.check(
     32        dict2.members[0].identifier.name, "aaandAnother", "'a' comes before 'c'"
     33    )
     34    harness.check(
     35        dict2.members[1].identifier.name, "child", "'a' really comes before 'c'"
     36    )
     37 
     38    # Test partial dictionary.
     39    parser = parser.reset()
     40    parser.parse(
     41        """
     42      dictionary A {
     43        long c;
     44        long g;
     45      };
     46      partial dictionary A {
     47        long h;
     48        long d;
     49      };
     50    """
     51    )
     52    results = parser.finish()
     53 
     54    dict1 = results[0]
     55    harness.check(len(dict1.members), 4, "Dict1 has four members")
     56    harness.check(dict1.members[0].identifier.name, "c", "c should be first")
     57    harness.check(dict1.members[1].identifier.name, "d", "d should come after c")
     58    harness.check(dict1.members[2].identifier.name, "g", "g should come after d")
     59    harness.check(dict1.members[3].identifier.name, "h", "h should be last")
     60 
     61    # Now reset our parser
     62    parser = parser.reset()
     63    threw = False
     64    try:
     65        parser.parse(
     66            """
     67          dictionary Dict {
     68            long prop = 5;
     69            long prop;
     70          };
     71        """
     72        )
     73        parser.finish()
     74    except WebIDL.WebIDLError:
     75        threw = True
     76 
     77    harness.ok(threw, "Should not allow name duplication in a dictionary")
     78 
     79    # Test no name duplication across normal and partial dictionary.
     80    parser = parser.reset()
     81    threw = False
     82    try:
     83        parser.parse(
     84            """
     85          dictionary A {
     86            long prop = 5;
     87          };
     88          partial dictionary A {
     89            long prop;
     90          };
     91        """
     92        )
     93        parser.finish()
     94    except WebIDL.WebIDLError:
     95        threw = True
     96 
     97    harness.ok(
     98        threw, "Should not allow name duplication across normal and partial dictionary"
     99    )
    100 
    101    # Now reset our parser again
    102    parser = parser.reset()
    103    threw = False
    104    try:
    105        parser.parse(
    106            """
    107          dictionary Dict1 : Dict2 {
    108            long prop = 5;
    109          };
    110          dictionary Dict2 : Dict3 {
    111            long prop2;
    112          };
    113          dictionary Dict3 {
    114            double prop;
    115          };
    116        """
    117        )
    118        parser.finish()
    119    except WebIDL.WebIDLError:
    120        threw = True
    121 
    122    harness.ok(
    123        threw, "Should not allow name duplication in a dictionary and its ancestor"
    124    )
    125 
    126    # More reset
    127    parser = parser.reset()
    128    threw = False
    129    try:
    130        parser.parse(
    131            """
    132          interface Iface {};
    133          dictionary Dict : Iface {
    134            long prop;
    135          };
    136        """
    137        )
    138        parser.finish()
    139    except WebIDL.WebIDLError:
    140        threw = True
    141 
    142    harness.ok(threw, "Should not allow non-dictionary parents for dictionaries")
    143 
    144    # Even more reset
    145    parser = parser.reset()
    146    threw = False
    147    try:
    148        parser.parse(
    149            """
    150            dictionary A : B {};
    151            dictionary B : A {};
    152        """
    153        )
    154        parser.finish()
    155    except WebIDL.WebIDLError:
    156        threw = True
    157 
    158    harness.ok(threw, "Should not allow cycles in dictionary inheritance chains")
    159 
    160    parser = parser.reset()
    161    threw = False
    162    try:
    163        parser.parse(
    164            """
    165            dictionary A {
    166              [LegacyNullToEmptyString] DOMString foo;
    167            };
    168        """
    169        )
    170        parser.finish()
    171    except WebIDL.WebIDLError:
    172        threw = True
    173 
    174    harness.ok(
    175        threw, "Should not allow [LegacyNullToEmptyString] on dictionary members"
    176    )
    177 
    178    parser = parser.reset()
    179    threw = False
    180    try:
    181        parser.parse(
    182            """
    183            dictionary A {
    184            };
    185            interface X {
    186              undefined doFoo(A arg);
    187            };
    188        """
    189        )
    190        parser.finish()
    191    except WebIDL.WebIDLError:
    192        threw = True
    193 
    194    harness.ok(threw, "Trailing dictionary arg must be optional")
    195 
    196    parser = parser.reset()
    197    threw = False
    198    try:
    199        parser.parse(
    200            """
    201            dictionary A {
    202            };
    203            interface X {
    204              undefined doFoo(optional A arg);
    205            };
    206        """
    207        )
    208        parser.finish()
    209    except WebIDL.WebIDLError:
    210        threw = True
    211 
    212    harness.ok(threw, "Trailing dictionary arg must have a default value")
    213 
    214    parser = parser.reset()
    215    threw = False
    216    try:
    217        parser.parse(
    218            """
    219            dictionary A {
    220            };
    221            interface X {
    222              undefined doFoo((A or DOMString) arg);
    223            };
    224        """
    225        )
    226        parser.finish()
    227    except WebIDL.WebIDLError:
    228        threw = True
    229 
    230    harness.ok(threw, "Trailing union arg containing a dictionary must be optional")
    231 
    232    parser = parser.reset()
    233    threw = False
    234    try:
    235        parser.parse(
    236            """
    237            dictionary A {
    238            };
    239            interface X {
    240              undefined doFoo(optional (A or DOMString) arg);
    241            };
    242        """
    243        )
    244        parser.finish()
    245    except WebIDL.WebIDLError:
    246        threw = True
    247 
    248    harness.ok(
    249        threw, "Trailing union arg containing a dictionary must have a default value"
    250    )
    251 
    252    parser = parser.reset()
    253    threw = False
    254    try:
    255        parser.parse(
    256            """
    257            dictionary A {
    258            };
    259            interface X {
    260              undefined doFoo(A arg1, optional long arg2);
    261            };
    262        """
    263        )
    264        parser.finish()
    265    except WebIDL.WebIDLError:
    266        threw = True
    267 
    268    harness.ok(threw, "Dictionary arg followed by optional arg must be optional")
    269 
    270    parser = parser.reset()
    271    threw = False
    272    try:
    273        parser.parse(
    274            """
    275            dictionary A {
    276            };
    277            interface X {
    278              undefined doFoo(optional A arg1, optional long arg2);
    279            };
    280        """
    281        )
    282        parser.finish()
    283    except WebIDL.WebIDLError:
    284        threw = True
    285 
    286    harness.ok(threw, "Dictionary arg followed by optional arg must have default value")
    287 
    288    parser = parser.reset()
    289    threw = False
    290    try:
    291        parser.parse(
    292            """
    293            dictionary A {
    294            };
    295            interface X {
    296              undefined doFoo(A arg1, optional long arg2, long arg3);
    297            };
    298        """
    299        )
    300        parser.finish()
    301    except WebIDL.WebIDLError:
    302        threw = True
    303 
    304    harness.ok(
    305        not threw,
    306        "Dictionary arg followed by non-optional arg doesn't have to be optional",
    307    )
    308 
    309    parser = parser.reset()
    310    threw = False
    311    try:
    312        parser.parse(
    313            """
    314            dictionary A {
    315            };
    316            interface X {
    317              undefined doFoo((A or DOMString) arg1, optional long arg2);
    318            };
    319        """
    320        )
    321        parser.finish()
    322    except WebIDL.WebIDLError:
    323        threw = True
    324 
    325    harness.ok(
    326        threw,
    327        "Union arg containing dictionary followed by optional arg must be optional",
    328    )
    329 
    330    parser = parser.reset()
    331    threw = False
    332    try:
    333        parser.parse(
    334            """
    335            dictionary A {
    336            };
    337            interface X {
    338              undefined doFoo(optional (A or DOMString) arg1, optional long arg2);
    339            };
    340        """
    341        )
    342        parser.finish()
    343    except WebIDL.WebIDLError:
    344        threw = True
    345 
    346    harness.ok(
    347        threw,
    348        "Union arg containing dictionary followed by optional arg must "
    349        "have a default value",
    350    )
    351 
    352    parser = parser.reset()
    353    parser.parse(
    354        """
    355            dictionary A {
    356            };
    357            interface X {
    358              undefined doFoo(A arg1, long arg2);
    359            };
    360        """
    361    )
    362    parser.finish()
    363    harness.ok(True, "Dictionary arg followed by required arg can be required")
    364 
    365    parser = parser.reset()
    366    threw = False
    367    try:
    368        parser.parse(
    369            """
    370            dictionary A {
    371            };
    372            interface X {
    373              undefined doFoo(optional A? arg1 = {});
    374            };
    375        """
    376        )
    377        parser.finish()
    378    except Exception as x:
    379        threw = x
    380 
    381    harness.ok(threw, "Optional dictionary arg must not be nullable")
    382    harness.ok(
    383        "nullable" in str(threw),
    384        "Must have the expected exception for optional nullable dictionary arg",
    385    )
    386 
    387    parser = parser.reset()
    388    threw = False
    389    try:
    390        parser.parse(
    391            """
    392            dictionary A {
    393              required long x;
    394            };
    395            interface X {
    396              undefined doFoo(A? arg1);
    397            };
    398        """
    399        )
    400        parser.finish()
    401    except Exception as x:
    402        threw = x
    403 
    404    harness.ok(threw, "Required dictionary arg must not be nullable")
    405    harness.ok(
    406        "nullable" in str(threw),
    407        "Must have the expected exception for required nullable dictionary arg",
    408    )
    409 
    410    parser = parser.reset()
    411    threw = False
    412    try:
    413        parser.parse(
    414            """
    415            dictionary A {
    416            };
    417            interface X {
    418              undefined doFoo(optional (A or long)? arg1 = {});
    419            };
    420        """
    421        )
    422        parser.finish()
    423    except Exception as x:
    424        threw = x
    425 
    426    harness.ok(threw, "Dictionary arg must not be in an optional nullable union")
    427    harness.ok(
    428        "nullable" in str(threw),
    429        "Must have the expected exception for optional nullable union "
    430        "arg containing dictionary",
    431    )
    432 
    433    parser = parser.reset()
    434    threw = False
    435    try:
    436        parser.parse(
    437            """
    438            dictionary A {
    439              required long x;
    440            };
    441            interface X {
    442              undefined doFoo((A or long)? arg1);
    443            };
    444        """
    445        )
    446        parser.finish()
    447    except Exception as x:
    448        threw = x
    449 
    450    harness.ok(threw, "Dictionary arg must not be in a required nullable union")
    451    harness.ok(
    452        "nullable" in str(threw),
    453        "Must have the expected exception for required nullable union "
    454        "arg containing dictionary",
    455    )
    456 
    457    parser = parser.reset()
    458    threw = False
    459    try:
    460        parser.parse(
    461            """
    462            dictionary A {
    463            };
    464            interface X {
    465              undefined doFoo(sequence<A?> arg1);
    466            };
    467        """
    468        )
    469        parser.finish()
    470    except WebIDL.WebIDLError:
    471        threw = True
    472 
    473    harness.ok(not threw, "Nullable union should be allowed in a sequence argument")
    474 
    475    parser = parser.reset()
    476    threw = False
    477    try:
    478        parser.parse(
    479            """
    480            dictionary A {
    481            };
    482            interface X {
    483              undefined doFoo(optional (A or long?) arg1);
    484            };
    485        """
    486        )
    487        parser.finish()
    488    except WebIDL.WebIDLError:
    489        threw = True
    490    harness.ok(threw, "Dictionary must not be in a union with a nullable type")
    491 
    492    parser = parser.reset()
    493    threw = False
    494    try:
    495        parser.parse(
    496            """
    497            dictionary A {
    498            };
    499            interface X {
    500              undefined doFoo(optional (long? or A) arg1);
    501            };
    502        """
    503        )
    504        parser.finish()
    505    except WebIDL.WebIDLError:
    506        threw = True
    507    harness.ok(threw, "A nullable type must not be in a union with a dictionary")
    508 
    509    parser = parser.reset()
    510    parser.parse(
    511        """
    512        dictionary A {
    513        };
    514        interface X {
    515          A? doFoo();
    516        };
    517    """
    518    )
    519    parser.finish()
    520    harness.ok(True, "Dictionary return value can be nullable")
    521 
    522    parser = parser.reset()
    523    parser.parse(
    524        """
    525        dictionary A {
    526        };
    527        interface X {
    528          undefined doFoo(optional A arg = {});
    529        };
    530    """
    531    )
    532    parser.finish()
    533    harness.ok(True, "Dictionary arg should actually parse")
    534 
    535    parser = parser.reset()
    536    parser.parse(
    537        """
    538        dictionary A {
    539        };
    540        interface X {
    541          undefined doFoo(optional (A or DOMString) arg = {});
    542        };
    543    """
    544    )
    545    parser.finish()
    546    harness.ok(True, "Union arg containing a dictionary should actually parse")
    547 
    548    parser = parser.reset()
    549    parser.parse(
    550        """
    551        dictionary A {
    552        };
    553        interface X {
    554          undefined doFoo(optional (A or DOMString) arg = "abc");
    555        };
    556    """
    557    )
    558    parser.finish()
    559    harness.ok(
    560        True,
    561        "Union arg containing a dictionary with string default should actually parse",
    562    )
    563 
    564    parser = parser.reset()
    565    threw = False
    566    try:
    567        parser.parse(
    568            """
    569            dictionary Foo {
    570              Foo foo;
    571            };
    572        """
    573        )
    574        parser.finish()
    575    except WebIDL.WebIDLError:
    576        threw = True
    577 
    578    harness.ok(threw, "Member type must not be its Dictionary.")
    579 
    580    parser = parser.reset()
    581    threw = False
    582    try:
    583        parser.parse(
    584            """
    585            dictionary Foo3 : Foo {
    586              short d;
    587            };
    588 
    589            dictionary Foo2 : Foo3 {
    590              boolean c;
    591            };
    592 
    593            dictionary Foo1 : Foo2 {
    594              long a;
    595            };
    596 
    597            dictionary Foo {
    598              Foo1 b;
    599            };
    600        """
    601        )
    602        parser.finish()
    603    except WebIDL.WebIDLError:
    604        threw = True
    605 
    606    harness.ok(
    607        threw,
    608        "Member type must not be a Dictionary that inherits from its Dictionary.",
    609    )
    610 
    611    parser = parser.reset()
    612    threw = False
    613    try:
    614        parser.parse(
    615            """
    616            dictionary Foo {
    617              (Foo or DOMString)[]? b;
    618            };
    619        """
    620        )
    621        parser.finish()
    622    except WebIDL.WebIDLError:
    623        threw = True
    624 
    625    harness.ok(
    626        threw,
    627        "Member type must not be a Nullable type "
    628        "whose inner type includes its Dictionary.",
    629    )
    630 
    631    parser = parser.reset()
    632    threw = False
    633    try:
    634        parser.parse(
    635            """
    636            dictionary Foo {
    637              (DOMString or Foo) b;
    638            };
    639        """
    640        )
    641        parser.finish()
    642    except WebIDL.WebIDLError:
    643        threw = True
    644 
    645    harness.ok(
    646        threw,
    647        "Member type must not be a Union type, one of "
    648        "whose member types includes its Dictionary.",
    649    )
    650 
    651    parser = parser.reset()
    652    threw = False
    653    try:
    654        parser.parse(
    655            """
    656            dictionary Foo {
    657              sequence<sequence<sequence<Foo>>> c;
    658            };
    659        """
    660        )
    661        parser.finish()
    662    except WebIDL.WebIDLError:
    663        threw = True
    664 
    665    harness.ok(
    666        threw,
    667        "Member type must not be a Sequence type "
    668        "whose element type includes its Dictionary.",
    669    )
    670 
    671    parser = parser.reset()
    672    threw = False
    673    try:
    674        parser.parse(
    675            """
    676            dictionary Foo {
    677              (DOMString or Foo)[] d;
    678            };
    679        """
    680        )
    681        parser.finish()
    682    except WebIDL.WebIDLError:
    683        threw = True
    684 
    685    harness.ok(
    686        threw,
    687        "Member type must not be an Array type "
    688        "whose element type includes its Dictionary.",
    689    )
    690 
    691    parser = parser.reset()
    692    threw = False
    693    try:
    694        parser.parse(
    695            """
    696            dictionary Foo {
    697              Foo1 b;
    698            };
    699 
    700            dictionary Foo3 {
    701              Foo d;
    702            };
    703 
    704            dictionary Foo2 : Foo3 {
    705              short c;
    706            };
    707 
    708            dictionary Foo1 : Foo2 {
    709              long a;
    710            };
    711        """
    712        )
    713        parser.finish()
    714    except WebIDL.WebIDLError:
    715        threw = True
    716 
    717    harness.ok(
    718        threw,
    719        "Member type must not be a Dictionary, one of whose "
    720        "members or inherited members has a type that includes "
    721        "its Dictionary.",
    722    )
    723 
    724    parser = parser.reset()
    725    threw = False
    726    try:
    727        parser.parse(
    728            """
    729            dictionary Foo {
    730            };
    731 
    732            dictionary Bar {
    733              Foo? d;
    734            };
    735        """
    736        )
    737        parser.finish()
    738    except WebIDL.WebIDLError:
    739        threw = True
    740 
    741    harness.ok(threw, "Member type must not be a nullable dictionary")
    742 
    743    parser = parser.reset()
    744    parser.parse(
    745        """
    746        dictionary Foo {
    747          unrestricted float  urFloat = 0;
    748          unrestricted float  urFloat2 = 1.1;
    749          unrestricted float  urFloat3 = -1.1;
    750          unrestricted float? urFloat4 = null;
    751          unrestricted float  infUrFloat = Infinity;
    752          unrestricted float  negativeInfUrFloat = -Infinity;
    753          unrestricted float  nanUrFloat = NaN;
    754 
    755          unrestricted double  urDouble = 0;
    756          unrestricted double  urDouble2 = 1.1;
    757          unrestricted double  urDouble3 = -1.1;
    758          unrestricted double? urDouble4 = null;
    759          unrestricted double  infUrDouble = Infinity;
    760          unrestricted double  negativeInfUrDouble = -Infinity;
    761          unrestricted double  nanUrDouble = NaN;
    762        };
    763    """
    764    )
    765    parser.finish()
    766    harness.ok(True, "Parsing default values for unrestricted types succeeded.")
    767 
    768    parser = parser.reset()
    769    threw = False
    770    try:
    771        parser.parse(
    772            """
    773            dictionary Foo {
    774              double f = Infinity;
    775            };
    776        """
    777        )
    778        parser.finish()
    779    except WebIDL.WebIDLError:
    780        threw = True
    781 
    782    harness.ok(threw, "Only unrestricted values can be initialized to Infinity")
    783 
    784    parser = parser.reset()
    785    threw = False
    786    try:
    787        parser.parse(
    788            """
    789            dictionary Foo {
    790              double f = -Infinity;
    791            };
    792        """
    793        )
    794        parser.finish()
    795    except WebIDL.WebIDLError:
    796        threw = True
    797 
    798    harness.ok(threw, "Only unrestricted values can be initialized to -Infinity")
    799 
    800    parser = parser.reset()
    801    threw = False
    802    try:
    803        parser.parse(
    804            """
    805            dictionary Foo {
    806              double f = NaN;
    807            };
    808        """
    809        )
    810        parser.finish()
    811    except WebIDL.WebIDLError:
    812        threw = True
    813 
    814    harness.ok(threw, "Only unrestricted values can be initialized to NaN")
    815 
    816    parser = parser.reset()
    817    threw = False
    818    try:
    819        parser.parse(
    820            """
    821            dictionary Foo {
    822              float f = Infinity;
    823            };
    824        """
    825        )
    826        parser.finish()
    827    except WebIDL.WebIDLError:
    828        threw = True
    829 
    830    harness.ok(threw, "Only unrestricted values can be initialized to Infinity")
    831 
    832    parser = parser.reset()
    833    threw = False
    834    try:
    835        parser.parse(
    836            """
    837            dictionary Foo {
    838              float f = -Infinity;
    839            };
    840        """
    841        )
    842        parser.finish()
    843    except WebIDL.WebIDLError:
    844        threw = True
    845 
    846    harness.ok(threw, "Only unrestricted values can be initialized to -Infinity")
    847 
    848    parser = parser.reset()
    849    threw = False
    850    try:
    851        parser.parse(
    852            """
    853            dictionary Foo {
    854              float f = NaN;
    855            };
    856        """
    857        )
    858        parser.finish()
    859    except WebIDL.WebIDLError:
    860        threw = True
    861 
    862    harness.ok(threw, "Only unrestricted values can be initialized to NaN")
    863 
    864    parser = parser.reset()
    865    threw = False
    866    try:
    867        parser.parse(
    868            """
    869            dictionary Foo {
    870              long module;
    871            };
    872        """
    873        )
    874        parser.finish()
    875    except WebIDL.WebIDLError:
    876        threw = True
    877 
    878    harness.ok(not threw, "Should be able to use 'module' as a dictionary member name")