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~¤•โ ๆ🌟ๆโ •¤~XYZ'); 56 assert_equals( 57 iso2022jp, 58 'ABC~¤•\x1b$B!z@1\x1b(B🌟\x1b$B@1!z\x1b(B•¤~XYZ'); 59 }, 'Form submission using ISO-2022-JP correctly replaces unencodables'); 60 61 </script>