From 4a7cb511483d4b0b9a0716e355b863db9769aad5 Mon Sep 17 00:00:00 2001 From: Adrian Wielgosik Date: Thu, 11 Aug 2022 19:46:36 +0200 Subject: [PATCH] avm2: Make missing props on sealed classes throw properly --- core/src/avm2/object/script_object.rs | 14 ++++++-- .../swfs/avm2/es4_oop_prototypes/Test.as | 31 ++++++++++++++++-- .../swfs/avm2/es4_oop_prototypes/output.txt | 5 +++ .../swfs/avm2/es4_oop_prototypes/test.fla | Bin 3985 -> 0 bytes .../swfs/avm2/es4_oop_prototypes/test.swf | Bin 1123 -> 1086 bytes 5 files changed, 44 insertions(+), 6 deletions(-) delete mode 100644 tests/tests/swfs/avm2/es4_oop_prototypes/test.fla diff --git a/core/src/avm2/object/script_object.rs b/core/src/avm2/object/script_object.rs index 860a860a7..aaccc9bc6 100644 --- a/core/src/avm2/object/script_object.rs +++ b/core/src/avm2/object/script_object.rs @@ -166,11 +166,19 @@ impl<'gc> ScriptObjectData<'gc> { }; let value = self.values.get(&local_name); - if let Some(value) = value { return Ok(*value); - } else if let Some(proto) = self.proto() { - return proto.get_property_local(multiname, activation); + } + + // follow the prototype chain + let mut proto = self.proto(); + while let Some(obj) = proto { + let obj = obj.base(); + let value = obj.values.get(&local_name); + if let Some(value) = value { + return Ok(*value); + } + proto = obj.proto(); } // Special case: Unresolvable properties on dynamic classes are treated diff --git a/tests/tests/swfs/avm2/es4_oop_prototypes/Test.as b/tests/tests/swfs/avm2/es4_oop_prototypes/Test.as index c90c7052e..6b7939ef9 100644 --- a/tests/tests/swfs/avm2/es4_oop_prototypes/Test.as +++ b/tests/tests/swfs/avm2/es4_oop_prototypes/Test.as @@ -1,5 +1,11 @@ -package { - public class Test {} +// compiled with mxmlc + +package { + import flash.display.MovieClip; + public class Test extends MovieClip { + public function Test() { + } + } } class ES4Class extends Object { @@ -50,4 +56,23 @@ trace(x.test_proto_var); x.test_method(); ES4Class.test_static(); x.test_proto_method(); -trace(x.test_get); \ No newline at end of file +trace(x.test_get); + +trace("-----------------") + +class SealedClass{} +SealedClass.prototype.field = 1; +x = new SealedClass(); +trace(x.field); +try { + trace(x.nofield); +} catch (e) { + trace("Caught missing field") +} + +dynamic class DynamicClass{} +DynamicClass.prototype.field = 1; +x = new DynamicClass(); +trace(x.field); +trace(x.nofield); + diff --git a/tests/tests/swfs/avm2/es4_oop_prototypes/output.txt b/tests/tests/swfs/avm2/es4_oop_prototypes/output.txt index 2e4c7dbd7..5597f8ddc 100644 --- a/tests/tests/swfs/avm2/es4_oop_prototypes/output.txt +++ b/tests/tests/swfs/avm2/es4_oop_prototypes/output.txt @@ -6,3 +6,8 @@ ES4Class test_method ES4Class test_static ES4Class test_proto_method ES4Class test_get +----------------- +1 +Caught missing field +1 +undefined diff --git a/tests/tests/swfs/avm2/es4_oop_prototypes/test.fla b/tests/tests/swfs/avm2/es4_oop_prototypes/test.fla deleted file mode 100644 index e8422682499736c841d221c3be55563405f47944..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3985 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 diff --git a/tests/tests/swfs/avm2/es4_oop_prototypes/test.swf b/tests/tests/swfs/avm2/es4_oop_prototypes/test.swf index 1c4962132eeba625589691671ee9eca692cdcdd6..70598473e8b7ff20b59628f141c742809862179a 100644 GIT binary patch literal 1086 zcmV-E1i|}SS5qrJ2mk;r1ONbC001BW06YKujv4yj=Vl0?JwAo?b#KsqVKo~Xixy4a z1v37mOh!q!duw(1D_l1z3z0VgHxB9Y;ryOt+H4UaGwq-bc5tB0m@amJ@Zeci1_!QZnT84W^-kDu!b~qNjlRVSVp3_xhTH3JNC+2)1J*>=-p>|kv2*_BK)@TdzxW~s5 zRX~U5S-?);A+G44YL3M0*f=<)^i{biPBGOIR$lYO&{zPAusrYQ+MNi=aD#T4!$ zPkS*y6Mr~&jb2>K)qny&rD&(ESY3$E?lK{?1zUms&{I3Vb02(qq)A{sjKOOY^24bQtYDw zh(LNvk6_-9ZixYgsUZ_Xs-b@GX-&pTkDn9d%>p~D2Lq@&ONvC|$1uRn?Xr8g41%gc zFmwg{BO~%rI`U&zg6#~gH_8IDHxf#DOIegISEYfB#nauVsuut5GA!7_+qCLvdN<#) zvDEWzPnK?*slnts?a)!Srf||36i30IzL%p(tbi~qbZjFAbFWBqVX$0X;=-?e*zJ2K z4^t@NJ544W6*(2EWgKX)>i6PSV&G4|?s>BmP$I0Z#I8Ha%6{IeEdu8D%5KdMG;fST zXfmOK-1UDj&R4?4V{$4wk5Ct7a{o-PGk?3Dj>wKcHXJUzo@U%l3cPaJ1oqj(0yOdH zhUyqyMUY|Hzja1+?5x7YJz@3>^~5#TQLjlZB-P4*^J(O~mc%kk4*Zi$PBebVxYQCac5hz}Lz44?z8k(uhL^=QgoakrMjAjxG5Kfs5>=Wza zIs9Gwckl-C1dk>nP0A)kT_NQ|^q%msK0qh?gk+C9`A^f;mPSX&@815%bP6Y`>nYT9phx#T#aWXuD8ekMShcz$^Dz1 zWc|CLt*so7Ak@WDVR?KX(klHCXm0rY!RhjYJD@91$0_&I*@WbMz1~x!D$M}qSk)OJ z8N#n@R9s&TO~-wo>c8BBX8fF#msmAI=~F51jolT%z%}3`AYWh{#0tU>5QS!q|M}db E_XwdUwEzGB literal 1123 zcmV-p1f2UrS5qr+2mkd*7cgcGOHhgtBgr(r?UVFP(np{deGmBw+#|`@IL4Dq8CLrC`_4Ig&e4%Rqu?n* zvA+_4W1JG(wA07qj_N{)p#4cC6o8pDy3-_S*fy=H=nvGE~+Q6M!Hn;WW z!X$kJ9(O($cE@Pt9@Rezy9jH=+qAp9{GRK*6a8Ft^`0o+vTc)}i_+RRtj5`Zd!$@B z`y`rn=jE~gZhzWV1Y4j{RabNT}WmK3lN-R8{SOf^GQ)uZ{ zzsoP#dt;!By{_J$nOKJGSFVmd3Hak;iXx0fF=9^Zxi zNfrYERm2Y5+dfP+x0@YdM)v&y_us(yaSt-&Fa!hPGpT#}p3$=*vM}Xp-_&if^ZzEi zrlxR)1=UO>l}x2FnRHTlmeK+kV?r=tixe}8LzILmj#3<>I8Jeb24|?8rpheEbCk?e zoMjBNutf0+drDZ0usC6BghdIPBP>DKJV*r^Dp7fZ%9~W)qVkKF|79It(#@T~3cw1& zlE-xT7$e2U1WQZ;BOsE4u*ZO9`pA&+aa)@ zZ;0JPDS|9>#nI@KX;Xo&vn)S+Dc7^Sqv^lXnF1 zuv4r@8sYY|o22H!gbPa^jJt575w6T2XR|>nDsr}9mqgABPfs64@Sp$w1BIvarNFBe!Xw?Y-9U(xcyl&TLuZj-NqhUK#nUx#~)F?bGwl>rRa%-N`8uMCX pL2G2S#uKf<;Qv9&`oE5Hwe4iU<#l52X5J>g(dZ2*{{iRTXVK(cFO2{I