| <!DOCTYPE html> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| <body> |
| <script> |
| function readableURL(url) { |
| return url.replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\t/g, "\\t"); |
| } |
| |
| var should_load = [ |
| `/images/green-1x1.png`, |
| `/images/gre\nen-1x1.png`, |
| `/images/gre\ten-1x1.png`, |
| `/images/gre\ren-1x1.png`, |
| `/images/green-1x1.png?img=<`, |
| `/images/green-1x1.png?img=<`, |
| `/images/green-1x1.png?img=%3C`, |
| `/images/gr\neen-1x1.png?img=%3C`, |
| `/images/gr\reen-1x1.png?img=%3C`, |
| `/images/gr\teen-1x1.png?img=%3C`, |
| `/images/green-1x1.png?img= `, |
| `/images/gr\neen-1x1.png?img= `, |
| `/images/gr\reen-1x1.png?img= `, |
| `/images/gr\teen-1x1.png?img= `, |
| ]; |
| should_load.forEach(url => async_test(t => { |
| fetch(url) |
| .then(t.step_func_done(r => { |
| assert_equals(r.status, 200); |
| })) |
| .catch(t.unreached_func("Fetch should succeed.")); |
| }, "Fetch: " + readableURL(url))); |
| |
| var should_block = [ |
| `/images/gre\nen-1x1.png?img=<`, |
| `/images/gre\ren-1x1.png?img=<`, |
| `/images/gre\ten-1x1.png?img=<`, |
| `/images/green-1x1.png?<\n=block`, |
| `/images/green-1x1.png?<\r=block`, |
| `/images/green-1x1.png?<\t=block`, |
| ]; |
| should_block.forEach(url => async_test(t => { |
| fetch(url) |
| .then(t.unreached_func("Fetch should fail.")) |
| .catch(t.step_func_done()); |
| }, "Fetch: " + readableURL(url))); |
| |
| |
| // For each of the following tests, we'll inject a frame containing the HTML we'd like to poke at |
| // as a `srcdoc` attribute. Because we're injecting markup via `srcdoc`, we need to entity-escape |
| // the content we'd like to treat as "raw" (e.g. `\n` => ` `, `<` => `<`), and |
| // double-escape the "escaped" content. |
| var rawBrace = "<"; |
| var escapedBrace = "&lt;"; |
| var rawNewline = " "; |
| var escapedNewline = "&#10;"; |
| |
| function appendFrameAndGetElement(test, frame) { |
| return new Promise((resolve, reject) => { |
| frame.onload = test.step_func(_ => { |
| frame.onload = null; |
| resolve(frame.contentDocument.querySelector('#dangling')); |
| }); |
| document.body.appendChild(frame); |
| }); |
| } |
| |
| function assert_img_loaded(test, frame) { |
| appendFrameAndGetElement(test, frame) |
| .then(test.step_func_done(img => { |
| assert_equals(img.naturalHeight, 1, "Height"); |
| frame.remove(); |
| })); |
| } |
| |
| function assert_img_not_loaded(test, frame) { |
| appendFrameAndGetElement(test, frame) |
| .then(test.step_func_done(img => { |
| assert_equals(img.naturalHeight, 0, "Height"); |
| assert_equals(img.naturalWidth, 0, "Width"); |
| })); |
| } |
| |
| function createFrame(markup) { |
| var i = document.createElement('iframe'); |
| i.srcdoc = `${markup}sekrit`; |
| return i; |
| } |
| |
| // The following resources should not be blocked, as their URLs do not contain both a `\n` and `<` |
| // character in the body of the URL. |
| var should_load = [ |
| // Brace alone doesn't block: |
| `<img id="dangling" src="/images/green-1x1.png?img=${rawBrace}b">`, |
| |
| // Newline alone doesn't block: |
| `<img id="dangling" src="/images/green-1x1.png?img=${rawNewline}b">`, |
| |
| // Entity-escaped characters don't trigger blocking: |
| `<img id="dangling" src="/images/green-1x1.png?img=${escapedNewline}b">`, |
| `<img id="dangling" src="/images/green-1x1.png?img=${escapedBrace}b">`, |
| `<img id="dangling" src="/images/green-1x1.png?img=${escapedNewline}b${escapedBrace}c">`, |
| |
| // Leading and trailing whitespace is stripped: |
| ` |
| <img id="dangling" src=" |
| /images/green-1x1.png?img= |
| "> |
| `, |
| ` |
| <img id="dangling" src=" |
| /images/green-1x1.png?img=${escapedBrace} |
| "> |
| `, |
| ` |
| <img id="dangling" src=" |
| /images/green-1x1.png?img=${escapedNewline} |
| "> |
| `, |
| ]; |
| |
| should_load.forEach(markup => { |
| async_test(t => { |
| var i = createFrame(`${markup} <element attr="" another=''>`); |
| assert_img_loaded(t, i); |
| }, readableURL(markup)); |
| }); |
| |
| // The following resources should be blocked, as their URLs contain both `\n` and `<` characters: |
| var should_block = [ |
| `<img id="dangling" src="/images/green-1x1.png?img=${rawNewline}${rawBrace}b">`, |
| `<img id="dangling" src="/images/green-1x1.png?img=${rawBrace}${rawNewline}b">`, |
| ` |
| <img id="dangling" src="/images/green-1x1.png?img= |
| ${rawBrace} |
| ${rawNewline}b |
| "> |
| `, |
| ]; |
| |
| should_block.forEach(markup => { |
| async_test(t => { |
| var i = createFrame(`${markup}`); |
| assert_img_not_loaded(t, i); |
| }, readableURL(markup)); |
| }); |
| </script> |