mirror of
https://github.com/servo/servo.git
synced 2025-08-04 05:00:08 +01:00
Auto merge of #8359 - ben0x539:js-url-query-fragment, r=eefriedman
Append query string + fragment to javascript: url. When loading a URL whose scheme is javascript, we should do what https://html.spec.whatwg.org/multipage/browsers.html#javascript-protocol says and append the URL's query and fragment components to the scheme data, as well as percent- and utf-8-decode the whole thing, before evaluating it as javascript. <!-- Reviewable:start --> [<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/8359) <!-- Reviewable:end -->
This commit is contained in:
commit
33bbed7dc1
4 changed files with 69 additions and 3 deletions
|
@ -1671,10 +1671,32 @@ impl ScriptTask {
|
||||||
|
|
||||||
let is_javascript = incomplete.url.scheme == "javascript";
|
let is_javascript = incomplete.url.scheme == "javascript";
|
||||||
let parse_input = if is_javascript {
|
let parse_input = if is_javascript {
|
||||||
|
use url::percent_encoding::percent_decode_to;
|
||||||
|
|
||||||
|
// Turn javascript: URL into JS code to eval, according to the steps in
|
||||||
|
// https://html.spec.whatwg.org/multipage/#javascript-protocol
|
||||||
let _ar = JSAutoRequest::new(self.get_cx());
|
let _ar = JSAutoRequest::new(self.get_cx());
|
||||||
let evalstr = incomplete.url.non_relative_scheme_data().unwrap();
|
let mut script_source_bytes = Vec::new();
|
||||||
|
// Start with the scheme data of the parsed URL (5.), while percent-decoding (8.)
|
||||||
|
percent_decode_to(incomplete.url.non_relative_scheme_data().unwrap().as_bytes(),
|
||||||
|
&mut script_source_bytes);
|
||||||
|
// Append question mark and query component, if any (6.), while percent-decoding (8.)
|
||||||
|
if let Some(ref query) = incomplete.url.query {
|
||||||
|
script_source_bytes.push(b'?');
|
||||||
|
percent_decode_to(query.as_bytes(), &mut script_source_bytes);
|
||||||
|
}
|
||||||
|
// Append number sign and fragment component if any (7.), while percent-decoding (8.)
|
||||||
|
if let Some(ref fragment) = incomplete.url.fragment {
|
||||||
|
script_source_bytes.push(b'#');
|
||||||
|
percent_decode_to(fragment.as_bytes(), &mut script_source_bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
// UTF-8 decode (9.)
|
||||||
|
let script_source = String::from_utf8_lossy(&script_source_bytes);
|
||||||
|
|
||||||
|
// Script source is ready to be evaluated (11.)
|
||||||
let mut jsval = RootedValue::new(self.get_cx(), UndefinedValue());
|
let mut jsval = RootedValue::new(self.get_cx(), UndefinedValue());
|
||||||
window.evaluate_js_on_global_with_result(evalstr, jsval.handle_mut());
|
window.evaluate_js_on_global_with_result(&script_source, jsval.handle_mut());
|
||||||
let strval = DOMString::from_jsval(self.get_cx(), jsval.handle(),
|
let strval = DOMString::from_jsval(self.get_cx(), jsval.handle(),
|
||||||
StringificationBehavior::Empty);
|
StringificationBehavior::Empty);
|
||||||
strval.unwrap_or(DOMString::new())
|
strval.unwrap_or(DOMString::new())
|
||||||
|
|
|
@ -29809,7 +29809,16 @@
|
||||||
},
|
},
|
||||||
"local_changes": {
|
"local_changes": {
|
||||||
"deleted": [],
|
"deleted": [],
|
||||||
"items": {},
|
"items": {
|
||||||
|
"testharness": {
|
||||||
|
"html/browsers/browsing-the-web/navigating-across-documents/javascript-url-query-fragment-components.html": [
|
||||||
|
{
|
||||||
|
"path": "html/browsers/browsing-the-web/navigating-across-documents/javascript-url-query-fragment-components.html",
|
||||||
|
"url": "/html/browsers/browsing-the-web/navigating-across-documents/javascript-url-query-fragment-components.html"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
"reftest_nodes": {}
|
"reftest_nodes": {}
|
||||||
},
|
},
|
||||||
"reftest_nodes": {
|
"reftest_nodes": {
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
[javascript-url-query-fragment-components.html]
|
||||||
|
type: testharness
|
||||||
|
expected: OK
|
||||||
|
[iframes with javascript src]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
<!doctype html>
|
||||||
|
<title> javascript url with query and fragment components </title>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script>
|
||||||
|
var a = null;
|
||||||
|
var b = null;
|
||||||
|
var c = null;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<iframe id="a" src='javascript:"nope" ? "yep" : "what";'></iframe>
|
||||||
|
<iframe id="b" src='javascript:"wrong"; // # %0a "ok";'></iframe>
|
||||||
|
<iframe id="c" src='javascript:"%252525 ? %252525 # %252525"'></iframe>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var t = async_test("iframes with javascript src", {timeout:1000});
|
||||||
|
function check(id, expected) {
|
||||||
|
assert_equals(
|
||||||
|
document.getElementById(id).contentDocument.body.textContent,
|
||||||
|
expected);
|
||||||
|
}
|
||||||
|
onload = t.step_func(function() {
|
||||||
|
check("a", "yep");
|
||||||
|
check("b", "ok");
|
||||||
|
check("c", "%2525 ? %2525 # %2525");
|
||||||
|
t.done();
|
||||||
|
});
|
||||||
|
</script>
|
Loading…
Add table
Add a link
Reference in a new issue