Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 22 additions & 11 deletions lib/natives/proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,17 @@ export class ASProxy extends ASObject {
this.sec.throwError('flash.errors.IllegalOperationError', Errors.ProxyNextValueError);
}

/**
* Resolve a flash_proxy trap override. Subclass overrides should shadow the base
* trap at `proxyPrefix + name`, but the override trait can end up mangled into the
* public namespace (`$Bg` + name) instead, in which case the base thrower would
* win the lookup and dynamic property access on the proxy dies with error #2088-96.
* Prefer a public-mangled override when one exists.
*/
private _proxyTrap(name: string): Function {
return (<any> this)['$Bg' + name] || (<any> this)[proxyPrefix + name];
}

public axGetProperty(mn: Multiname) {
let value: any;
const trait = typeof mn.name === 'string' ? this.traits.getTrait(mn.namespaces, mn.name) : null;
Expand All @@ -101,17 +112,17 @@ export class ASProxy extends ASObject {
return this.axGetMethod(name);
}
} else {
value = this[proxyPrefix + 'getProperty'](this.sec.AXQName.FromMultiname(mn));
value = this._proxyTrap('getProperty').call(this, this.sec.AXQName.FromMultiname(mn));
}
return value;
}

public axGetNumericProperty(name: number): any {
return this[proxyPrefix + 'getProperty']((+name) + '');
return this._proxyTrap('getProperty').call(this, (+name) + '');
}

public axSetNumericProperty(name: number, value: any) {
this[proxyPrefix + 'setProperty']((+name) + '', value);
this._proxyTrap('setProperty').call(this, (+name) + '', value);
}

public axSetProperty(mn: Multiname, value: any, bc: Bytecode) {
Expand All @@ -120,7 +131,7 @@ export class ASProxy extends ASObject {
super.axSetProperty(mn, value, bc);
return;
}
this[proxyPrefix + 'setProperty'](this.sec.AXQName.FromMultiname(mn), value);
this._proxyTrap('setProperty').call(this, this.sec.AXQName.FromMultiname(mn), value);
}

public axCallProperty(mn: Multiname, args: any[], isLex: boolean): any {
Expand All @@ -129,7 +140,7 @@ export class ASProxy extends ASObject {
return super.axCallProperty(mn, args, isLex);
}
const callArgs = [this.sec.AXQName.FromMultiname(mn)].concat(args);
return this[proxyPrefix + 'callProperty'](...callArgs);
return this._proxyTrap('callProperty').apply(this, callArgs);
}

public axHasProperty(mn: Multiname): any {
Expand All @@ -141,35 +152,35 @@ export class ASProxy extends ASObject {
if (this.axHasPropertyInternal(rn)) {
return true;
}
return this[proxyPrefix + 'hasProperty'](nm);
return this._proxyTrap('hasProperty').call(this, nm);
}

public axHasOwnProperty(mn: Multiname): any {
const trait = typeof mn.name === 'string' ? this.traits.getTrait(mn.namespaces, mn.name) : null;
if (trait) {
return true;
}
return this[proxyPrefix + 'hasProperty'](this.sec.AXQName.FromMultiname(mn));
return this._proxyTrap('hasProperty').call(this, this.sec.AXQName.FromMultiname(mn));
}

public axDeleteProperty(mn: Multiname): any {
const trait = typeof mn.name === 'string' ? this.traits.getTrait(mn.namespaces, mn.name) : null;
if (trait) {
return delete this[trait.multiname.getMangledName()];
}
return this[proxyPrefix + 'deleteProperty'](this.sec.AXQName.FromMultiname(mn));
return this._proxyTrap('deleteProperty').call(this, this.sec.AXQName.FromMultiname(mn));
}

public axNextName(index: number): any {
return this[proxyPrefix + 'nextName'](index);
return this._proxyTrap('nextName').call(this, index);
}

public axNextValue(index: number): any {
return this[proxyPrefix + 'nextValue'](index);
return this._proxyTrap('nextValue').call(this, index);
}

public axNextNameIndex(index: number): number {
return this[proxyPrefix + 'nextNameIndex'](index);
return this._proxyTrap('nextNameIndex').call(this, index);
}
}

Expand Down