From af7c5914144989705750fa5f107aff3b19702401 Mon Sep 17 00:00:00 2001 From: pjh456 <147148383@qq.com> Date: Tue, 9 Jun 2026 21:18:16 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=AF=B9=20Object.pro?= =?UTF-8?q?totype=20=E9=9D=9E=20null=20=E8=B5=8B=E5=80=BC=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/oxide_vm/src/dispatch/property.rs | 13 +++++++++++++ crates/oxide_vm/src/vm.rs | 5 +++++ 2 files changed, 18 insertions(+) diff --git a/crates/oxide_vm/src/dispatch/property.rs b/crates/oxide_vm/src/dispatch/property.rs index 7cb78a4f..cad2ad74 100644 --- a/crates/oxide_vm/src/dispatch/property.rs +++ b/crates/oxide_vm/src/dispatch/property.rs @@ -98,6 +98,11 @@ impl Vm { let prop_name_si = self.property_key_si(self.regs[b]); if self.kernel.string_forge().lookup(prop_name_si).as_deref() == Some("__proto__") { let obj = unsafe { &mut *obj_ptr }; + if self.is_object_prototype(obj_ptr) && !self.regs[a].is_null() { + self.raise_type_error("Object.prototype.__proto__ is immutable")?; + self.pc += 3; + return Ok(()); + } obj.set_proto(self.regs[a]).map_err(|e| e.to_string())?; self.pc += 3; return Ok(()); @@ -171,6 +176,10 @@ impl Vm { let obj = unsafe { &mut *obj_ptr }; let prop_name_si = self.property_key_si(self.regs[b]); if self.kernel.string_forge().lookup(prop_name_si).as_deref() == Some("__proto__") { + if self.is_object_prototype(obj_ptr) && !self.regs[a].is_null() { + self.raise_type_error("Object.prototype.__proto__ is immutable")?; + return Ok(()); + } obj.set_proto(self.regs[a]).map_err(|e| e.to_string())?; return Ok(()); } @@ -199,6 +208,10 @@ impl Vm { let obj = unsafe { &mut *obj_ptr }; let prop_name_si = self.property_key_si(self.regs[a]); if self.kernel.string_forge().lookup(prop_name_si).as_deref() == Some("__proto__") { + if self.is_object_prototype(obj_ptr) && !self.regs[b].is_null() { + self.raise_type_error("Object.prototype.__proto__ is immutable")?; + return Ok(()); + } obj.set_proto(self.regs[b]).map_err(|e| e.to_string())?; return Ok(()); } diff --git a/crates/oxide_vm/src/vm.rs b/crates/oxide_vm/src/vm.rs index 8a6e8ad1..a6f13f95 100644 --- a/crates/oxide_vm/src/vm.rs +++ b/crates/oxide_vm/src/vm.rs @@ -198,6 +198,11 @@ impl Vm { &self.kernel } + pub(crate) fn is_object_prototype(&self, ptr: *const JsObject) -> bool { + let proto_ptr = self.kernel.builtin_world().object_proto.as_ptr(); + std::ptr::eq(ptr, proto_ptr) + } + pub fn reg(&self, idx: u8) -> JsValue { self.regs[idx as usize] }