Reject unsuccessful script responses
This commit is contained in:
1 parent
caaf02e11c
commit
f61493fbd1
5 files changed
+132
-4
No files matched your search
Vendored
+10
-1
@@ -253,7 +253,16 @@ async function __processDynScriptQueue() {
|
||||
body = _decodeDataScriptUrl(task.url);
|
||||
} else {
|
||||
const raw = await Deno.core.ops.op_fetch_url(task.url, "GET", "{}", "", task.pageOrigin, "no-cors");
|
||||
body = JSON.parse(raw).body;
|
||||
const parsed = JSON.parse(raw);
|
||||
// The HTML script-fetch algorithm treats an unsuccessful HTTP
|
||||
// response as a network error. Evaluating its response body is both
|
||||
// observably unlike browsers and dangerous: JSON error payloads
|
||||
// become JavaScript source, while servers can return diagnostic
|
||||
// HTML that mutates global state before throwing.
|
||||
if (!(parsed.status >= 200 && parsed.status <= 299)) {
|
||||
throw new Error('HTTP ' + (parsed.status || 0));
|
||||
}
|
||||
body = parsed.body;
|
||||
}
|
||||
if (body) {
|
||||
globalThis.__currentScriptNid = task.nid;
|
||||
|
||||
@@ -4893,6 +4893,52 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "current_thread")]
|
||||
async fn unsuccessful_dynamic_script_response_fires_error_without_evaluating_body() {
|
||||
let mut rt = setup_runtime("<html><head></head><body></body></html>");
|
||||
let result = rt
|
||||
.call_function_on_for_cdp(
|
||||
r#"async () => {
|
||||
const originalFetchOp = Deno.core.ops.op_fetch_url;
|
||||
try {
|
||||
Deno.core.ops.op_fetch_url = (url) => JSON.stringify({
|
||||
status: 401,
|
||||
headers: { "content-type": "application/json" },
|
||||
body: "globalThis.__executedFailedScript = true",
|
||||
url,
|
||||
});
|
||||
const script = document.createElement("script");
|
||||
script.src = "/unauthorized.js";
|
||||
const outcome = await new Promise(resolve => {
|
||||
script.onload = () => resolve("load");
|
||||
script.onerror = () => resolve("error");
|
||||
document.head.appendChild(script);
|
||||
});
|
||||
return {
|
||||
outcome,
|
||||
executed: globalThis.__executedFailedScript === true,
|
||||
};
|
||||
} finally {
|
||||
Deno.core.ops.op_fetch_url = originalFetchOp;
|
||||
}
|
||||
}"#,
|
||||
None,
|
||||
&[],
|
||||
true,
|
||||
true,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
result.value.unwrap(),
|
||||
serde_json::json!({
|
||||
"outcome": "error",
|
||||
"executed": false,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "current_thread")]
|
||||
async fn test_response_array_buffer_preserves_typed_array_view() {
|
||||
let mut rt = setup_runtime("<html><body></body></html>");
|
||||
|
||||
Reference in new issue
Block a user