tor-browser

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

iso2022jp-encode-form-errors-stateful.html (2559B)


      1 <!DOCTYPE html>
      2 <meta charset="utf-8">
      3 <title>Encoding: ISO-2022-JP unencodable replacement in form submission</title>
      4 <link rel="help" href="https://encoding.spec.whatwg.org/#iso-2022-jp-encoder">
      5 <link rel="author" title="Benjamin C. Wiley Sittler"
      6      href="mailto:bsittler@chromium.org">
      7 <script src="/resources/testharness.js"></script>
      8 <script src="/resources/testharnessreport.js"></script>
      9 <script>
     10 'use strict';
     11 
     12 promise_test(async testCase => {
     13  const target = Object.assign(document.createElement('iframe'), {
     14    name: 'target',
     15  });
     16  if (document.readyState !== 'complete') {
     17    await new Promise(resolve => addEventListener('load', resolve));
     18  }
     19  document.body.insertBefore(target, document.body.firstChild);
     20  const form = Object.assign(document.createElement('form'), {
     21    acceptCharset: 'iso-2022-jp',
     22    // NOTE: This uses escape and unescape rather than
     23    // encodeURI/encodeURIComponent and decodeURI/decodeURIComponent
     24    // intentionally, because:
     25    //
     26    // - escape() is required because encodeURI{,Component} encodes
     27    //   using UTF-8, and would falsely imply that non-ASCII
     28    //   characters are expected to work here -- which they won't, as
     29    //   the data URI has ISO-2022-JP charset; likewise
     30    //
     31    // - unescape() is required because the encoded byte sequence
     32    //   we're trying to decode and verify represents ISO-2022-JP data
     33    //   rather than the UTF-8 expected by decodeURI{,Component}
     34    //
     35    // The resulting document inside the IFRAME will look like:
     36    // <body onload="..."><plaintext>?utf16=...
     37    action: 'data:text/html;charset=iso-2022-jp,' + escape(
     38            '<body onload="(' +
     39            (() => parent.postMessage({
     40              utf16: document.body.innerText.split('=').pop(),
     41              iso2022jp: unescape(location.href.split('=').pop()),
     42            }, '*')) +
     43            ')()"><plaintext>'),
     44    target: target.name,
     45  });
     46  form.appendChild(Object.assign(document.createElement('input'), {
     47    name: 'utf16',
     48    value: 'ABC~ยคโ€ขโ˜…ๆ˜Ÿ๐ŸŒŸๆ˜Ÿโ˜…โ€ขยค~XYZ',
     49  }));
     50  document.body.insertBefore(form, document.body.firstChild);
     51  const {iso2022jp, utf16} = await new Promise(resolve => {
     52    addEventListener('message', ({data}) => resolve(data));
     53    form.submit();
     54  });
     55  assert_equals(utf16, 'ABC~&#164;&#8226;โ˜…ๆ˜Ÿ&#127775;ๆ˜Ÿโ˜…&#8226;&#164;~XYZ');
     56  assert_equals(
     57      iso2022jp,
     58      'ABC~&#164;&#8226;\x1b$B!z@1\x1b(B&#127775;\x1b$B@1!z\x1b(B&#8226;&#164;~XYZ');
     59 }, 'Form submission using ISO-2022-JP correctly replaces unencodables');
     60 
     61 </script>