Resolve flash_proxy trap overrides mangled into the public namespace - #13
Open
neilrackett wants to merge 1 commit into
Open
Resolve flash_proxy trap overrides mangled into the public namespace#13neilrackett wants to merge 1 commit into
neilrackett wants to merge 1 commit into
Conversation
…espace
Subclass overrides of the flash_proxy traps (getProperty, setProperty,
callProperty, hasProperty, deleteProperty, nextName, nextValue,
nextNameIndex) are expected to shadow the base thrower at
proxyPrefix + name, but the override trait can be installed with a
public-namespace mangled name ($Bg + name) instead, depending on how the
SWF's ABC interns the flash_proxy namespace. The base thrower then wins
the lookup, and any dynamic property access or call on a Proxy subclass
dies with errors #2088-#2096 ('The Proxy class does not implement
<trap>. It must be overridden by a subclass.').
Route all trap dispatch through a resolver that prefers a public-mangled
override when one exists, and invoke it with an explicit receiver
(.call/.apply) so the trap body's scope chain sees the proxy instance.
Observed in the wild with an AS3/Flex-era app (compiled ~2012) whose
Proxy-based RPC service layer was completely non-functional under the
runtime; with this change all dynamic service calls route correctly.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Proxy: resolve flash_proxy trap overrides mangled into the public namespace
This PR fixes
flash.utils.Proxysubclasses whose trap overrides(
callProperty,getProperty,setProperty, …) were unreachable, so anydynamic property access or call on the proxy died with the base-class errors
#2088–#2096 ("The Proxy class does not implement trap. It must be
overridden by a subclass.") — even though the subclass clearly overrides them.
The bug
ASProxydispatches traps by looking upproxyPrefix + name, i.e. theflash_proxy-namespace mangled property (e.g.
$G_v0hLCcallProperty). That'swhere
classInitializerinstalls the base throwers, and where subclassoverrides are expected to shadow them.
In practice, though, the override trait from the SWF's ABC can be installed
under a public-namespace mangled name instead (
$BgcallProperty),depending on how the ABC's flash_proxy namespace is interned. The prototype
chain then looks like this:
…and every dynamic access on the proxy throws.
The fix
Route all trap dispatch through a small resolver that prefers a
public-mangled override when one exists, falling back to the
flash_proxy-mangled name:
The resolved trap is invoked with an explicit receiver (
.call(this, …)/.apply(this, …)) — the previous inlinethis[key](…)form kept thereceiver implicitly, so the rewrite preserves it deliberately: the trap
bodies are compiled AS3 whose scope chain must see the proxy instance.
Real-world impact
Found while reviving an AS3/Flex-era business app (compiled ~2012) whose
entire RPC layer is a
Proxysubclass — the AMFPHP/Flex idiom ofservice.anyMethodName(args)routed throughflash_proxy::getProperty/callProperty. Under the runtime the app hung on its preloader foreverbecause every service call threw #2090 (swallowed by a Timer handler). With
this change, all dynamic service calls route correctly and the app runs
end-to-end.
Companion PR in playerglobal (independent, but the same app needs both):
Flash Remoting (AMF over HTTP) support in NetConnection.