Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions LayoutTests/http/wpt/identity/idl.https-expected.txt
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,5 @@ PASS DigitalCredential interface: existence and properties of interface prototyp
PASS DigitalCredential interface: attribute protocol
PASS DigitalCredential interface: attribute data
PASS DigitalCredential interface: operation userAgentAllowsProtocol(DOMString)
PASS DigitalCredential interface: operation toJSON()

1 change: 1 addition & 0 deletions LayoutTests/http/wpt/identity/idl.https.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
readonly attribute DOMString protocol;
readonly attribute Uint8Array data;
static boolean userAgentAllowsProtocol(DOMString protocol);
[Default] object toJSON();
};
</script>
<script>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ PASS navigator.credentials.get() promise is rejected if called with an aborted s
FAIL navigator.credentials.get() promise is rejected if abort controller is aborted after call to get(). promise_rejects_dom: function "function() { throw e }" threw object "NotSupportedError: Digital credentials are not supported." that is not a DOMException AbortError: property "code" is equal to 9, expected 20
FAIL navigator.credentials.get() promise is rejected if abort controller is aborted after call to get() in cross-origin iframe. assert_equals: expected "AbortError" but got "NotAllowedError"
PASS Mediation is required to get a DigitalCredential.
PASS Throws TypeError when request data is not JSON stringifiable.

Original file line number Diff line number Diff line change
Expand Up @@ -231,4 +231,24 @@
);
}
}, "Mediation is required to get a DigitalCredential.");

promise_test(async t => {
const throwingValues = [
BigInt(123),
(() => { const o = {}; o.self = o; return o; })(),
Symbol("foo")
];

for (const badValue of throwingValues) {
const options = makeGetOptions("openid4vp");
options.digital.requests[0].data = badValue;

await promise_rejects_js(
t,
TypeError,
navigator.credentials.get(options),
`Should throw for: ${String(badValue)}`
);
}
}, "Throws TypeError when request data is not JSON stringifiable.");
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ PASS navigator.credentials.get() promise is rejected if called with an aborted s
FAIL navigator.credentials.get() promise is rejected if abort controller is aborted after call to get(). promise_rejects_dom: function "function() { throw e }" threw object "NotSupportedError: Digital credentials are not supported." that is not a DOMException AbortError: property "code" is equal to 9, expected 20
FAIL navigator.credentials.get() promise is rejected if abort controller is aborted after call to get() in cross-origin iframe. assert_equals: expected "AbortError" but got "NotAllowedError"
PASS Mediation is required to get a DigitalCredential.
PASS Throws TypeError when request data is not JSON stringifiable.

Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ PASS navigator.credentials.get() promise is rejected if called with an aborted s
FAIL navigator.credentials.get() promise is rejected if abort controller is aborted after call to get(). promise_rejects_dom: function "function() { throw e }" threw object "NotSupportedError: Digital credentials are not supported." that is not a DOMException AbortError: property "code" is equal to 9, expected 20
FAIL navigator.credentials.get() promise is rejected if abort controller is aborted after call to get() in cross-origin iframe. assert_equals: expected "AbortError" but got "NotAllowedError"
PASS Mediation is required to get a DigitalCredential.
PASS Throws TypeError when request data is not JSON stringifiable.

5 changes: 5 additions & 0 deletions Source/WebCore/Modules/identity/DigitalCredential.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ static ExceptionOr<UnvalidatedDigitalCredentialRequest> jsToCredentialRequest(co
auto scope = DECLARE_THROW_SCOPE(document.globalObject()->vm());
auto* globalObject = document.globalObject();

// Check that the object is JSON stringifiable.
JSC::JSONStringify(globalObject, request.data.get(), 0);
if (scope.exception()) [[unlikely]]
return Exception { ExceptionCode::ExistingExceptionError };

switch (request.protocol) {
case IdentityCredentialProtocol::OrgIsoMdoc: {
auto result = convertDictionary<MobileDocumentRequest>(*globalObject, request.data.get());
Expand Down
1 change: 1 addition & 0 deletions Source/WebCore/Modules/identity/DigitalCredential.idl
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,5 @@
[SameObject] readonly attribute object data;
readonly attribute IdentityCredentialProtocol protocol;
static boolean userAgentAllowsProtocol(DOMString protocol);
[Default] object toJSON();
};