tor-browser

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

test_TextDecoder.js (26366B)


      1 /*
      2 * test_TextDecoderOptions.js
      3 * bug 764234 tests
      4 */
      5 
      6 /* eslint-env mozilla/testharness */
      7 
      8 function runTextDecoderOptions() {
      9  const data = [
     10    0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab,
     11    0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
     12    0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3,
     13    0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
     14    0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdf,
     15    0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb,
     16    0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
     17    0xf8, 0xf9, 0xfa, 0xfb,
     18  ];
     19 
     20  const expectedString =
     21    "\u00a0\u0e01\u0e02\u0e03\u0e04\u0e05\u0e06\u0e07" +
     22    "\u0e08\u0e09\u0e0a\u0e0b\u0e0c\u0e0d\u0e0e\u0e0f" +
     23    "\u0e10\u0e11\u0e12\u0e13\u0e14\u0e15\u0e16\u0e17" +
     24    "\u0e18\u0e19\u0e1a\u0e1b\u0e1c\u0e1d\u0e1e\u0e1f" +
     25    "\u0e20\u0e21\u0e22\u0e23\u0e24\u0e25\u0e26\u0e27" +
     26    "\u0e28\u0e29\u0e2a\u0e2b\u0e2c\u0e2d\u0e2e\u0e2f" +
     27    "\u0e30\u0e31\u0e32\u0e33\u0e34\u0e35\u0e36\u0e37" +
     28    "\u0e38\u0e39\u0e3a\u0e3f\u0e40\u0e41\u0e42\u0e43" +
     29    "\u0e44\u0e45\u0e46\u0e47\u0e48\u0e49\u0e4a\u0e4b" +
     30    "\u0e4c\u0e4d\u0e4e\u0e4f\u0e50\u0e51\u0e52\u0e53" +
     31    "\u0e54\u0e55\u0e56\u0e57\u0e58\u0e59\u0e5a\u0e5b";
     32 
     33  test(testDecoderGetEncoding, "testDecoderGetEncoding");
     34  test(testDecodeGreek, "testDecodeGreek");
     35  test(function () {
     36    testConstructorFatalOption(data, expectedString);
     37  }, "testConstructorFatalOption");
     38  test(function () {
     39    testConstructorEncodingOption(data, expectedString);
     40  }, "testConstructorEncodingOption");
     41  test(function () {
     42    testDecodeStreamOption(data, expectedString);
     43  }, "testDecodeStreamOption");
     44  test(testDecodeStreamCompositions, "testDecodeStreamCompositions");
     45  test(function () {
     46    testDecodeABVOption(data, expectedString);
     47  }, "testDecodeABVOption");
     48  test(testDecoderForThaiEncoding, "testDecoderForThaiEncoding");
     49  test(testInvalid2022JP, "testInvalid2022JP");
     50  test(testDecoderForBig5, "testDecoderForBig5");
     51 }
     52 
     53 /*
     54 * function testConstructor()
     55 *
     56 * - This function tests the constructor optional arguments.
     57 * - Stream option remains null for this test.
     58 * - The stream option is passed to the decode function.
     59 * - This function is not testing the decode function.
     60 *
     61 */
     62 function testConstructorFatalOption() {
     63  //invalid string to decode passed, fatal = false
     64  testCharset({
     65    fatal: false,
     66    encoding: "iso-8859-11",
     67    input: [],
     68    expected: "",
     69    msg: "constructor fatal option set to false test.",
     70  });
     71 
     72  //invalid string to decode passed, fatal = true
     73  testCharset({
     74    fatal: true,
     75    encoding: "iso-8859-11",
     76    input: [],
     77    expected: "",
     78    msg: "constructor fatal option set to true test.",
     79  });
     80 }
     81 
     82 function testConstructorEncodingOption(aData, aExpectedString) {
     83  function errorMessage(encoding) {
     84    return `TextDecoder constructor: The given encoding '${String(
     85      encoding
     86    ).trim()}' is not supported.`;
     87  }
     88 
     89  // valid encoding passed
     90  var encoding = "iso-8859-11";
     91  testCharset({
     92    encoding,
     93    input: aData,
     94    expected: aExpectedString,
     95    msg: "decoder testing constructor valid encoding.",
     96  });
     97 
     98  // passing spaces for encoding
     99  encoding = "   ";
    100  testCharset({
    101    encoding,
    102    input: aData,
    103    error: "RangeError",
    104    errorMessage: errorMessage(encoding),
    105    msg: "constructor encoding, spaces encoding test.",
    106  });
    107 
    108  // invalid encoding passed
    109  encoding = "asdfasdf";
    110  testCharset({
    111    encoding,
    112    input: aData,
    113    error: "RangeError",
    114    errorMessage: errorMessage(encoding),
    115    msg: "constructor encoding, invalid encoding test.",
    116  });
    117 
    118  // null encoding passed
    119  encoding = null;
    120  testCharset({
    121    encoding,
    122    input: aData,
    123    error: "RangeError",
    124    errorMessage: errorMessage(encoding),
    125    msg: 'constructor encoding, "null" encoding test.',
    126  });
    127 
    128  // empty encoding passed
    129  encoding = "";
    130  testCharset({
    131    encoding,
    132    input: aData,
    133    error: "RangeError",
    134    errorMessage: errorMessage(encoding),
    135    msg: "constructor encoding, empty encoding test.",
    136  });
    137 
    138  // replacement character test
    139  aExpectedString =
    140    "\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd" +
    141    "\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd" +
    142    "\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd" +
    143    "\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd" +
    144    "\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd" +
    145    "\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd" +
    146    "\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd" +
    147    "\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd" +
    148    "\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd" +
    149    "\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd" +
    150    "\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd";
    151  testCharset({
    152    encoding: "utf-8",
    153    input: aData,
    154    expected: aExpectedString,
    155    msg: "constuctor encoding, utf-8 test.",
    156  });
    157 }
    158 
    159 /*
    160 * function testDecodeStreamOption()
    161 *
    162 * - fatal remains null for the entire test
    163 * - encoding remains as "iso-8859-11"
    164 * - The stream option is modified for this test.
    165 * - ArrayBufferView is modified for this test.
    166 */
    167 function testDecodeStreamOption(data, expectedString) {
    168  const streamData = [];
    169  const expectedStreamString = [];
    170  const chunkSize = data.length / 3;
    171  for (let i = 0; i < data.length; i += chunkSize) {
    172    streamData.push(data.slice(i, i + chunkSize));
    173    expectedStreamString.push(expectedString.slice(i, i + chunkSize));
    174  }
    175 
    176  // streaming test
    177 
    178  /* - the streaming is null
    179   *  - streaming is not set in the decode function
    180   */
    181  testCharset({
    182    encoding: "iso-8859-11",
    183    array: [
    184      { input: streamData[0], expected: expectedStreamString[0] },
    185      { input: streamData[1], expected: expectedStreamString[1] },
    186      { input: streamData[2], expected: expectedStreamString[2] },
    187    ],
    188    msg: "decode() stream test zero.",
    189  });
    190 
    191  testCharset({
    192    encoding: "iso-8859-11",
    193    array: [
    194      { input: streamData[0], expected: expectedStreamString[0], stream: true },
    195      { input: streamData[1], expected: expectedStreamString[1], stream: true },
    196      { input: streamData[2], expected: expectedStreamString[2], stream: true },
    197    ],
    198    msg: "decode() stream test one.",
    199  });
    200 
    201  testCharset({
    202    encoding: "iso-8859-11",
    203    array: [
    204      { input: streamData[0], expected: expectedStreamString[0], stream: true },
    205      { input: streamData[1], expected: expectedStreamString[1] },
    206      { input: streamData[2], expected: expectedStreamString[2] },
    207    ],
    208    msg: "decode() stream test two.",
    209  });
    210 
    211  testCharset({
    212    encoding: "utf-8",
    213    array: [
    214      { input: [0xc2], expected: "\uFFFD" },
    215      { input: [0x80], expected: "\uFFFD" },
    216    ],
    217    msg: "decode() stream test utf-8.",
    218  });
    219 
    220  testCharset({
    221    encoding: "utf-8",
    222    fatal: true,
    223    array: [
    224      { input: [0xc2], error: "TypeError" },
    225      { input: [0x80], error: "TypeError" },
    226    ],
    227    msg: "decode() stream test utf-8 fatal.",
    228  });
    229 }
    230 
    231 function testDecodeStreamCompositions() {
    232  var tests = [
    233    { encoding: "utf-8", input: [0xc2, 0x80], expected: ["", "\x80"] },
    234    {
    235      encoding: "utf-8",
    236      input: [0xef, 0xbb, 0xbf, 0xc2, 0x80],
    237      expected: ["", "", "", "", "\x80"],
    238    },
    239    { encoding: "utf-16", input: [0x01, 0x00], expected: ["", "\x01"] },
    240    {
    241      encoding: "utf-16",
    242      input: [0x01, 0x00, 0x03, 0x02],
    243      expected: ["", "\x01", "", "\u0203"],
    244    },
    245    { encoding: "utf-16", input: [0xff, 0xfd], expected: ["", "\uFDFF"] },
    246    { encoding: "utf-16", input: [0xff, 0xfe], expected: ["", ""] },
    247    { encoding: "utf-16", input: [0xff, 0xff], expected: ["", "\uFFFF"] },
    248    {
    249      encoding: "utf-16",
    250      input: [0xff, 0xfe, 0x01, 0x00],
    251      expected: ["", "", "", "\x01"],
    252    },
    253    {
    254      encoding: "utf-16",
    255      input: [0xff, 0xfe, 0xff, 0xfe],
    256      expected: ["", "", "", "\uFEFF"],
    257    },
    258    {
    259      encoding: "utf-16",
    260      input: [0xff, 0xfe, 0xfe, 0xff],
    261      expected: ["", "", "", "\uFFFE"],
    262    },
    263    { encoding: "utf-16", input: [0xfd, 0xfe], expected: ["", "\uFEFD"] },
    264    { encoding: "utf-16", input: [0xfd, 0xff], expected: ["", "\uFFFD"] },
    265    { encoding: "utf-16", input: [0xfe, 0xfd], expected: ["", "\uFDFE"] },
    266    { encoding: "utf-16", input: [0xfe, 0xfe], expected: ["", "\uFEFE"] },
    267    { encoding: "utf-16", input: [0xfe, 0xff], expected: ["", "\uFFFE"] },
    268    {
    269      encoding: "utf-16",
    270      input: [0xfe, 0xff, 0x01, 0x00],
    271      expected: ["", "\uFFFE", "", "\x01"],
    272    },
    273    {
    274      encoding: "utf-16",
    275      input: [0xfe, 0xff, 0xff, 0xfe],
    276      expected: ["", "\uFFFE", "", "\uFEFF"],
    277    },
    278    {
    279      encoding: "utf-16",
    280      input: [0xfe, 0xff, 0xfe, 0xff],
    281      expected: ["", "\uFFFE", "", "\uFFFE"],
    282    },
    283    { encoding: "utf-16le", input: [0x01, 0x00], expected: ["", "\x01"] },
    284    {
    285      encoding: "utf-16le",
    286      input: [0x01, 0x00, 0x03, 0x02],
    287      expected: ["", "\x01", "", "\u0203"],
    288    },
    289    {
    290      encoding: "utf-16le",
    291      input: [0xff, 0xfe, 0x01, 0x00],
    292      expected: ["", "", "", "\x01"],
    293    },
    294    {
    295      encoding: "utf-16le",
    296      input: [0xfe, 0xff, 0x01, 0x00],
    297      expected: ["", "\uFFFE", "", "\x01"],
    298    },
    299    { encoding: "utf-16be", input: [0x01, 0x00], expected: ["", "\u0100"] },
    300    {
    301      encoding: "utf-16be",
    302      input: [0x01, 0x00, 0x03, 0x02],
    303      expected: ["", "\u0100", "", "\u0302"],
    304    },
    305    { encoding: "utf-16be", input: [0xfd, 0xfe], expected: ["", "\uFDFE"] },
    306    { encoding: "utf-16be", input: [0xfd, 0xff], expected: ["", "\uFDFF"] },
    307    { encoding: "utf-16be", input: [0xfe, 0xfd], expected: ["", "\uFEFD"] },
    308    { encoding: "utf-16be", input: [0xfe, 0xfe], expected: ["", "\uFEFE"] },
    309    { encoding: "utf-16be", input: [0xfe, 0xff], expected: ["", ""] },
    310    {
    311      encoding: "utf-16be",
    312      input: [0xfe, 0xff, 0x01, 0x00],
    313      expected: ["", "", "", "\u0100"],
    314    },
    315    { encoding: "utf-16be", input: [0xff, 0xfd], expected: ["", "\uFFFD"] },
    316    { encoding: "utf-16be", input: [0xff, 0xfe], expected: ["", "\uFFFE"] },
    317    { encoding: "utf-16be", input: [0xff, 0xff], expected: ["", "\uFFFF"] },
    318    {
    319      encoding: "utf-16be",
    320      input: [0xff, 0xfe, 0x01, 0x00],
    321      expected: ["", "\uFFFE", "", "\u0100"],
    322    },
    323    { encoding: "shift_jis", input: [0x81, 0x40], expected: ["", "\u3000"] },
    324  ];
    325  tests.forEach(function (t) {
    326    (function generateCompositions(a, n) {
    327      a.push(n);
    328      var l = a.length - 1;
    329      var array = [];
    330      for (var i = 0, o = 0; i <= l; i++) {
    331        array.push({
    332          input: t.input.slice(o, o + a[i]),
    333          expected: t.expected.slice(o, (o += a[i])).join(""),
    334          stream: i < l,
    335        });
    336      }
    337      testCharset({
    338        encoding: t.encoding,
    339        array,
    340        msg: "decode() stream test " + t.encoding + " " + a.join("-") + ".",
    341      });
    342      while (a[l] > 1) {
    343        a[l]--;
    344        generateCompositions(a.slice(0), n - a[l]);
    345      }
    346    })([], t.input.length);
    347  });
    348 }
    349 
    350 /*
    351 * function testDecodeABVOption()
    352 *
    353 * - ABV for ArrayBufferView
    354 * - fatal remains null for the entire test
    355 * - encoding remains as "iso-8859-11"
    356 * - The stream option is modified for this test.
    357 * - ArrayBufferView is modified for this test.
    358 */
    359 function testDecodeABVOption(data, expectedString) {
    360  // valid data
    361  testCharset({
    362    encoding: "iso-8859-11",
    363    input: data,
    364    expected: expectedString,
    365    msg: "decode test ABV valid data.",
    366  });
    367 
    368  // invalid empty data
    369  testCharset({
    370    encoding: "iso-8859-11",
    371    input: [],
    372    expected: "",
    373    msg: "decode test ABV empty data.",
    374  });
    375 
    376  // spaces
    377  testCharset({
    378    encoding: "iso-8859-11",
    379    input: ["\u0020\u0020"],
    380    expected: "\0",
    381    msg: "text decoding ABV string test.",
    382  });
    383 
    384  testCharset({
    385    encoding: "iso-8859-11",
    386    input: [""],
    387    expected: "\0",
    388    msg: "text decoding ABV empty string test.",
    389  });
    390 
    391  // null for Array Buffer
    392  testCharset({
    393    encoding: "iso-8859-11",
    394    input: null,
    395    error: "TypeError",
    396    msg: "text decoding ABV null test.",
    397  });
    398 }
    399 
    400 function testDecodeGreek() {
    401  var data = [
    402    0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab,
    403    0xac, 0xad, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8,
    404    0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4,
    405    0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0,
    406    0xd1, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd,
    407    0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
    408    0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5,
    409    0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe,
    410  ];
    411 
    412  var expectedString =
    413    "\u00a0\u2018\u2019\u00a3\u20ac\u20af\u00a6\u00a7\u00a8" +
    414    "\u00a9\u037a\u00ab\u00ac\u00ad\u2015\u00b0\u00b1" +
    415    "\u00b2\u00b3\u0384\u0385\u0386\u00b7\u0388\u0389" +
    416    "\u038a\u00bb\u038c\u00bd\u038e\u038f\u0390\u0391" +
    417    "\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399" +
    418    "\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1" +
    419    "\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9\u03aa" +
    420    "\u03ab\u03ac\u03ad\u03ae\u03af\u03b0\u03b1\u03b2" +
    421    "\u03b3\u03b4\u03b5\u03b6\u03b7\u03b8\u03b9\u03ba" +
    422    "\u03bb\u03bc\u03bd\u03be\u03bf\u03c0\u03c1\u03c2" +
    423    "\u03c3\u03c4\u03c5\u03c6\u03c7\u03c8\u03c9\u03ca" +
    424    "\u03cb\u03cc\u03cd\u03ce";
    425 
    426  testCharset({
    427    encoding: "greek",
    428    input: data,
    429    expected: expectedString,
    430    msg: "decode greek test.",
    431  });
    432 }
    433 
    434 function testDecoderForThaiEncoding() {
    435  // TEST One
    436  const data = [
    437    0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab,
    438    0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
    439    0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3,
    440    0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
    441    0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdf,
    442    0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb,
    443    0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
    444    0xf8, 0xf9, 0xfa, 0xfb,
    445  ];
    446 
    447  const expectedString =
    448    "\u00a0\u0e01\u0e02\u0e03\u0e04\u0e05\u0e06\u0e07\u0e08\u0e09\u0e0a\u0e0b\u0e0c\u0e0d\u0e0e\u0e0f\u0e10\u0e11\u0e12\u0e13\u0e14\u0e15\u0e16\u0e17\u0e18\u0e19\u0e1a\u0e1b\u0e1c\u0e1d\u0e1e\u0e1f\u0e20\u0e21\u0e22\u0e23\u0e24\u0e25\u0e26\u0e27\u0e28\u0e29\u0e2a\u0e2b\u0e2c\u0e2d\u0e2e\u0e2f\u0e30\u0e31\u0e32\u0e33\u0e34\u0e35\u0e36\u0e37\u0e38\u0e39\u0e3a\u0e3f\u0e40\u0e41\u0e42\u0e43\u0e44\u0e45\u0e46\u0e47\u0e48\u0e49\u0e4a\u0e4b\u0e4c\u0e4d\u0e4e\u0e4f\u0e50\u0e51\u0e52\u0e53\u0e54\u0e55\u0e56\u0e57\u0e58\u0e59\u0e5a\u0e5b";
    449 
    450  testCharset({
    451    encoding: "iso-8859-11",
    452    input: data,
    453    expected: expectedString,
    454    msg: "decoder testing valid ISO-8859-11 encoding.",
    455  });
    456 }
    457 
    458 function testDecoderGetEncoding() {
    459  var labelEncodings = [
    460    { encoding: "utf-8", labels: ["unicode-1-1-utf-8", "utf-8", "utf8"] },
    461    { encoding: "ibm866", labels: ["866", "cp866", "csibm866", "ibm866"] },
    462    {
    463      encoding: "iso-8859-2",
    464      labels: [
    465        "csisolatin2",
    466        "iso-8859-2",
    467        "iso-ir-101",
    468        "iso8859-2",
    469        "iso88592",
    470        "iso_8859-2",
    471        "iso_8859-2:1987",
    472        "l2",
    473        "latin2",
    474      ],
    475    },
    476    {
    477      encoding: "iso-8859-3",
    478      labels: [
    479        "csisolatin3",
    480        "iso-8859-3",
    481        "iso-ir-109",
    482        "iso8859-3",
    483        "iso88593",
    484        "iso_8859-3",
    485        "iso_8859-3:1988",
    486        "l3",
    487        "latin3",
    488      ],
    489    },
    490    {
    491      encoding: "iso-8859-4",
    492      labels: [
    493        "csisolatin4",
    494        "iso-8859-4",
    495        "iso-ir-110",
    496        "iso8859-4",
    497        "iso88594",
    498        "iso_8859-4",
    499        "iso_8859-4:1988",
    500        "l4",
    501        "latin4",
    502      ],
    503    },
    504    {
    505      encoding: "iso-8859-5",
    506      labels: [
    507        "csisolatincyrillic",
    508        "cyrillic",
    509        "iso-8859-5",
    510        "iso-ir-144",
    511        "iso8859-5",
    512        "iso88595",
    513        "iso_8859-5",
    514        "iso_8859-5:1988",
    515      ],
    516    },
    517    {
    518      encoding: "iso-8859-6",
    519      labels: [
    520        "arabic",
    521        "asmo-708",
    522        "csiso88596e",
    523        "csiso88596i",
    524        "csisolatinarabic",
    525        "ecma-114",
    526        "iso-8859-6",
    527        "iso-8859-6-e",
    528        "iso-8859-6-i",
    529        "iso-ir-127",
    530        "iso8859-6",
    531        "iso88596",
    532        "iso_8859-6",
    533        "iso_8859-6:1987",
    534      ],
    535    },
    536    {
    537      encoding: "iso-8859-7",
    538      labels: [
    539        "csisolatingreek",
    540        "ecma-118",
    541        "elot_928",
    542        "greek",
    543        "greek8",
    544        "iso-8859-7",
    545        "iso-ir-126",
    546        "iso8859-7",
    547        "iso88597",
    548        "iso_8859-7",
    549        "iso_8859-7:1987",
    550        "sun_eu_greek",
    551      ],
    552    },
    553    {
    554      encoding: "iso-8859-8",
    555      labels: [
    556        "csiso88598e",
    557        "csisolatinhebrew",
    558        "hebrew",
    559        "iso-8859-8",
    560        "iso-8859-8-e",
    561        "iso-ir-138",
    562        "iso8859-8",
    563        "iso88598",
    564        "iso_8859-8",
    565        "iso_8859-8:1988",
    566        "visual",
    567      ],
    568    },
    569    {
    570      encoding: "iso-8859-8-i",
    571      labels: ["csiso88598i", "iso-8859-8-i", "logical"],
    572    },
    573    {
    574      encoding: "iso-8859-10",
    575      labels: [
    576        "csisolatin6",
    577        "iso-8859-10",
    578        "iso-ir-157",
    579        "iso8859-10",
    580        "iso885910",
    581        "l6",
    582        "latin6",
    583      ],
    584    },
    585    {
    586      encoding: "iso-8859-13",
    587      labels: ["iso-8859-13", "iso8859-13", "iso885913"],
    588    },
    589    {
    590      encoding: "iso-8859-14",
    591      labels: ["iso-8859-14", "iso8859-14", "iso885914"],
    592    },
    593    {
    594      encoding: "iso-8859-15",
    595      labels: [
    596        "csisolatin9",
    597        "iso-8859-15",
    598        "iso8859-15",
    599        "iso885915",
    600        "iso_8859-15",
    601        "l9",
    602      ],
    603    },
    604    { encoding: "iso-8859-16", labels: ["iso-8859-16"] },
    605    {
    606      encoding: "koi8-r",
    607      labels: ["cskoi8r", "koi", "koi8", "koi8-r", "koi8_r"],
    608    },
    609    { encoding: "koi8-u", labels: ["koi8-u"] },
    610    {
    611      encoding: "macintosh",
    612      labels: ["csmacintosh", "mac", "macintosh", "x-mac-roman"],
    613    },
    614    {
    615      encoding: "windows-874",
    616      labels: [
    617        "dos-874",
    618        "iso-8859-11",
    619        "iso8859-11",
    620        "iso885911",
    621        "tis-620",
    622        "windows-874",
    623      ],
    624    },
    625    {
    626      encoding: "windows-1250",
    627      labels: ["cp1250", "windows-1250", "x-cp1250"],
    628    },
    629    {
    630      encoding: "windows-1251",
    631      labels: ["cp1251", "windows-1251", "x-cp1251"],
    632    },
    633    {
    634      encoding: "windows-1252",
    635      labels: [
    636        "ansi_x3.4-1968",
    637        "ascii",
    638        "cp1252",
    639        "cp819",
    640        "csisolatin1",
    641        "ibm819",
    642        "iso-8859-1",
    643        "iso-ir-100",
    644        "iso8859-1",
    645        "iso88591",
    646        "iso_8859-1",
    647        "iso_8859-1:1987",
    648        "l1",
    649        "latin1",
    650        "us-ascii",
    651        "windows-1252",
    652        "x-cp1252",
    653      ],
    654    },
    655    {
    656      encoding: "windows-1253",
    657      labels: ["cp1253", "windows-1253", "x-cp1253"],
    658    },
    659    {
    660      encoding: "windows-1254",
    661      labels: [
    662        "cp1254",
    663        "csisolatin5",
    664        "iso-8859-9",
    665        "iso-ir-148",
    666        "iso8859-9",
    667        "iso88599",
    668        "iso_8859-9",
    669        "iso_8859-9:1989",
    670        "l5",
    671        "latin5",
    672        "windows-1254",
    673        "x-cp1254",
    674      ],
    675    },
    676    {
    677      encoding: "windows-1255",
    678      labels: ["cp1255", "windows-1255", "x-cp1255"],
    679    },
    680    {
    681      encoding: "windows-1256",
    682      labels: ["cp1256", "windows-1256", "x-cp1256"],
    683    },
    684    {
    685      encoding: "windows-1257",
    686      labels: ["cp1257", "windows-1257", "x-cp1257"],
    687    },
    688    {
    689      encoding: "windows-1258",
    690      labels: ["cp1258", "windows-1258", "x-cp1258"],
    691    },
    692    {
    693      encoding: "x-mac-cyrillic",
    694      labels: ["x-mac-cyrillic", "x-mac-ukrainian"],
    695    },
    696    {
    697      encoding: "gbk",
    698      labels: [
    699        "chinese",
    700        "csgb2312",
    701        "csiso58gb231280",
    702        "gb2312",
    703        "gb_2312",
    704        "gb_2312-80",
    705        "gbk",
    706        "iso-ir-58",
    707        "x-gbk",
    708      ],
    709    },
    710    { encoding: "gb18030", labels: ["gb18030"] },
    711    {
    712      encoding: "big5",
    713      labels: ["big5", "cn-big5", "csbig5", "x-x-big5", "big5-hkscs"],
    714    },
    715    {
    716      encoding: "euc-jp",
    717      labels: ["cseucpkdfmtjapanese", "euc-jp", "x-euc-jp"],
    718    },
    719    { encoding: "iso-2022-jp", labels: ["csiso2022jp", "iso-2022-jp"] },
    720    {
    721      encoding: "shift_jis",
    722      labels: [
    723        "csshiftjis",
    724        "ms932",
    725        "ms_kanji",
    726        "shift-jis",
    727        "shift_jis",
    728        "sjis",
    729        "windows-31j",
    730        "x-sjis",
    731      ],
    732    },
    733    {
    734      encoding: "euc-kr",
    735      labels: [
    736        "cseuckr",
    737        "csksc56011987",
    738        "euc-kr",
    739        "iso-ir-149",
    740        "korean",
    741        "ks_c_5601-1987",
    742        "ks_c_5601-1989",
    743        "ksc5601",
    744        "ksc_5601",
    745        "windows-949",
    746      ],
    747    },
    748    { encoding: "utf-16le", labels: ["utf-16", "utf-16le"] },
    749    { encoding: "utf-16be", labels: ["utf-16be"] },
    750    { encoding: "x-user-defined", labels: ["x-user-defined"] },
    751    {
    752      error: "RangeError",
    753      labels: [
    754        "x-windows-949",
    755        "\u0130SO-8859-1",
    756        "csiso2022kr",
    757        "iso-2022-kr",
    758        "iso-2022-cn",
    759        "iso-2022-cn-ext",
    760        "replacement",
    761        "hz-gb-2312",
    762      ],
    763    },
    764  ];
    765 
    766  for (var le of labelEncodings) {
    767    for (var label of le.labels) {
    768      try {
    769        var decoder = new TextDecoder(label);
    770      } catch (e) {
    771        assert_true(!!le.error, label + " shoud not throw " + e.name);
    772        assert_equals(
    773          e.name,
    774          le.error,
    775          label + " label encoding unsupported test."
    776        );
    777        continue;
    778      }
    779      assert_true(!le.error, label + " shoud throw " + le.error);
    780      assert_equals(
    781        decoder.encoding,
    782        le.encoding,
    783        label + " label encoding test."
    784      );
    785    }
    786  }
    787 }
    788 
    789 function testCharset(test) {
    790  try {
    791    var fatal = test.fatal ? { fatal: test.fatal } : null;
    792    var decoder = new TextDecoder(test.encoding, fatal);
    793  } catch (e) {
    794    assert_equals(
    795      e.name,
    796      test.error,
    797      test.msg + " error thrown from the constructor."
    798    );
    799    if (test.errorMessage) {
    800      assert_equals(
    801        e.message,
    802        test.errorMessage,
    803        test.msg + " error thrown from the constructor."
    804      );
    805    }
    806    return;
    807  }
    808 
    809  var array = test.array || [test];
    810  var num_strings = array.length;
    811  for (var i = 0; i < num_strings; i++) {
    812    var decodeView =
    813      array[i].input !== null ? new Uint8Array(array[i].input) : null;
    814    var stream = array[i].stream ? { stream: array[i].stream } : null;
    815    var outText;
    816    try {
    817      outText = decoder.decode(decodeView, stream);
    818    } catch (e) {
    819      assert_equals(
    820        e.name,
    821        array[i].error,
    822        test.msg + " error thrown from decode()."
    823      );
    824      return;
    825    }
    826 
    827    var expected = array[i].expected;
    828    if (outText !== expected) {
    829      assert_equals(
    830        escape(outText),
    831        escape(expected),
    832        test.msg + " Code points do not match expected code points."
    833      );
    834      break;
    835    }
    836  }
    837  assert_true(!test.error, test.msg);
    838 }
    839 
    840 function testInvalid2022JP() {
    841  var inputs = [
    842    [0x80],
    843    [0x1b, 0xff],
    844    [0x1b, 0x28, 0xff],
    845    [0x1b, 0x24, 0x80],
    846    [0x1b, 0x24, 0x28, 0x80],
    847    [0x1b, 0x28, 0x4a, 0xff],
    848    [0x1b, 0x28, 0x49, 0xff],
    849    [0x1b, 0x24, 0x40, 0x20],
    850    [0x1b, 0x24, 0x41, 0x20],
    851    [0x1b, 0x24, 0x42, 0x20],
    852    [0x1b, 0x24, 0x28, 0x43, 0x20],
    853    [0x1b, 0x24, 0x28, 0x44, 0x20],
    854    [0x1b, 0x24, 0x40, 0x80, 0x21],
    855    [0x1b, 0x24, 0x41, 0xff, 0x21],
    856    [0x1b, 0x24, 0x42, 0x80, 0x21],
    857    [0x1b, 0x24, 0x28, 0x43, 0xff, 0x21],
    858    [0x1b, 0x24, 0x28, 0x44, 0x80, 0x21],
    859    [0x1b, 0x24, 0x40, 0x21, 0x20],
    860    [0x1b, 0x24, 0x41, 0x21, 0x20],
    861    [0x1b, 0x24, 0x42, 0x21, 0x20],
    862    [0x1b, 0x24, 0x28, 0x43, 0x21, 0x20],
    863    [0x1b, 0x24, 0x28, 0x44, 0x21, 0x20],
    864    [0x1b, 0x2e, 0xff],
    865    [0x1b, 0x4e, 0x20],
    866    [0x1b, 0x4e, 0x7f],
    867    [0x1b, 0x2e, 0x41, 0x1b, 0x4e, 0x80],
    868    [0x1b, 0x2e, 0x41, 0x1b, 0x4e, 0xff],
    869  ];
    870 
    871  var failureCount = 0;
    872  inputs.forEach(function (input) {
    873    try {
    874      // decode() should never throw unless {fatal: true} is specified
    875      new TextDecoder("iso-2022-jp").decode(new Uint8Array(input));
    876    } catch (e) {
    877      if (e.name !== "TypeError") {
    878        throw e;
    879      }
    880      failureCount++;
    881    }
    882  });
    883  assert_equals(
    884    failureCount,
    885    0,
    886    failureCount + " of " + inputs.length + " tests failed"
    887  );
    888 }
    889 
    890 function testDecoderForBig5() {
    891  const inputs = [
    892    [0x61, 0x62],
    893    [0x87, 0x40],
    894    [0xfe, 0xfe],
    895    [0xfe, 0xfd],
    896    [0x88, 0x62],
    897    [0x88, 0x64],
    898    [0x88, 0x66],
    899    [0x88, 0xa3],
    900    [0x88, 0xa5],
    901    [0x88, 0xa7],
    902    [0x99, 0xd4],
    903    [0x99, 0xd5],
    904    [0x99, 0xd6],
    905    [0x61, 0x87, 0x40, 0x62],
    906    [0x61, 0xfe, 0xfe, 0x62],
    907    [0x61, 0xfe, 0xfd, 0x62],
    908    [0x61, 0x88, 0x62, 0x62],
    909    [0x61, 0x88, 0x64, 0x62],
    910    [0x61, 0x88, 0x66, 0x62],
    911    [0x61, 0x88, 0xa3, 0x62],
    912    [0x61, 0x88, 0xa5, 0x62],
    913    [0x61, 0x88, 0xa7, 0x62],
    914    [0x61, 0x99, 0xd4, 0x62],
    915    [0x61, 0x99, 0xd5, 0x62],
    916    [0x61, 0x99, 0xd6, 0x62],
    917    [0x80, 0x61],
    918    [0xff, 0x61],
    919    [0xfe, 0x39],
    920    [0x87, 0x66],
    921    [0x81, 0x40],
    922    [0x61, 0x81],
    923  ];
    924  const expectations = [
    925    "\u0061\u0062",
    926    "\u43F0",
    927    "\u79D4",
    928    "\uD864\uDD0D",
    929    "\u00CA\u0304",
    930    "\u00CA\u030C",
    931    "\u00CA",
    932    "\u00EA\u0304",
    933    "\u00EA\u030C",
    934    "\u00EA",
    935    "\u8991",
    936    "\uD85E\uDD67",
    937    "\u8A29",
    938    "\u0061\u43F0\u0062",
    939    "\u0061\u79D4\u0062",
    940    "\u0061\uD864\uDD0D\u0062",
    941    "\u0061\u00CA\u0304\u0062",
    942    "\u0061\u00CA\u030C\u0062",
    943    "\u0061\u00CA\u0062",
    944    "\u0061\u00EA\u0304\u0062",
    945    "\u0061\u00EA\u030C\u0062",
    946    "\u0061\u00EA\u0062",
    947    "\u0061\u8991\u0062",
    948    "\u0061\uD85E\uDD67\u0062",
    949    "\u0061\u8A29\u0062",
    950    "\uFFFD\u0061",
    951    "\uFFFD\u0061",
    952    "\uFFFD\u0039",
    953    "\uFFFD\u0066",
    954    "\uFFFD\u0040",
    955    "\u0061\uFFFD",
    956  ];
    957 
    958  for (var i = 0; i < inputs.length; i++) {
    959    testCharset({
    960      encoding: "big5",
    961      input: inputs[i],
    962      expected: expectations[i],
    963      msg: "decoder test #" + i + " for big5.",
    964    });
    965  }
    966 }