• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
12promise_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>
62