Bug 1426562 - Don't crash on `Response` constructor in WebExtensions. r=baku

Differential Revision: https://phabricator.services.mozilla.com/D29365

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Perry Jiang 2019-05-13 17:03:58 +00:00
Родитель d3544d3efb
Коммит 144e795dbb
4 изменённых файлов: 67 добавлений и 2 удалений

Просмотреть файл

@ -167,6 +167,11 @@ already_AddRefed<Response> Response::Constructor(
const ResponseInit& aInit, ErrorResult& aRv) {
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
if (NS_WARN_IF(!global)) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return nullptr;
}
if (aInit.mStatus < 200 || aInit.mStatus > 599) {
aRv.ThrowRangeError<MSG_INVALID_RESPONSE_STATUSCODE_ERROR>();
return nullptr;
@ -209,10 +214,22 @@ already_AddRefed<Response> Response::Constructor(
aRv.ThrowTypeError<MSG_FETCH_BODY_CONSUMED_ERROR>();
return nullptr;
}
} else {
internalResponse->InitChannelInfo(info);
} else if (nsContentUtils::IsSystemPrincipal(global->PrincipalOrNull())) {
info.InitFromChromeGlobal(global);
internalResponse->InitChannelInfo(info);
}
internalResponse->InitChannelInfo(info);
/**
* The channel info is left uninitialized if neither the above `if` nor
* `else if` statements are executed; this could be because we're in a
* WebExtensions content script, where the global (i.e. `global`) is a
* wrapper, and the principal is an expanded principal. In this case,
* as far as I can tell, there's no way to get the security info, but we'd
* like the `Response` to be successfully constructed.
*/
} else {
WorkerPrivate* worker = GetCurrentThreadWorkerPrivate();
MOZ_ASSERT(worker);

Просмотреть файл

@ -60,6 +60,7 @@ LOCAL_INCLUDES += [
]
BROWSER_CHROME_MANIFESTS += [ 'tests/browser.ini' ]
MOCHITEST_MANIFESTS += [ 'tests/mochitest.ini' ]
FINAL_LIBRARY = 'xul'

Просмотреть файл

@ -0,0 +1 @@
[test_ext_response_constructor.html]

Просмотреть файл

@ -0,0 +1,46 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test `Response` constructor in a WebExtension</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/ExtensionTestUtils.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
<script>
add_task(async function testResponseConstructor() {
function contentScript() {
new Response();
browser.test.notifyPass("done");
}
const extension = ExtensionTestUtils.loadExtension({
manifest: {
content_scripts: [
{
matches: ["<all_urls>"],
js: ["content_script.js"],
},
],
},
files: {
"content_script.js": contentScript,
},
});
await extension.startup();
const win = window.open("https://example.com");
await extension.awaitFinish("done");
win.close();
await extension.unload();
});
</script>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test"></pre>
</body>
</html>