Browse Source

Fix `Object.defineProperty()` (#1005)

- Fix panic if first argument is not supplied.
 - Fix panic if second argument is not supplied.
 - Fix bug when the object is not a object.
 - Implemented `DefinePropertyOrThrow()`
pull/1016/head
Halid Odat 4 years ago committed by GitHub
parent
commit
4625c1ac29
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 28
      boa/src/builtins/object/mod.rs
  2. 29
      boa/src/object/gcobject.rs

28
boa/src/builtins/object/mod.rs

@ -287,19 +287,23 @@ impl Object {
/// Define a property in an object
pub fn define_property(_: &Value, args: &[Value], context: &mut Context) -> Result<Value> {
let obj = args.get(0).expect("Cannot get object");
let prop = args
.get(1)
.expect("Cannot get object")
.to_property_key(context)?;
let desc = if let Value::Object(ref object) = args.get(2).cloned().unwrap_or_default() {
object.to_property_descriptor(context)?
let object = args.get(0).cloned().unwrap_or_else(Value::undefined);
if let Some(mut object) = object.as_object() {
let key = args
.get(1)
.unwrap_or(&Value::undefined())
.to_property_key(context)?;
let desc = args
.get(2)
.unwrap_or(&Value::undefined())
.to_property_descriptor(context)?;
object.define_property_or_throw(key, desc, context)?;
Ok(object.into())
} else {
return context.throw_type_error("Property description must be an object");
};
obj.set_property(prop, desc);
Ok(obj.clone())
context.throw_type_error("Object.defineProperty called on non-object")
}
}
/// `Object.defineProperties( proto, [propertiesObject] )`

29
boa/src/object/gcobject.rs

@ -761,7 +761,6 @@ impl GcObject {
Ok(false)
}
}
#[inline]
#[track_caller]
pub fn has_own_property<K>(&self, key: K) -> bool
@ -771,6 +770,34 @@ impl GcObject {
let key = key.into();
self.get_own_property(&key).is_some()
}
/// Defines the property or throws a `TypeError` if the operation fails.
///
/// More information:
/// - [EcmaScript reference][spec]
///
/// [spec]: https://tc39.es/ecma262/#sec-definepropertyorthrow
#[inline]
pub(crate) fn define_property_or_throw<K, P>(
&mut self,
key: K,
desc: P,
context: &mut Context,
) -> Result<()>
where
K: Into<PropertyKey>,
P: Into<PropertyDescriptor>,
{
let key = key.into();
let desc = desc.into();
let success = self.define_own_property(key.clone(), desc);
if !success {
Err(context.construct_type_error(format!("Cannot redefine property: {}", key)))
} else {
Ok(())
}
}
}
impl AsRef<GcCell<Object>> for GcObject {

Loading…
Cancel
Save