Bug 1935127 - Part 1: Throw NS_ERROR_NOT_AVAILABLE error when the ClipboardDataSnapshot is no longer valid; r=nika
Differential Revision: https://phabricator.services.mozilla.com/D231809
This commit is contained in:
@@ -74,7 +74,7 @@ IPCResult ClipboardReadRequestParent::RecvGetData(
|
|||||||
bool valid = false;
|
bool valid = false;
|
||||||
if (NS_FAILED(mClipboardDataSnapshot->GetValid(&valid)) || !valid) {
|
if (NS_FAILED(mClipboardDataSnapshot->GetValid(&valid)) || !valid) {
|
||||||
Unused << PClipboardReadRequestParent::Send__delete__(this);
|
Unused << PClipboardReadRequestParent::Send__delete__(this);
|
||||||
aResolver(NS_ERROR_FAILURE);
|
aResolver(NS_ERROR_NOT_AVAILABLE);
|
||||||
return IPC_OK();
|
return IPC_OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,7 +130,7 @@ IPCResult ClipboardReadRequestParent::RecvGetDataSync(
|
|||||||
bool valid = false;
|
bool valid = false;
|
||||||
if (NS_FAILED(mClipboardDataSnapshot->GetValid(&valid)) || !valid) {
|
if (NS_FAILED(mClipboardDataSnapshot->GetValid(&valid)) || !valid) {
|
||||||
destroySoon();
|
destroySoon();
|
||||||
*aTransferableDataOrError = NS_ERROR_FAILURE;
|
*aTransferableDataOrError = NS_ERROR_NOT_AVAILABLE;
|
||||||
return IPC_OK();
|
return IPC_OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1010,7 +1010,7 @@ NS_IMETHODIMP nsBaseClipboard::ClipboardDataSnapshot::GetData(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!IsValid()) {
|
if (!IsValid()) {
|
||||||
aCallback->OnComplete(NS_ERROR_FAILURE);
|
aCallback->OnComplete(NS_ERROR_NOT_AVAILABLE);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1066,7 +1066,7 @@ NS_IMETHODIMP nsBaseClipboard::ClipboardDataSnapshot::GetData(
|
|||||||
// `IsValid()` checks the clipboard sequence number to ensure the data
|
// `IsValid()` checks the clipboard sequence number to ensure the data
|
||||||
// we are requesting is still valid.
|
// we are requesting is still valid.
|
||||||
if (!self->IsValid()) {
|
if (!self->IsValid()) {
|
||||||
callback->OnComplete(NS_ERROR_FAILURE);
|
callback->OnComplete(NS_ERROR_NOT_AVAILABLE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mozilla::contentanalysis::ContentAnalysis::
|
mozilla::contentanalysis::ContentAnalysis::
|
||||||
@@ -1102,7 +1102,7 @@ NS_IMETHODIMP nsBaseClipboard::ClipboardDataSnapshot::GetDataSync(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!IsValid()) {
|
if (!IsValid()) {
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
MOZ_ASSERT(mClipboard);
|
MOZ_ASSERT(mClipboard);
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
#include "nsContentUtils.h"
|
#include "nsContentUtils.h"
|
||||||
#include "PermissionMessageUtils.h"
|
#include "PermissionMessageUtils.h"
|
||||||
|
|
||||||
|
using mozilla::ipc::ResponseRejectReason;
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
using namespace mozilla::dom;
|
using namespace mozilla::dom;
|
||||||
|
|
||||||
@@ -168,7 +169,7 @@ NS_IMETHODIMP ClipboardDataSnapshotProxy::GetData(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!mActor->CanSend()) {
|
if (!mActor->CanSend()) {
|
||||||
return aCallback->OnComplete(NS_ERROR_FAILURE);
|
return aCallback->OnComplete(NS_ERROR_NOT_AVAILABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
mActor->SendGetData(flavors)->Then(
|
mActor->SendGetData(flavors)->Then(
|
||||||
@@ -196,9 +197,10 @@ NS_IMETHODIMP ClipboardDataSnapshotProxy::GetData(
|
|||||||
callback->OnComplete(NS_OK);
|
callback->OnComplete(NS_OK);
|
||||||
},
|
},
|
||||||
/* reject */
|
/* reject */
|
||||||
[callback =
|
[callback = nsCOMPtr{aCallback}](ResponseRejectReason aReason) {
|
||||||
nsCOMPtr{aCallback}](mozilla::ipc::ResponseRejectReason aReason) {
|
callback->OnComplete(ResponseRejectReason::ActorDestroyed == aReason
|
||||||
callback->OnComplete(NS_ERROR_FAILURE);
|
? NS_ERROR_NOT_AVAILABLE
|
||||||
|
: NS_ERROR_FAILURE);
|
||||||
});
|
});
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
@@ -226,13 +228,13 @@ NS_IMETHODIMP ClipboardDataSnapshotProxy::GetDataSync(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!mActor->CanSend()) {
|
if (!mActor->CanSend()) {
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
IPCTransferableDataOrError ipcTransferableDataOrError;
|
IPCTransferableDataOrError ipcTransferableDataOrError;
|
||||||
bool success = mActor->SendGetDataSync(flavors, &ipcTransferableDataOrError);
|
bool success = mActor->SendGetDataSync(flavors, &ipcTransferableDataOrError);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
}
|
}
|
||||||
if (ipcTransferableDataOrError.type() ==
|
if (ipcTransferableDataOrError.type() ==
|
||||||
IPCTransferableDataOrError::Tnsresult) {
|
IPCTransferableDataOrError::Tnsresult) {
|
||||||
@@ -309,8 +311,7 @@ NS_IMETHODIMP nsClipboardProxy::GetDataSnapshot(
|
|||||||
callback->OnSuccess(result.inspect());
|
callback->OnSuccess(result.inspect());
|
||||||
},
|
},
|
||||||
/* reject */
|
/* reject */
|
||||||
[callback = nsCOMPtr{aCallback}](
|
[callback = nsCOMPtr{aCallback}](ResponseRejectReason aReason) {
|
||||||
mozilla::ipc::ResponseRejectReason aReason) {
|
|
||||||
callback->OnError(NS_ERROR_FAILURE);
|
callback->OnError(NS_ERROR_FAILURE);
|
||||||
});
|
});
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|||||||
@@ -234,18 +234,18 @@ function asyncClipboardRequestGetData(aRequest, aFlavor, aThrows = false) {
|
|||||||
aThrows ? "throw" : "success"
|
aThrows ? "throw" : "success"
|
||||||
}`
|
}`
|
||||||
);
|
);
|
||||||
reject(e);
|
reject(e.result);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function syncClipboardRequestGetData(aRequest, aFlavor, aThrows = false) {
|
function syncClipboardRequestGetData(aRequest, aFlavor, aResult = Cr.NS_OK) {
|
||||||
var trans = Cc["@mozilla.org/widget/transferable;1"].createInstance(
|
var trans = Cc["@mozilla.org/widget/transferable;1"].createInstance(
|
||||||
Ci.nsITransferable
|
Ci.nsITransferable
|
||||||
);
|
);
|
||||||
trans.init(null);
|
trans.init(null);
|
||||||
trans.addDataFlavor(aFlavor);
|
trans.addDataFlavor(aFlavor);
|
||||||
let error = undefined;
|
let result = Cr.NS_OK;
|
||||||
try {
|
try {
|
||||||
aRequest.getDataSync(trans);
|
aRequest.getDataSync(trans);
|
||||||
try {
|
try {
|
||||||
@@ -258,12 +258,13 @@ function syncClipboardRequestGetData(aRequest, aFlavor, aThrows = false) {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
error = e;
|
result = e.result;
|
||||||
return error;
|
|
||||||
} finally {
|
} finally {
|
||||||
ok(
|
is(
|
||||||
aThrows === (error !== undefined),
|
result,
|
||||||
`nsIAsyncGetClipboardData.getData should ${aThrows ? "throw" : "success"}`
|
aResult,
|
||||||
|
`nsIAsyncGetClipboardData.getData should ${aResult == Cr.NS_OK ? "throw" : "success"}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,10 +65,14 @@ clipboardTypes.forEach(function (type) {
|
|||||||
|
|
||||||
let request = await getClipboardDataSnapshot(type);
|
let request = await getClipboardDataSnapshot(type);
|
||||||
isDeeply(request.flavorList, [], "Check flavorList");
|
isDeeply(request.flavorList, [], "Check flavorList");
|
||||||
await asyncClipboardRequestGetData(request, "text/plain", true).catch(
|
await asyncClipboardRequestGetData(request, "text/plain", true).catch(e => {
|
||||||
() => {}
|
is(
|
||||||
);
|
e,
|
||||||
syncClipboardRequestGetData(request, "text/plain", true);
|
Cr.NS_ERROR_FAILURE,
|
||||||
|
"should be rejected with NS_ERROR_FAILURE error"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
syncClipboardRequestGetData(request, "text/plain", Cr.NS_ERROR_FAILURE);
|
||||||
});
|
});
|
||||||
|
|
||||||
add_task(async function test_clipboard_getDataSnapshot_after_write() {
|
add_task(async function test_clipboard_getDataSnapshot_after_write() {
|
||||||
@@ -90,11 +94,15 @@ clipboardTypes.forEach(function (type) {
|
|||||||
);
|
);
|
||||||
ok(request.valid, "request should still be valid");
|
ok(request.valid, "request should still be valid");
|
||||||
// Requesting a flavor that is not in the list should throw error.
|
// Requesting a flavor that is not in the list should throw error.
|
||||||
await asyncClipboardRequestGetData(request, "text/html", true).catch(
|
await asyncClipboardRequestGetData(request, "text/html", true).catch(e => {
|
||||||
() => {}
|
is(
|
||||||
);
|
e,
|
||||||
|
Cr.NS_ERROR_FAILURE,
|
||||||
|
"should be rejected with NS_ERROR_FAILURE error"
|
||||||
|
);
|
||||||
|
});
|
||||||
ok(request.valid, "request should still be valid");
|
ok(request.valid, "request should still be valid");
|
||||||
syncClipboardRequestGetData(request, "text/html", true);
|
syncClipboardRequestGetData(request, "text/html", Cr.NS_ERROR_FAILURE);
|
||||||
ok(request.valid, "request should still be valid");
|
ok(request.valid, "request should still be valid");
|
||||||
|
|
||||||
// Writing a new data should invalid existing get request.
|
// Writing a new data should invalid existing get request.
|
||||||
@@ -103,12 +111,21 @@ clipboardTypes.forEach(function (type) {
|
|||||||
() => {
|
() => {
|
||||||
ok(false, "asyncClipboardRequestGetData should not success");
|
ok(false, "asyncClipboardRequestGetData should not success");
|
||||||
},
|
},
|
||||||
() => {
|
e => {
|
||||||
|
is(
|
||||||
|
e,
|
||||||
|
Cr.NS_ERROR_NOT_AVAILABLE,
|
||||||
|
"should throw NS_ERROR_NOT_AVAILABLE error"
|
||||||
|
);
|
||||||
ok(true, "asyncClipboardRequestGetData should reject");
|
ok(true, "asyncClipboardRequestGetData should reject");
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
ok(!request.valid, "request should no longer be valid");
|
ok(!request.valid, "request should no longer be valid");
|
||||||
syncClipboardRequestGetData(request, "text/plain", true);
|
syncClipboardRequestGetData(
|
||||||
|
request,
|
||||||
|
"text/plain",
|
||||||
|
Cr.NS_ERROR_NOT_AVAILABLE
|
||||||
|
);
|
||||||
ok(!request.valid, "request should no longer be valid");
|
ok(!request.valid, "request should no longer be valid");
|
||||||
|
|
||||||
info(`check clipboard data again`);
|
info(`check clipboard data again`);
|
||||||
@@ -155,8 +172,12 @@ clipboardTypes.forEach(function (type) {
|
|||||||
() => {
|
() => {
|
||||||
ok(false, "asyncClipboardRequestGetData should not success");
|
ok(false, "asyncClipboardRequestGetData should not success");
|
||||||
},
|
},
|
||||||
() => {
|
e => {
|
||||||
ok(true, "asyncClipboardRequestGetData should reject");
|
is(
|
||||||
|
e,
|
||||||
|
Cr.NS_ERROR_NOT_AVAILABLE,
|
||||||
|
"asyncClipboardRequestGetData should reject with NS_ERROR_NOT_AVAILABLE error"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
ok(!request.valid, "request should no longer be valid");
|
ok(!request.valid, "request should no longer be valid");
|
||||||
@@ -187,9 +208,13 @@ add_task(async function test_html_data() {
|
|||||||
"Check data"
|
"Check data"
|
||||||
);
|
);
|
||||||
// Requesting a flavor that is not in the list should throw error.
|
// Requesting a flavor that is not in the list should throw error.
|
||||||
await asyncClipboardRequestGetData(request, "text/plain", true).catch(
|
await asyncClipboardRequestGetData(request, "text/plain", true).catch(e => {
|
||||||
() => {}
|
is(
|
||||||
);
|
e,
|
||||||
|
Cr.NS_ERROR_FAILURE,
|
||||||
|
"should be rejected with NS_ERROR_FAILURE error"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
is(
|
is(
|
||||||
syncClipboardRequestGetData(request, "text/html"),
|
syncClipboardRequestGetData(request, "text/html"),
|
||||||
@@ -197,5 +222,5 @@ add_task(async function test_html_data() {
|
|||||||
"Check data (sync)"
|
"Check data (sync)"
|
||||||
);
|
);
|
||||||
// Requesting a flavor that is not in the list should throw error.
|
// Requesting a flavor that is not in the list should throw error.
|
||||||
syncClipboardRequestGetData(request, "text/plain", true);
|
syncClipboardRequestGetData(request, "text/plain", Cr.NS_ERROR_FAILURE);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -48,10 +48,10 @@ clipboardTypes.forEach(function (type) {
|
|||||||
|
|
||||||
let request = getClipboardDataSnapshotSync(type);
|
let request = getClipboardDataSnapshotSync(type);
|
||||||
isDeeply(request.flavorList, [], "Check flavorList");
|
isDeeply(request.flavorList, [], "Check flavorList");
|
||||||
await asyncClipboardRequestGetData(request, "text/plain", true).catch(
|
await asyncClipboardRequestGetData(request, "text/plain", true).catch(e => {
|
||||||
() => {}
|
is(e, Cr.NS_ERROR_FAILURE, "should throw NS_ERROR_FAILURE error");
|
||||||
);
|
});
|
||||||
syncClipboardRequestGetData(request, "text/plain", true);
|
syncClipboardRequestGetData(request, "text/plain", Cr.NS_ERROR_FAILURE);
|
||||||
});
|
});
|
||||||
|
|
||||||
add_task(async function test_clipboard_getDataSnapshotSync_after_write() {
|
add_task(async function test_clipboard_getDataSnapshotSync_after_write() {
|
||||||
@@ -73,11 +73,11 @@ clipboardTypes.forEach(function (type) {
|
|||||||
);
|
);
|
||||||
ok(request.valid, "request should still be valid");
|
ok(request.valid, "request should still be valid");
|
||||||
// Requesting a flavor that is not in the list should throw error.
|
// Requesting a flavor that is not in the list should throw error.
|
||||||
await asyncClipboardRequestGetData(request, "text/html", true).catch(
|
await asyncClipboardRequestGetData(request, "text/html", true).catch(e => {
|
||||||
() => {}
|
is(e, Cr.NS_ERROR_FAILURE, "should throw NS_ERROR_FAILURE error");
|
||||||
);
|
});
|
||||||
ok(request.valid, "request should still be valid");
|
ok(request.valid, "request should still be valid");
|
||||||
syncClipboardRequestGetData(request, "text/html", true);
|
syncClipboardRequestGetData(request, "text/html", Cr.NS_ERROR_FAILURE);
|
||||||
ok(request.valid, "request should still be valid");
|
ok(request.valid, "request should still be valid");
|
||||||
|
|
||||||
// Writing a new data should invalid existing get request.
|
// Writing a new data should invalid existing get request.
|
||||||
@@ -86,12 +86,20 @@ clipboardTypes.forEach(function (type) {
|
|||||||
() => {
|
() => {
|
||||||
ok(false, "asyncClipboardRequestGetData should not success");
|
ok(false, "asyncClipboardRequestGetData should not success");
|
||||||
},
|
},
|
||||||
() => {
|
e => {
|
||||||
ok(true, "asyncClipboardRequestGetData should reject");
|
is(
|
||||||
|
e,
|
||||||
|
Cr.NS_ERROR_NOT_AVAILABLE,
|
||||||
|
"should throw NS_ERROR_NOT_AVAILABLE error"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
ok(!request.valid, "request should no longer be valid");
|
ok(!request.valid, "request should no longer be valid");
|
||||||
syncClipboardRequestGetData(request, "text/plain", true);
|
syncClipboardRequestGetData(
|
||||||
|
request,
|
||||||
|
"text/plain",
|
||||||
|
Cr.NS_ERROR_NOT_AVAILABLE
|
||||||
|
);
|
||||||
ok(!request.valid, "request should no longer be valid");
|
ok(!request.valid, "request should no longer be valid");
|
||||||
|
|
||||||
info(`check clipboard data again`);
|
info(`check clipboard data again`);
|
||||||
@@ -132,8 +140,12 @@ clipboardTypes.forEach(function (type) {
|
|||||||
() => {
|
() => {
|
||||||
ok(false, "asyncClipboardRequestGetData should not success");
|
ok(false, "asyncClipboardRequestGetData should not success");
|
||||||
},
|
},
|
||||||
() => {
|
e => {
|
||||||
ok(true, "asyncClipboardRequestGetData should reject");
|
is(
|
||||||
|
e,
|
||||||
|
Cr.NS_ERROR_NOT_AVAILABLE,
|
||||||
|
"should throw NS_ERROR_NOT_AVAILABLE error"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
ok(!request.valid, "request should no longer be valid");
|
ok(!request.valid, "request should no longer be valid");
|
||||||
@@ -164,9 +176,9 @@ add_task(async function test_clipboard_getDataSnapshotSync_html_data() {
|
|||||||
"Check data"
|
"Check data"
|
||||||
);
|
);
|
||||||
// Requesting a flavor that is not in the list should throw error.
|
// Requesting a flavor that is not in the list should throw error.
|
||||||
await asyncClipboardRequestGetData(request, "text/plain", true).catch(
|
await asyncClipboardRequestGetData(request, "text/plain", true).catch(e => {
|
||||||
() => {}
|
is(e, Cr.NS_ERROR_FAILURE, "should throw NS_ERROR_FAILURE error");
|
||||||
);
|
});
|
||||||
|
|
||||||
is(
|
is(
|
||||||
syncClipboardRequestGetData(request, "text/html"),
|
syncClipboardRequestGetData(request, "text/html"),
|
||||||
@@ -174,5 +186,5 @@ add_task(async function test_clipboard_getDataSnapshotSync_html_data() {
|
|||||||
"Check data (sync)"
|
"Check data (sync)"
|
||||||
);
|
);
|
||||||
// Requesting a flavor that is not in the list should throw error.
|
// Requesting a flavor that is not in the list should throw error.
|
||||||
syncClipboardRequestGetData(request, "text/plain", true);
|
syncClipboardRequestGetData(request, "text/plain", Cr.NS_ERROR_FAILURE);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user