Skip to content

Commit 708d099

Browse files
nschimmefrankosterfeld
authored andcommitted
keychain_wasm: fix dangling pointer in async JS callbacks
Guard navigator.credentials.get/.store Promise callbacks with an isJobAlive() check against window.qtk_active_jobs before calling back into C++. If the C++ job is destroyed while a Promise is in flight, hide_bridge_form already removes the entry from the map, so the check prevents access to the freed pointer. Also drop the unnecessary null guards on the three EMSCRIPTEN_KEEPALIVE callbacks; job is always `this` from scheduledStart() and cannot be null.
1 parent 0ada1a7 commit 708d099

1 file changed

Lines changed: 9 additions & 9 deletions

File tree

qtkeychain/keychain_wasm.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,24 +19,20 @@ extern "C" {
1919
EMSCRIPTEN_KEEPALIVE
2020
void qtkeychain_read_password_success(JobPrivate *job, const char *data, int length)
2121
{
22-
if (job) {
23-
job->data = QByteArray(data, length);
24-
job->q->emitFinished();
25-
}
22+
job->data = QByteArray(data, length);
23+
job->q->emitFinished();
2624
}
2725

2826
EMSCRIPTEN_KEEPALIVE
2927
void qtkeychain_write_password_success(JobPrivate *job)
3028
{
31-
if (job)
32-
job->q->emitFinished();
29+
job->q->emitFinished();
3330
}
3431

3532
EMSCRIPTEN_KEEPALIVE
3633
void qtkeychain_error(JobPrivate *job, int error, const char *errorString)
3734
{
38-
if (job)
39-
job->q->emitFinishedWithError(static_cast<Error>(error), QString::fromUtf8(errorString));
35+
job->q->emitFinishedWithError(static_cast<Error>(error), QString::fromUtf8(errorString));
4036
}
4137
}
4238

@@ -196,6 +192,8 @@ EM_JS(void, show_bridge_form,
196192
finishWithError(accessDeniedByUser, "User cancelled");
197193
};
198194

195+
const isJobAlive = () => !!(window.qtk_active_jobs && window.qtk_active_jobs.has(job));
196+
199197
if (!isWrite && hasCredAPI("get")) {
200198
const btn = createBtn(extraDiv, {
201199
className: "qtk-success", textContent: "Use a saved password..."
@@ -208,7 +206,7 @@ EM_JS(void, show_bridge_form,
208206
console.log("QtKeychain: Requesting credentials...");
209207
navigator.credentials.get({ password: true })
210208
.then(cred => {
211-
if (cred) {
209+
if (cred && isJobAlive()) {
212210
userInput.value = cred.id || "";
213211
passInput.value = cred.password || "";
214212
form.dispatchEvent(new Event("submit"));
@@ -228,6 +226,8 @@ EM_JS(void, show_bridge_form,
228226
if (isWrite) {
229227
const done = () => {
230228
console.log("QtKeychain: Save complete");
229+
if (!isJobAlive())
230+
return;
231231
cleanup();
232232
_qtkeychain_write_password_success(job);
233233
};

0 commit comments

Comments
 (0)