From 511b0b583239fe6b1a7a8b81fe7d8046a3305080 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ralph=20K=C3=BCpper?= Date: Thu, 4 Jun 2026 15:40:01 +0200 Subject: [PATCH] fix(runtime): don't let typed-array own-property fallback shadow secret-key buffer metadata MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #4363 (typed array own properties) added a typed-array own-property block at the top of js_object_get_field_by_name that, for a Uint8Array-backed buffer, returns undefined for any key it doesn't recognize. A KeyObject's secret-key backing buffer is a Uint8Array, so its type / symmetricKeySize / asymmetricKey* metadata (resolved by the KeyObject block later in the same function) was shadowed and read back as undefined — a deterministic regression that fails the secret_key_buffer_metadata_survives_ic_miss_for_aes_sizes unit test on main (and every PR's cargo-test). Fix: fall through to the metadata block for a secret-key buffer instead of returning the typed-array undefined fallback. Plain typed arrays are unchanged (still return undefined for unknown keys). cargo test -p perry-runtime --lib: 979 passed, 0 failed (was 1 failed). --- crates/perry-runtime/src/object/field_get_set.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/crates/perry-runtime/src/object/field_get_set.rs b/crates/perry-runtime/src/object/field_get_set.rs index 61ad8237e7..dd68e233b8 100644 --- a/crates/perry-runtime/src/object/field_get_set.rs +++ b/crates/perry-runtime/src/object/field_get_set.rs @@ -2099,7 +2099,15 @@ pub extern "C" fn js_object_get_field_by_name( } } } - return JSValue::undefined(); + // #4363 regression fix: a secret-key Uint8Array (KeyObject backing + // buffer) exposes `type` / `symmetricKeySize` / `asymmetricKey*` + // through the KeyObject metadata block later in this function. The + // typed-array own-property fallback must not shadow those with + // `undefined` — fall through for a secret-key buffer so the metadata + // block resolves them. Plain typed arrays keep the `undefined` result. + if !crate::buffer::is_secret_key(addr) { + return JSValue::undefined(); + } } // #2128: a plain JS number value (a finite double or canonical NaN — // anything `JSValue::is_number` returns true for *minus* the raw-I64