Allow overwriting read-only virtual properties in scope chains.
The previous behavior had an oversight: if you tried to set a variable with the same name as an in-scope property, it would always try to overwrite that property. This can fail silently and doesn't match with Flash Player behavior. Now, an attempt to overwrite a read-only property is instead correctly rejected so that it can be defined in local scope.
This commit is contained in:
parent
bae0476113
commit
b8c24890fc
|
@ -108,6 +108,15 @@ impl<'gc> Property<'gc> {
|
|||
Property::Stored { attributes, .. } => !attributes.contains(DontEnum),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_overwritable(&self) -> bool {
|
||||
match self {
|
||||
Property::Virtual {
|
||||
attributes, set, ..
|
||||
} => !attributes.contains(ReadOnly) && !set.is_none(),
|
||||
Property::Stored { attributes, .. } => !attributes.contains(ReadOnly),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<'gc> gc_arena::Collect for Property<'gc> {
|
||||
|
@ -339,6 +348,13 @@ impl<'gc> Object<'gc> {
|
|||
self.values.contains_key(name)
|
||||
}
|
||||
|
||||
pub fn is_property_overwritable(&self, name: &str) -> bool {
|
||||
self.values
|
||||
.get(name)
|
||||
.map(|p| p.is_overwritable())
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
pub fn get_keys(&self) -> Vec<String> {
|
||||
self.values
|
||||
.iter()
|
||||
|
|
|
@ -288,7 +288,7 @@ impl<'gc> Scope<'gc> {
|
|||
context: &mut UpdateContext<'_, 'gc, '_>,
|
||||
this: GcCell<'gc, Object<'gc>>,
|
||||
) -> Result<Option<Value<'gc>>, Error> {
|
||||
if self.locals().has_property(name) {
|
||||
if self.locals().has_property(name) && self.locals().is_property_overwritable(name) {
|
||||
self.locals_mut(context.gc_context)
|
||||
.set(name, value, avm, context, this)?;
|
||||
return Ok(None);
|
||||
|
|
Loading…
Reference in New Issue