tor-browser

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

test_MIME_params.js (21622B)


      1 /**
      2 * Tests for parsing header fields using the syntax used in
      3 * Content-Disposition and Content-Type
      4 *
      5 * See also https://bugzilla.mozilla.org/show_bug.cgi?id=609667
      6 */
      7 
      8 "use strict";
      9 
     10 var BS = "\\";
     11 var DQUOTE = '"';
     12 
     13 // Test array:
     14 //  - element 0: "Content-Disposition" header to test
     15 //  under MIME (email):
     16 //  - element 1: correct value returned for disposition-type (empty param name)
     17 //  - element 2: correct value for filename returned
     18 //  under HTTP:
     19 // (currently supports continuations; expected results without continuations
     20 // are commented out for now)
     21 //  - element 3: correct value returned for disposition-type (empty param name)
     22 //  - element 4: correct value for filename returned
     23 //
     24 // 3 and 4 may be left out if they are identical
     25 
     26 var tests = [
     27  // No filename parameter: return nothing
     28  ["attachment;", "attachment", Cr.NS_ERROR_INVALID_ARG],
     29 
     30  // basic
     31  ["attachment; filename=basic", "attachment", "basic"],
     32 
     33  // extended
     34  ["attachment; filename*=UTF-8''extended", "attachment", "extended"],
     35 
     36  // prefer extended to basic (bug 588781)
     37  [
     38    "attachment; filename=basic; filename*=UTF-8''extended",
     39    "attachment",
     40    "extended",
     41  ],
     42 
     43  // prefer extended to basic (bug 588781)
     44  [
     45    "attachment; filename*=UTF-8''extended; filename=basic",
     46    "attachment",
     47    "extended",
     48  ],
     49 
     50  // use first basic value (invalid; error recovery)
     51  ["attachment; filename=first; filename=wrong", "attachment", "first"],
     52 
     53  // old school bad HTTP servers: missing 'attachment' or 'inline'
     54  // (invalid; error recovery)
     55  ["filename=old", "filename=old", "old"],
     56 
     57  ["attachment; filename*=UTF-8''extended", "attachment", "extended"],
     58 
     59  // continuations not part of RFC 5987 (bug 610054)
     60  [
     61    "attachment; filename*0=foo; filename*1=bar",
     62    "attachment",
     63    "foobar",
     64    /* "attachment", Cr.NS_ERROR_INVALID_ARG */
     65  ],
     66 
     67  // Return first continuation (invalid; error recovery)
     68  [
     69    "attachment; filename*0=first; filename*0=wrong; filename=basic",
     70    "attachment",
     71    "first",
     72    /* "attachment", "basic" */
     73  ],
     74 
     75  // Only use correctly ordered continuations  (invalid; error recovery)
     76  [
     77    "attachment; filename*0=first; filename*1=second; filename*0=wrong",
     78    "attachment",
     79    "firstsecond",
     80    /* "attachment", Cr.NS_ERROR_INVALID_ARG */
     81  ],
     82 
     83  // prefer continuation to basic (unless RFC 5987)
     84  [
     85    "attachment; filename=basic; filename*0=foo; filename*1=bar",
     86    "attachment",
     87    "foobar",
     88    /* "attachment", "basic" */
     89  ],
     90 
     91  // Prefer extended to basic and/or (broken or not) continuation
     92  // (invalid; error recovery)
     93  [
     94    "attachment; filename=basic; filename*0=first; filename*0=wrong; filename*=UTF-8''extended",
     95    "attachment",
     96    "extended",
     97  ],
     98 
     99  // RFC 2231 not clear on correct outcome: we prefer non-continued extended
    100  // (invalid; error recovery)
    101  [
    102    "attachment; filename=basic; filename*=UTF-8''extended; filename*0=foo; filename*1=bar",
    103    "attachment",
    104    "extended",
    105  ],
    106 
    107  // Gaps should result in returning only value until gap hit
    108  // (invalid; error recovery)
    109  [
    110    "attachment; filename*0=foo; filename*2=bar",
    111    "attachment",
    112    "foo",
    113    /* "attachment", Cr.NS_ERROR_INVALID_ARG */
    114  ],
    115 
    116  // Don't allow leading 0's (*01) (invalid; error recovery)
    117  [
    118    "attachment; filename*0=foo; filename*01=bar",
    119    "attachment",
    120    "foo",
    121    /* "attachment", Cr.NS_ERROR_INVALID_ARG */
    122  ],
    123 
    124  // continuations should prevail over non-extended (unless RFC 5987)
    125  [
    126    "attachment; filename=basic; filename*0*=UTF-8''multi;\r\n" +
    127      " filename*1=line;\r\n" +
    128      " filename*2*=%20extended",
    129    "attachment",
    130    "multiline extended",
    131    /* "attachment", "basic" */
    132  ],
    133 
    134  // Gaps should result in returning only value until gap hit
    135  // (invalid; error recovery)
    136  [
    137    "attachment; filename=basic; filename*0*=UTF-8''multi;\r\n" +
    138      " filename*1=line;\r\n" +
    139      " filename*3*=%20extended",
    140    "attachment",
    141    "multiline",
    142    /* "attachment", "basic" */
    143  ],
    144 
    145  // First series, only please, and don't slurp up higher elements (*2 in this
    146  // case) from later series into earlier one (invalid; error recovery)
    147  [
    148    "attachment; filename=basic; filename*0*=UTF-8''multi;\r\n" +
    149      " filename*1=line;\r\n" +
    150      " filename*0*=UTF-8''wrong;\r\n" +
    151      " filename*1=bad;\r\n" +
    152      " filename*2=evil",
    153    "attachment",
    154    "multiline",
    155    /* "attachment", "basic" */
    156  ],
    157 
    158  // RFC 2231 not clear on correct outcome: we prefer non-continued extended
    159  // (invalid; error recovery)
    160  [
    161    "attachment; filename=basic; filename*0=UTF-8''multi\r\n;" +
    162      " filename*=UTF-8''extended;\r\n" +
    163      " filename*1=line;\r\n" +
    164      " filename*2*=%20extended",
    165    "attachment",
    166    "extended",
    167  ],
    168 
    169  // sneaky: if unescaped, make sure we leave UTF-8'' in value
    170  [
    171    "attachment; filename*0=UTF-8''unescaped;\r\n" +
    172      " filename*1*=%20so%20includes%20UTF-8''%20in%20value",
    173    "attachment",
    174    "UTF-8''unescaped so includes UTF-8'' in value",
    175    /* "attachment", Cr.NS_ERROR_INVALID_ARG */
    176  ],
    177 
    178  // sneaky: if unescaped, make sure we leave UTF-8'' in value
    179  [
    180    "attachment; filename=basic; filename*0=UTF-8''unescaped;\r\n" +
    181      " filename*1*=%20so%20includes%20UTF-8''%20in%20value",
    182    "attachment",
    183    "UTF-8''unescaped so includes UTF-8'' in value",
    184    /* "attachment", "basic" */
    185  ],
    186 
    187  // Prefer basic over invalid continuation
    188  // (invalid; error recovery)
    189  [
    190    "attachment; filename=basic; filename*1=multi;\r\n" +
    191      " filename*2=line;\r\n" +
    192      " filename*3*=%20extended",
    193    "attachment",
    194    "basic",
    195  ],
    196 
    197  // support digits over 10
    198  [
    199    "attachment; filename=basic; filename*0*=UTF-8''0;\r\n" +
    200      " filename*1=1; filename*2=2;filename*3=3;filename*4=4;filename*5=5;\r\n" +
    201      " filename*6=6; filename*7=7;filename*8=8;filename*9=9;filename*10=a;\r\n" +
    202      " filename*11=b; filename*12=c;filename*13=d;filename*14=e;filename*15=f\r\n",
    203    "attachment",
    204    "0123456789abcdef",
    205    /* "attachment", "basic" */
    206  ],
    207 
    208  // support digits over 10 (detect gaps)
    209  [
    210    "attachment; filename=basic; filename*0*=UTF-8''0;\r\n" +
    211      " filename*1=1; filename*2=2;filename*3=3;filename*4=4;filename*5=5;\r\n" +
    212      " filename*6=6; filename*7=7;filename*8=8;filename*9=9;filename*10=a;\r\n" +
    213      " filename*11=b; filename*12=c;filename*14=e\r\n",
    214    "attachment",
    215    "0123456789abc",
    216    /* "attachment", "basic" */
    217  ],
    218 
    219  // return nothing: invalid
    220  // (invalid; error recovery)
    221  [
    222    "attachment; filename*1=multi;\r\n" +
    223      " filename*2=line;\r\n" +
    224      " filename*3*=%20extended",
    225    "attachment",
    226    Cr.NS_ERROR_INVALID_ARG,
    227  ],
    228 
    229  // Bug 272541: Empty disposition type treated as "attachment"
    230 
    231  // sanity check
    232  [
    233    "attachment; filename=foo.html",
    234    "attachment",
    235    "foo.html",
    236    "attachment",
    237    "foo.html",
    238  ],
    239 
    240  // the actual bug
    241  [
    242    "; filename=foo.html",
    243    Cr.NS_ERROR_FIRST_HEADER_FIELD_COMPONENT_EMPTY,
    244    "foo.html",
    245    Cr.NS_ERROR_FIRST_HEADER_FIELD_COMPONENT_EMPTY,
    246    "foo.html",
    247  ],
    248 
    249  // regression check, but see bug 671204
    250  [
    251    "filename=foo.html",
    252    "filename=foo.html",
    253    "foo.html",
    254    "filename=foo.html",
    255    "foo.html",
    256  ],
    257 
    258  // Bug 384571: RFC 2231 parameters not decoded when appearing in reversed order
    259 
    260  // check ordering
    261  [
    262    "attachment; filename=basic; filename*0*=UTF-8''0;\r\n" +
    263      " filename*1=1; filename*2=2;filename*3=3;filename*4=4;filename*5=5;\r\n" +
    264      " filename*6=6; filename*7=7;filename*8=8;filename*9=9;filename*10=a;\r\n" +
    265      " filename*11=b; filename*12=c;filename*13=d;filename*15=f;filename*14=e;\r\n",
    266    "attachment",
    267    "0123456789abcdef",
    268    /* "attachment", "basic" */
    269  ],
    270 
    271  // check non-digits in sequence numbers
    272  [
    273    "attachment; filename=basic; filename*0*=UTF-8''0;\r\n" +
    274      " filename*1a=1\r\n",
    275    "attachment",
    276    "0",
    277    /* "attachment", "basic" */
    278  ],
    279 
    280  // check duplicate sequence numbers
    281  [
    282    "attachment; filename=basic; filename*0*=UTF-8''0;\r\n" +
    283      " filename*0=bad; filename*1=1;\r\n",
    284    "attachment",
    285    "0",
    286    /* "attachment", "basic" */
    287  ],
    288 
    289  // check overflow
    290  [
    291    "attachment; filename=basic; filename*0*=UTF-8''0;\r\n" +
    292      " filename*11111111111111111111111111111111111111111111111111111111111=1",
    293    "attachment",
    294    "0",
    295    /* "attachment", "basic" */
    296  ],
    297 
    298  // check underflow
    299  [
    300    // eslint-disable-next-line no-useless-concat
    301    "attachment; filename=basic; filename*0*=UTF-8''0;\r\n" + " filename*-1=1",
    302    "attachment",
    303    "0",
    304    /* "attachment", "basic" */
    305  ],
    306 
    307  // check mixed token/quoted-string
    308  [
    309    'attachment; filename=basic; filename*0="0";\r\n' +
    310      " filename*1=1;\r\n" +
    311      " filename*2*=%32",
    312    "attachment",
    313    "012",
    314    /* "attachment", "basic" */
    315  ],
    316 
    317  // check empty sequence number
    318  [
    319    "attachment; filename=basic; filename**=UTF-8''0\r\n",
    320    "attachment",
    321    "basic",
    322    "attachment",
    323    "basic",
    324  ],
    325 
    326  // Bug 419157: ensure that a MIME parameter with no charset information
    327  // fallbacks to Latin-1
    328 
    329  [
    330    "attachment;filename=IT839\x04\xB5(m8)2.pdf;",
    331    "attachment",
    332    "IT839\u0004\u00b5(m8)2.pdf",
    333  ],
    334 
    335  // Bug 588389: unescaping backslashes in quoted string parameters
    336 
    337  // '\"', should be parsed as '"'
    338  [
    339    "attachment; filename=" + DQUOTE + (BS + DQUOTE) + DQUOTE,
    340    "attachment",
    341    DQUOTE,
    342  ],
    343 
    344  // 'a\"b', should be parsed as 'a"b'
    345  [
    346    "attachment; filename=" + DQUOTE + "a" + (BS + DQUOTE) + "b" + DQUOTE,
    347    "attachment",
    348    "a" + DQUOTE + "b",
    349  ],
    350 
    351  // '\x', should be parsed as 'x'
    352  ["attachment; filename=" + DQUOTE + (BS + "x") + DQUOTE, "attachment", "x"],
    353 
    354  // test empty param (quoted-string)
    355  ["attachment; filename=" + DQUOTE + DQUOTE, "attachment", ""],
    356 
    357  // test empty param
    358  ["attachment; filename=", "attachment", ""],
    359 
    360  // Bug 601933: RFC 2047 does not apply to parameters (at least in HTTP)
    361  [
    362    "attachment; filename==?ISO-8859-1?Q?foo-=E4.html?=",
    363    "attachment",
    364    "foo-\u00e4.html",
    365    /* "attachment", "=?ISO-8859-1?Q?foo-=E4.html?=" */
    366  ],
    367 
    368  [
    369    'attachment; filename="=?ISO-8859-1?Q?foo-=E4.html?="',
    370    "attachment",
    371    "foo-\u00e4.html",
    372    /* "attachment", "=?ISO-8859-1?Q?foo-=E4.html?=" */
    373  ],
    374 
    375  // format sent by GMail as of 2012-07-23 (5987 overrides 2047)
    376  [
    377    "attachment; filename=\"=?ISO-8859-1?Q?foo-=E4.html?=\"; filename*=UTF-8''5987",
    378    "attachment",
    379    "5987",
    380  ],
    381 
    382  // Bug 651185: double quotes around 2231/5987 encoded param
    383  // Change reverted to backwards compat issues with various web services,
    384  // such as OWA (Bug 703015), plus similar problems in Thunderbird. If this
    385  // is tried again in the future, email probably needs to be special-cased.
    386 
    387  // sanity check
    388  ["attachment; filename*=utf-8''%41", "attachment", "A"],
    389 
    390  // the actual bug
    391  [
    392    "attachment; filename*=" + DQUOTE + "utf-8''%41" + DQUOTE,
    393    "attachment",
    394    "A",
    395  ],
    396  // previously with the fix for 651185:
    397  // "attachment", Cr.NS_ERROR_INVALID_ARG],
    398 
    399  // Bug 670333: Content-Disposition parser does not require presence of "="
    400  // in params
    401 
    402  // sanity check
    403  ["attachment; filename*=UTF-8''foo-%41.html", "attachment", "foo-A.html"],
    404 
    405  // the actual bug
    406  [
    407    "attachment; filename *=UTF-8''foo-%41.html",
    408    "attachment",
    409    Cr.NS_ERROR_INVALID_ARG,
    410  ],
    411 
    412  // the actual bug, without 2231/5987 encoding
    413  ["attachment; filename X", "attachment", Cr.NS_ERROR_INVALID_ARG],
    414 
    415  // sanity check with WS on both sides
    416  ["attachment; filename = foo-A.html", "attachment", "foo-A.html"],
    417 
    418  // Bug 685192: in RFC2231/5987 encoding, a missing charset field should be
    419  // treated as error
    420 
    421  // the actual bug
    422  ["attachment; filename*=''foo", "attachment", "foo"],
    423  // previously with the fix for 692574:
    424  // "attachment", Cr.NS_ERROR_INVALID_ARG],
    425 
    426  // sanity check
    427  ["attachment; filename*=a''foo", "attachment", "foo"],
    428 
    429  // Bug 692574: RFC2231/5987 decoding should not tolerate missing single
    430  // quotes
    431 
    432  // one missing
    433  ["attachment; filename*=UTF-8'foo-%41.html", "attachment", "foo-A.html"],
    434  // previously with the fix for 692574:
    435  // "attachment", Cr.NS_ERROR_INVALID_ARG],
    436 
    437  // both missing
    438  ["attachment; filename*=foo-%41.html", "attachment", "foo-A.html"],
    439  // previously with the fix for 692574:
    440  // "attachment", Cr.NS_ERROR_INVALID_ARG],
    441 
    442  // make sure fallback works
    443  [
    444    "attachment; filename*=UTF-8'foo-%41.html; filename=bar.html",
    445    "attachment",
    446    "foo-A.html",
    447  ],
    448  // previously with the fix for 692574:
    449  // "attachment", "bar.html"],
    450 
    451  // Bug 693806: RFC2231/5987 encoding: charset information should be treated
    452  // as authoritative
    453 
    454  // UTF-8 labeled ISO-8859-1
    455  ["attachment; filename*=ISO-8859-1''%c3%a4", "attachment", "\u00c3\u00a4"],
    456 
    457  // UTF-8 labeled ISO-8859-1, but with octets not allowed in ISO-8859-1
    458  // accepts x82, understands it as Win1252, maps it to Unicode \u20a1
    459  [
    460    "attachment; filename*=ISO-8859-1''%e2%82%ac",
    461    "attachment",
    462    "\u00e2\u201a\u00ac",
    463  ],
    464 
    465  // defective UTF-8
    466  ["attachment; filename*=UTF-8''A%e4B", "attachment", Cr.NS_ERROR_INVALID_ARG],
    467 
    468  // defective UTF-8, with fallback
    469  [
    470    "attachment; filename*=UTF-8''A%e4B; filename=fallback",
    471    "attachment",
    472    "fallback",
    473  ],
    474 
    475  // defective UTF-8 (continuations), with fallback
    476  [
    477    "attachment; filename*0*=UTF-8''A%e4B; filename=fallback",
    478    "attachment",
    479    "fallback",
    480  ],
    481 
    482  // check that charsets aren't mixed up
    483  [
    484    "attachment; filename*0*=ISO-8859-15''euro-sign%3d%a4; filename*=ISO-8859-1''currency-sign%3d%a4",
    485    "attachment",
    486    "currency-sign=\u00a4",
    487  ],
    488 
    489  // same as above, except reversed
    490  [
    491    "attachment; filename*=ISO-8859-1''currency-sign%3d%a4; filename*0*=ISO-8859-15''euro-sign%3d%a4",
    492    "attachment",
    493    "currency-sign=\u00a4",
    494  ],
    495 
    496  // Bug 704989: add workaround for broken Outlook Web App (OWA)
    497  // attachment handling
    498 
    499  ['attachment; filename*="a%20b"', "attachment", "a b"],
    500 
    501  // Bug 717121: crash nsMIMEHeaderParamImpl::DoParameterInternal
    502 
    503  ['attachment; filename="', "attachment", ""],
    504 
    505  // We used to read past string if last param w/o = and ;
    506  // Note: was only detected on windows PGO builds
    507  ["attachment; filename=foo; trouble", "attachment", "foo"],
    508 
    509  // Same, followed by space, hits another case
    510  ["attachment; filename=foo; trouble ", "attachment", "foo"],
    511 
    512  ["attachment", "attachment", Cr.NS_ERROR_INVALID_ARG],
    513 
    514  // Bug 730574: quoted-string in RFC2231-continuations not handled
    515 
    516  [
    517    'attachment; filename=basic; filename*0="foo"; filename*1="\\b\\a\\r.html"',
    518    "attachment",
    519    "foobar.html",
    520    /* "attachment", "basic" */
    521  ],
    522 
    523  // unmatched escape char
    524  [
    525    'attachment; filename=basic; filename*0="foo"; filename*1="\\b\\a\\',
    526    "attachment",
    527    "fooba\\",
    528    /* "attachment", "basic" */
    529  ],
    530 
    531  // Bug 732369: Content-Disposition parser does not require presence of ";" between params
    532  // optimally, this would not even return the disposition type "attachment"
    533 
    534  [
    535    "attachment; extension=bla filename=foo",
    536    "attachment",
    537    Cr.NS_ERROR_INVALID_ARG,
    538  ],
    539 
    540  // Bug 1440677 - spaces inside filenames ought to be quoted, but too many
    541  // servers do the wrong thing and most browsers accept this, so we were
    542  // forced to do the same for compat.
    543  ["attachment; filename=foo extension=bla", "attachment", "foo extension=bla"],
    544 
    545  ["attachment filename=foo", "attachment", Cr.NS_ERROR_INVALID_ARG],
    546 
    547  // Bug 777687: handling of broken %escapes
    548 
    549  ["attachment; filename*=UTF-8''f%oo; filename=bar", "attachment", "bar"],
    550 
    551  ["attachment; filename*=UTF-8''foo%; filename=bar", "attachment", "bar"],
    552 
    553  // Bug 783502 - xpcshell test netwerk/test/unit/test_MIME_params.js fails on AddressSanitizer
    554  ['attachment; filename="\\b\\a\\', "attachment", "ba\\"],
    555 
    556  // Bug 1412213 - do continue to parse, behind an empty parameter
    557  ["attachment; ; filename=foo", "attachment", "foo"],
    558 
    559  // Bug 1412213 - do continue to parse, behind a parameter w/o =
    560  ["attachment; badparameter; filename=foo", "attachment", "foo"],
    561 
    562  // Bug 1440677 - spaces inside filenames ought to be quoted, but too many
    563  // servers do the wrong thing and most browsers accept this, so we were
    564  // forced to do the same for compat.
    565  ["attachment; filename=foo bar.html", "attachment", "foo bar.html"],
    566  // Note: we keep the tab character, but later validation will replace with a space,
    567  // as file systems do not like tab characters.
    568  ["attachment; filename=foo\tbar.html", "attachment", "foo\tbar.html"],
    569  // Newlines get stripped completely (in practice, http header parsing may
    570  // munge these into spaces before they get to us, but we should check we deal
    571  // with them either way):
    572  ["attachment; filename=foo\nbar.html", "attachment", "foobar.html"],
    573  ["attachment; filename=foo\r\nbar.html", "attachment", "foobar.html"],
    574  ["attachment; filename=foo\rbar.html", "attachment", "foobar.html"],
    575 
    576  // Trailing rubbish shouldn't matter:
    577  ["attachment; filename=foo bar; garbage", "attachment", "foo bar"],
    578  ["attachment; filename=foo bar; extension=blah", "attachment", "foo bar"],
    579 
    580  // Check that whitespace processing can't crash.
    581  ["attachment; filename =      ", "attachment", ""],
    582 
    583  // Bug 1784348
    584  [
    585    "attachment; filename=foo.exe\0.pdf",
    586    Cr.NS_ERROR_ILLEGAL_VALUE,
    587    Cr.NS_ERROR_INVALID_ARG,
    588  ],
    589  [
    590    "attachment; filename=\0\0foo\0",
    591    Cr.NS_ERROR_ILLEGAL_VALUE,
    592    Cr.NS_ERROR_INVALID_ARG,
    593  ],
    594  ["attachment; filename=foo\0\0\0", "attachment", "foo"],
    595  ["attachment; filename=\0\0\0", "attachment", ""],
    596 ];
    597 
    598 var rfc5987paramtests = [
    599  [
    600    // basic test
    601    "UTF-8'language'value",
    602    "value",
    603    "language",
    604    Cr.NS_OK,
    605  ],
    606  [
    607    // percent decoding
    608    "UTF-8''1%202",
    609    "1 2",
    610    "",
    611    Cr.NS_OK,
    612  ],
    613  [
    614    // UTF-8
    615    "UTF-8''%c2%a3%20and%20%e2%82%ac%20rates",
    616    "\u00a3 and \u20ac rates",
    617    "",
    618    Cr.NS_OK,
    619  ],
    620  [
    621    // missing charset
    622    "''abc",
    623    "",
    624    "",
    625    Cr.NS_ERROR_INVALID_ARG,
    626  ],
    627  [
    628    // ISO-8859-1: unsupported
    629    "ISO-8859-1''%A3%20rates",
    630    "",
    631    "",
    632    Cr.NS_ERROR_INVALID_ARG,
    633  ],
    634  [
    635    // unknown charset
    636    "foo''abc",
    637    "",
    638    "",
    639    Cr.NS_ERROR_INVALID_ARG,
    640  ],
    641  [
    642    // missing component
    643    "abc",
    644    "",
    645    "",
    646    Cr.NS_ERROR_INVALID_ARG,
    647  ],
    648  [
    649    // missing component
    650    "'abc",
    651    "",
    652    "",
    653    Cr.NS_ERROR_INVALID_ARG,
    654  ],
    655  [
    656    // illegal chars
    657    "UTF-8''a b",
    658    "",
    659    "",
    660    Cr.NS_ERROR_INVALID_ARG,
    661  ],
    662  [
    663    // broken % escapes
    664    "UTF-8''a%zz",
    665    "",
    666    "",
    667    Cr.NS_ERROR_INVALID_ARG,
    668  ],
    669  [
    670    // broken % escapes
    671    "UTF-8''a%b",
    672    "",
    673    "",
    674    Cr.NS_ERROR_INVALID_ARG,
    675  ],
    676  [
    677    // broken % escapes
    678    "UTF-8''a%",
    679    "",
    680    "",
    681    Cr.NS_ERROR_INVALID_ARG,
    682  ],
    683  [
    684    // broken UTF-8
    685    "UTF-8''%A3%20rates",
    686    "",
    687    "",
    688    0x8050000e /* NS_ERROR_UDEC_ILLEGALINPUT */,
    689  ],
    690 ];
    691 
    692 function do_tests(whichRFC) {
    693  var mhp = Cc["@mozilla.org/network/mime-hdrparam;1"].getService(
    694    Ci.nsIMIMEHeaderParam
    695  );
    696 
    697  var unused = { value: null };
    698 
    699  for (var i = 0; i < tests.length; ++i) {
    700    dump("Testing #" + i + ": " + tests[i] + "\n");
    701 
    702    // check disposition type
    703    var expectedDt =
    704      tests[i].length == 3 || whichRFC == 0 ? tests[i][1] : tests[i][3];
    705 
    706    try {
    707      let result;
    708 
    709      if (whichRFC == 0) {
    710        result = mhp.getParameter(tests[i][0], "", "UTF-8", true, unused);
    711      } else {
    712        result = mhp.getParameterHTTP(tests[i][0], "", "UTF-8", true, unused);
    713      }
    714 
    715      Assert.equal(result, expectedDt);
    716    } catch (e) {
    717      // Tests can also succeed by expecting to fail with given error code
    718      if (e.result) {
    719        // Allow following tests to run by catching exception from do_check_eq()
    720        try {
    721          Assert.equal(e.result, expectedDt);
    722        } catch (e1) {}
    723      }
    724      continue;
    725    }
    726 
    727    // check filename parameter
    728    var expectedFn =
    729      tests[i].length == 3 || whichRFC == 0 ? tests[i][2] : tests[i][4];
    730 
    731    try {
    732      let result;
    733 
    734      if (whichRFC == 0) {
    735        result = mhp.getParameter(
    736          tests[i][0],
    737          "filename",
    738          "UTF-8",
    739          true,
    740          unused
    741        );
    742      } else {
    743        result = mhp.getParameterHTTP(
    744          tests[i][0],
    745          "filename",
    746          "UTF-8",
    747          true,
    748          unused
    749        );
    750      }
    751 
    752      Assert.equal(result, expectedFn);
    753    } catch (e) {
    754      // Tests can also succeed by expecting to fail with given error code
    755      if (e.result) {
    756        // Allow following tests to run by catching exception from do_check_eq()
    757        try {
    758          Assert.equal(e.result, expectedFn);
    759        } catch (e1) {}
    760      }
    761      continue;
    762    }
    763  }
    764 }
    765 
    766 function test_decode5987Param() {
    767  var mhp = Cc["@mozilla.org/network/mime-hdrparam;1"].getService(
    768    Ci.nsIMIMEHeaderParam
    769  );
    770 
    771  for (var i = 0; i < rfc5987paramtests.length; ++i) {
    772    dump("Testing #" + i + ": " + rfc5987paramtests[i] + "\n");
    773 
    774    var lang = {};
    775    try {
    776      var decoded = mhp.decodeRFC5987Param(rfc5987paramtests[i][0], lang);
    777      if (rfc5987paramtests[i][3] == Cr.NS_OK) {
    778        Assert.equal(rfc5987paramtests[i][1], decoded);
    779        Assert.equal(rfc5987paramtests[i][2], lang.value);
    780      } else {
    781        Assert.equal(rfc5987paramtests[i][3], "instead got: " + decoded);
    782      }
    783    } catch (e) {
    784      Assert.equal(rfc5987paramtests[i][3], e.result);
    785    }
    786  }
    787 }
    788 
    789 function run_test() {
    790  // Test RFC 2231 (complete header field values)
    791  do_tests(0);
    792 
    793  // Test RFC 5987 (complete header field values)
    794  do_tests(1);
    795 
    796  // tests for RFC5987 parameter parsing
    797  test_decode5987Param();
    798 }