diff --git a/builtins/web/crypto/json-web-key.cpp b/builtins/web/crypto/json-web-key.cpp index 65617341..5344a639 100644 --- a/builtins/web/crypto/json-web-key.cpp +++ b/builtins/web/crypto/json-web-key.cpp @@ -19,17 +19,15 @@ namespace builtins::web::crypto { namespace { JS::Result> extractStringPropertyFromObject(JSContext *cx, JS::HandleObject object, const char* property) { - bool has_property = false; - if (!JS_HasProperty(cx, object, property, &has_property)) { - return JS::Result>(JS::Error()); - } - if (!has_property) { - return std::optional(std::nullopt); - } JS::RootedValue value(cx); if (!JS_GetProperty(cx, object, property, &value)) { return JS::Result>(JS::Error()); } + // A dictionary member whose value is undefined is treated as not present: + // https://webidl.spec.whatwg.org/#js-dictionary + if (value.isUndefined()) { + return std::optional(std::nullopt); + } // Convert into a String following https://tc39.es/ecma262/#sec-tostring auto chars = core::encode(cx, value); if (!chars) { @@ -163,30 +161,22 @@ std::unique_ptr JsonWebKey::parse(JSContext *cx, JS::HandleValue val // boolean ext; std::optional ext = std::nullopt; { - bool has_ext = false; - if (!JS_HasProperty(cx, object, "ext", &has_ext)) { + JS::RootedValue ext_val(cx); + if (!JS_GetProperty(cx, object, "ext", &ext_val)) { return nullptr; } - if (has_ext) { - JS::RootedValue ext_val(cx); - if (!JS_GetProperty(cx, object, "ext", &ext_val)) { - return nullptr; - } + if (!ext_val.isUndefined()) { ext = JS::ToBoolean(ext_val); } } // sequence key_ops; std::vector key_ops; { - bool has_key_ops = false; - if (!JS_HasProperty(cx, object, "key_ops", &has_key_ops)) { + JS::RootedValue key_ops_val(cx); + if (!JS_GetProperty(cx, object, "key_ops", &key_ops_val)) { return nullptr; } - if (has_key_ops) { - JS::RootedValue key_ops_val(cx); - if (!JS_GetProperty(cx, object, "key_ops", &key_ops_val)) { - return nullptr; - } + if (!key_ops_val.isUndefined()) { bool key_ops_is_array = false; if (!JS::IsArrayObject(cx, key_ops_val, &key_ops_is_array)) { return nullptr; @@ -255,15 +245,11 @@ std::unique_ptr JsonWebKey::parse(JSContext *cx, JS::HandleValue val std::vector oth; { - bool has_oth = false; - if (!JS_HasProperty(cx, object, "oth", &has_oth)) { + JS::RootedValue oth_val(cx); + if (!JS_GetProperty(cx, object, "oth", &oth_val)) { return nullptr; } - if (has_oth) { - JS::RootedValue oth_val(cx); - if (!JS_GetProperty(cx, object, "oth", &oth_val)) { - return nullptr; - } + if (!oth_val.isUndefined()) { bool oth_is_array = false; if (!JS::IsArrayObject(cx, oth_val, &oth_is_array)) { return nullptr; diff --git a/tests/wpt-harness/expectations/WebCryptoAPI/import_export/okp_importKey_failures_Ed25519.https.any.js.json b/tests/wpt-harness/expectations/WebCryptoAPI/import_export/okp_importKey_failures_Ed25519.https.any.js.json index 19e96014..894f04da 100644 --- a/tests/wpt-harness/expectations/WebCryptoAPI/import_export/okp_importKey_failures_Ed25519.https.any.js.json +++ b/tests/wpt-harness/expectations/WebCryptoAPI/import_export/okp_importKey_failures_Ed25519.https.any.js.json @@ -2253,37 +2253,37 @@ "status": "PASS" }, "Import from a non-extractable: importKey(jwk (public) , Ed25519, true, [verify])": { - "status": "FAIL" + "status": "PASS" }, "Import from a non-extractable: importKey(jwk(private), {name: Ed25519}, true, [sign])": { "status": "PASS" }, "Import from a non-extractable: importKey(jwk (public) , {name: Ed25519}, true, [verify])": { - "status": "FAIL" + "status": "PASS" }, "Invalid 'use' field: importKey(jwk(private), Ed25519, true, [sign])": { "status": "PASS" }, "Invalid 'use' field: importKey(jwk (public) , Ed25519, true, [verify])": { - "status": "FAIL" + "status": "PASS" }, "Invalid 'use' field: importKey(jwk(private), {name: Ed25519}, true, [sign])": { "status": "PASS" }, "Invalid 'use' field: importKey(jwk (public) , {name: Ed25519}, true, [verify])": { - "status": "FAIL" + "status": "PASS" }, "Invalid 'crv' field: importKey(jwk(private), Ed25519, true, [sign])": { "status": "PASS" }, "Invalid 'crv' field: importKey(jwk (public) , Ed25519, true, [verify])": { - "status": "FAIL" + "status": "PASS" }, "Invalid 'crv' field: importKey(jwk(private), {name: Ed25519}, true, [sign])": { "status": "PASS" }, "Invalid 'crv' field: importKey(jwk (public) , {name: Ed25519}, true, [verify])": { - "status": "FAIL" + "status": "PASS" }, "Invalid 'alg' field 'ed25519': importKey(jwk(private), Ed25519, true, [sign])": { "status": "PASS" @@ -2292,10 +2292,10 @@ "status": "PASS" }, "Invalid 'alg' field 'ed25519': importKey(jwk (public) , Ed25519, true, [verify])": { - "status": "FAIL" + "status": "PASS" }, "Invalid 'alg' field 'ED25519': importKey(jwk (public) , Ed25519, true, [verify])": { - "status": "FAIL" + "status": "PASS" }, "Invalid 'alg' field 'ed25519': importKey(jwk(private), {name: Ed25519}, true, [sign])": { "status": "PASS" @@ -2304,9 +2304,9 @@ "status": "PASS" }, "Invalid 'alg' field 'ed25519': importKey(jwk (public) , {name: Ed25519}, true, [verify])": { - "status": "FAIL" + "status": "PASS" }, "Invalid 'alg' field 'ED25519': importKey(jwk (public) , {name: Ed25519}, true, [verify])": { - "status": "FAIL" + "status": "PASS" } } \ No newline at end of file