Bug 1752863: Prevent recursion while xhr.send is running. r=dom-worker-reviewers,asuth

Differential Revision: https://phabricator.services.mozilla.com/D138131
This commit is contained in:
Jens Stutte 2022-02-09 09:01:45 +00:00
Родитель 3d0ac481f0
Коммит 91e1ae23e8
5 изменённых файлов: 73 добавлений и 0 удалений

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

@ -1355,6 +1355,7 @@ XMLHttpRequestWorker::XMLHttpRequestWorker(WorkerPrivate* aWorkerPrivate,
mBackgroundRequest(false),
mWithCredentials(false),
mCanceled(false),
mFlagSendActive(false),
mMozAnon(false),
mMozSystem(false),
mMimeTypeOverride(VoidString()) {
@ -1881,6 +1882,17 @@ void XMLHttpRequestWorker::Send(
ErrorResult& aRv) {
mWorkerPrivate->AssertIsOnWorkerThread();
if (mFlagSendActive) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_XHR_HAS_INVALID_CONTEXT);
return;
}
mFlagSendActive = true;
auto clearRecursionFlag = MakeScopeExit([&]() {
// No one else should have touched this flag.
MOZ_ASSERT(mFlagSendActive);
mFlagSendActive = false;
});
if (mCanceled) {
aRv.ThrowUncatchableException();
return;

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

@ -77,6 +77,7 @@ class XMLHttpRequestWorker final : public XMLHttpRequest {
bool mBackgroundRequest;
bool mWithCredentials;
bool mCanceled;
bool mFlagSendActive;
bool mMozAnon;
bool mMozSystem;

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

@ -129,3 +129,5 @@ support-files = xhr_worker_doubleSend.js
support-files = xhr_sharedworker.js
[test_bug1697539.html]
support-files = worker_bug1697539.js
[test_bug1752863.html]
support-files = test_bug1752863_worker.js

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

@ -0,0 +1,29 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Test for Bug 1752863</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript">
SimpleTest.waitForExplicitFinish();
var worker = new Worker("test_bug1752863_worker.js");
worker.onmessage = function(event) {
if (event.data == "DOMException") {
ok(true, "Got DOMException");
} else if (event.data == "TERMINATE") {
ok(false, "Got TERMINATE");
} else {
ok(false, "Unexpected message: " + event.data);
}
SimpleTest.finish();
}
worker.postMessage(true);
</script>
</head>
</html>

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

@ -0,0 +1,29 @@
self.onmessage = async function(ev) {
var xhr = new XMLHttpRequest({ mozAnon: false });
var myself = self;
xhr.addEventListener(
"loadstart",
async () => {
try {
xhr.open("POST", "FOOBAR", false);
xhr.send();
// We do not expect to ever get here. However, this would happen
// if the loadstart event would be queued and not directly
// executed on the same C++ stack of the xhr.send syncloop.
myself.postMessage("MissingError");
} catch (err) {
if (err instanceof DOMException) {
// This is what we expect to happen.
myself.postMessage("DOMException");
} else {
myself.postMessage("OtherError");
}
}
},
true
);
xhr.open("POST", "FOOBAR", false);
xhr.send();
// We do not expect to ever get here, see "MissingError".
postMessage("TERMINATE");
};