From 4197e4913bdd9931c00e247476867fbc1de87db2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Sat, 4 Dec 2021 08:28:48 +0100 Subject: [PATCH] Fixed #1763 AS3 - initialization of activation object in some cases --- CHANGELOG.md | 2 + .../flash/FinalProcessLocalData.java | 3 +- .../abc/avm2/AVM2FinalProcessLocalData.java | 21 +++++ .../flash/abc/avm2/graph/AVM2Graph.java | 23 +++++- .../ActionScript3AssembledDecompileTest.java | 6 ++ .../ActionScript3ClassicAirDecompileTest.java | 7 +- .../as3_assembled-0/as3_assembled-0.main.abc | Bin 7021 -> 7230 bytes .../as3_assembled-0.main.asasm | 1 + .../tests/TestActivationProps.class.asasm | 76 ++++++++++++++++++ .../tests/TestActivationProps.script.asasm | 29 +++++++ .../as3_assembled/bin/as3_assembled.swf | Bin 4250 -> 4362 bytes 11 files changed, 161 insertions(+), 7 deletions(-) create mode 100644 libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2FinalProcessLocalData.java create mode 100644 libsrc/ffdec_lib/testdata/as3_assembled/abc/as3_assembled-0/tests/TestActivationProps.class.asasm create mode 100644 libsrc/ffdec_lib/testdata/as3_assembled/abc/as3_assembled-0/tests/TestActivationProps.script.asasm diff --git a/CHANGELOG.md b/CHANGELOG.md index 74728161c..b82408689 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ All notable changes to this project will be documented in this file. - [#1762] AS call on integer numbers parenthesis - [#1762] AS3 - Auto adding returnvoid/return undefined - [#1762] AS - switch detection (mostcommon pathpart) +- [#1763] AS3 - initialization of activation object in some cases ## [15.0.0] - 2021-11-29 ### Added @@ -2325,6 +2326,7 @@ All notable changes to this project will be documented in this file. [alpha 7]: https://github.com/jindrapetrik/jpexs-decompiler/releases/tag/alpha7 [#1761]: https://www.free-decompiler.com/flash/issues/1761 [#1762]: https://www.free-decompiler.com/flash/issues/1762 +[#1763]: https://www.free-decompiler.com/flash/issues/1763 [#1750]: https://www.free-decompiler.com/flash/issues/1750 [#1485]: https://www.free-decompiler.com/flash/issues/1485 [#1681]: https://www.free-decompiler.com/flash/issues/1681 diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/FinalProcessLocalData.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/FinalProcessLocalData.java index e39342e1a..d129f4959 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/FinalProcessLocalData.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/FinalProcessLocalData.java @@ -12,7 +12,8 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library. */ + * License along with this library. + */ package com.jpexs.decompiler.flash; import com.jpexs.decompiler.graph.Loop; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2FinalProcessLocalData.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2FinalProcessLocalData.java new file mode 100644 index 000000000..941f76f88 --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2FinalProcessLocalData.java @@ -0,0 +1,21 @@ +package com.jpexs.decompiler.flash.abc.avm2; + +import com.jpexs.decompiler.flash.FinalProcessLocalData; +import com.jpexs.decompiler.graph.Loop; +import java.util.HashMap; +import java.util.List; + +/** + * + * @author JPEXS + */ +public class AVM2FinalProcessLocalData extends FinalProcessLocalData { + + public HashMap localRegNames; + + public AVM2FinalProcessLocalData(List loops, HashMap localRegNames) { + super(loops); + this.localRegNames = localRegNames; + } + +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2Graph.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2Graph.java index 061c21b77..c211c9b53 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2Graph.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2Graph.java @@ -21,6 +21,7 @@ import com.jpexs.decompiler.flash.FinalProcessLocalData; import com.jpexs.decompiler.flash.abc.ABC; import com.jpexs.decompiler.flash.abc.AVM2LocalData; import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2FinalProcessLocalData; import com.jpexs.decompiler.flash.abc.avm2.CodeStats; import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; @@ -46,6 +47,7 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushByteIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushScopeIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.types.CoerceAIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.types.ConvertIIns; +import com.jpexs.decompiler.flash.abc.avm2.model.AVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.ConstructAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.FilteredCheckAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.FindPropertyAVM2Item; @@ -114,6 +116,7 @@ import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; @@ -1966,6 +1969,24 @@ public class AVM2Graph extends Graph { Map localRegNames = body.getLocalRegNames(abc); loopi: for (int i = 0; i < list.size(); i++) { + if (list.get(i) instanceof SetPropertyAVM2Item) { + SetPropertyAVM2Item sp = (SetPropertyAVM2Item) list.get(i); + if (sp.object instanceof FindPropertyAVM2Item) { + if (sp.propertyName instanceof FullMultinameAVM2Item) { + FullMultinameAVM2Item propName = (FullMultinameAVM2Item) sp.propertyName; + if (sp.value instanceof LocalRegAVM2Item) { + LocalRegAVM2Item lr = (LocalRegAVM2Item) sp.value; + AVM2FinalProcessLocalData aLocalData = (AVM2FinalProcessLocalData) localData; + if (Objects.equals(propName.resolvedMultinameName, AVM2Item.localRegName(aLocalData.localRegNames, lr.regIndex))) { + list.remove(i); + i--; + continue loopi; + } + } + + } + } + } if (list.get(i) instanceof SetSlotAVM2Item) { SetSlotAVM2Item sslot = (SetSlotAVM2Item) list.get(i); if (sslot.slotObject instanceof NewActivationAVM2Item) { @@ -2155,7 +2176,7 @@ public class AVM2Graph extends Graph { @Override protected FinalProcessLocalData getFinalData(BaseLocalData localData, List loops, List throwStates) { - FinalProcessLocalData finalProcess = super.getFinalData(localData, loops, throwStates); + FinalProcessLocalData finalProcess = new AVM2FinalProcessLocalData(loops, ((AVM2LocalData) localData).localRegNames); finalProcess.registerUsage = ((AVM2LocalData) localData).setLocalPosToGetLocalPos; return finalProcess; } diff --git a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3AssembledDecompileTest.java b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3AssembledDecompileTest.java index e95a32d4a..01cf0321f 100644 --- a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3AssembledDecompileTest.java +++ b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3AssembledDecompileTest.java @@ -16,6 +16,12 @@ public class ActionScript3AssembledDecompileTest extends ActionScript3DecompileT addSwf("assembled", "testdata/as3_assembled/bin/as3_assembled.swf"); } + @Test + public void testActivationProps() { + decompileMethod("assembled", "testActivationProps", "\r\n", + false); + } + @Test public void testDeclareReg() { decompileMethod("assembled", "testDeclareReg", "with(other)\r\n" diff --git a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3ClassicAirDecompileTest.java b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3ClassicAirDecompileTest.java index 3765548e9..4cd5aa870 100644 --- a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3ClassicAirDecompileTest.java +++ b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3ClassicAirDecompileTest.java @@ -1039,7 +1039,6 @@ public class ActionScript3ClassicAirDecompileTest extends ActionScript3Decompile decompileMethod("classic_air", "testInlineFunctions", "var first:String = \"value1\";\r\n" + "var traceParameter:Function = function(aParam:String):String\r\n" + "{\r\n" - + "aParam = aParam;\r\n" + "var second:String = \"value2\";\r\n" + "second = second + \"cc\";\r\n" + "var traceParam2:Function = function(bParam:String):String\r\n" @@ -1057,8 +1056,7 @@ public class ActionScript3ClassicAirDecompileTest extends ActionScript3Decompile @Test public void testInnerFunctionScope() { - decompileMethod("classic_air", "testInnerFunctionScope", "a = a;\r\n" - + "var innerFunc:Function = function(b:String):*\r\n" + decompileMethod("classic_air", "testInnerFunctionScope", "var innerFunc:Function = function(b:String):*\r\n" + "{\r\n" + "testProm = 4;\r\n" + "trace(testProm);\r\n" @@ -1069,8 +1067,7 @@ public class ActionScript3ClassicAirDecompileTest extends ActionScript3Decompile @Test public void testInnerFunctions() { - decompileMethod("classic_air", "testInnerFunctions", "a = a;\r\n" - + "var s:int = 0;\r\n" + decompileMethod("classic_air", "testInnerFunctions", "var s:int = 0;\r\n" + "var innerFunc:Function = function(b:String):*\r\n" + "{\r\n" + "trace(b);\r\n" diff --git a/libsrc/ffdec_lib/testdata/as3_assembled/abc/as3_assembled-0/as3_assembled-0.main.abc b/libsrc/ffdec_lib/testdata/as3_assembled/abc/as3_assembled-0/as3_assembled-0.main.abc index 7a52bbf8efc5543a798b77bbaf06c7b8b6b6d135..0654c160d3afad6bf1b9741a448188d9abd26a81 100644 GIT binary patch delta 2639 zcmZuxNpKs-75%?4gPz7Z1W9bRWL`fq`pa8Bz$yzK@wB?Pm zEP0V_MM@`?D$BQ2l8O>Lc5=uel~nnZE9FY4OH!3noJ&g5A(vFSm~NnulLz(j-~4|6 z_3vf=zkC1G&veKD$pU=!kUi>DFW=lOUdK@!!*TV%=JJ&d=gDi=*EW``XP4JEMi)2M zHj5i;SFg-mzj|%`tKZM7Ep$T+tX)}+NWVVtJ+$A|I(?+`c#s8qwbw$uAr@RyLHuS^ zO~kH*vSF7B;l8LVdNFz_`f~Jg^eUgxy27CDQ?r^DycT>Vs0Dw6p@$gyF@`n%NZaQR z{}RKGG5jkG{~DuxP5i0WgEQR2?hL9KB#Hyw*!=^f*iTXXe=bbEou+t{Vv6EBNZAHu zHz?jmYAV!qTa3E+pIKt7fs#f_&QQ`sNi!ual(bS3qoj?Jc1q%ubkIIG>mqdxwCe(8 zX^JN)Qi^*hc2oBr>eQ+CeWc!Q+P{}g5$0FedBQ$H!up+cja2KRt_Mh6KSa9cu9);J z#U#ZAii;FCDVn0bEsD3q$a}&*7Pgn-kA(XIsry5u&O_9Bm^x2TkDq#u(d;bkIYsv( zRTZjIswSxS1EjqlAyww6lH$L04eAENAVVKR#xTls2mj7B-VjIDfs7-$2#z#V9&{WB z4Lu(InP-B3=`p{@RF@-JraMgj$a6qYv@LXKa1Y!vP6;~p3wue}u&@zfqr%389f+PuY=+!_;#ONeA# zC@!Pe&rvvm>S>sRd02oIh$`q4WDRQ-Ko5o$AUXyWaMWN(0VRwP1=M=1SHRhXh5|H( z)e2}G7*&9!u|@%xiA@T)d$3UfPe1Akc=uyW0pAF=DVM-Mfh`K?(-=^o>IlXa2+Uxs z0@bIKh6yo?lL4yW0-{3cGM&XL1#0uytU$1c?FxjJu}*>T8u}H8h%1MH;cfGUTEOS2 zr2-qpgh1(~f{SPT_2=(nKm*v$B|!H8j%Ec4WLNUM3O^ly(yC}SZLU_ z{6GGVHqVXZ!@MU|^vq{c#f)HjD$Fg(T(O8@hxwRZaK9zrS1pHO2l?lEqVJ_ess{kr z0$tErZ_Oqbolm}5P;Dy!L>5+ zAU7@dI#yZ0>$0A!mS))1{A?g@blu>^E2nXj`Gg}!|pd^#**bS>>B>h zz^3QD65+DtHtZ&DSGVC1zh529T02u|&)pq){AsW7itxU>J89>RQ17Xz-z_Cyu{?&| z$aku<&9CMV4YB??z!B)LRQal$vtW4*TjzZ8|B49#=k;d!-`smd~(b{Bcbx(>aNlSjK$k zO6TN3xP2M(LSM%8uoQe^&Ove~X^Jxt0~zk9ZH}G;1Q4CFtoTt$anbS{b{ik6?KqVe z^XjwZN(UtNVyWsuiT_)Uk4gM(8Ba+3mogrb`0FyBl=zD>Ug3YJ{n?a9M8v|pW#=oq zgJpN5>~dvyT)3ubfQd?#AC#(Gvvk95;lBu`*}EtgxjpITe+xFUJO6)ELS62g@(5nB zsth~8he9dr;0Ukwnu?(4L9b%bp=6u9&+1*Y?ew_~uhRCu$N0R^UI4 zbommc^Sn?F75P6RtDg5u^KMu{!*1p$qbWScx1v!z#XpVK52oUFYRb@v5Lgu(Ifc%y zZYOn|mTmKlY?~H1R47)~@Nr3N-U=CZJAV;PY)vQggQ-J8odt!;$)yKtT39{I%fGPd&ySs^m*tq42>g|%MZG{cHPQ+KlbyFPMrhu!6it5}p xw-1W$0X9(-HSi2e_y3IOU}h}e@ub)xKCBMeSk|PV?3$Z$>#kW5!}g1`{{f5H<&*#b delta 2389 zcmX|>S#ul55rDe~yOHsBD(uxu&fR|Rbbyx>| zi?l4thjNG>yDF7D=OMD4O3LqX{0}I{p(~YgUY%4bW%@NQ%nVS-q8j~ePhT^=HGdlV z&j8aQ3#1p|iyiixAdce%PO2w1)^6Q*&fmFv2e_RxVo zc7iaU!WId8ii8a~<4siSqOM;cbv;9xdrwrjM6r`%iDH@JeTrF%?@)Y5@v&I@NJt;W zkA-@U)crnE=L~h8q|W3V_4uggH0?Q0`{rpsQdOZUrD~FTpCCQ_AyUPnN{TD)VLi;y z$B;3MF~5W9$P4bt;0}^?aHOI3pri2RXYNsSbyh8oEbu?Lr^M#baa72#kYhrQ3mFwM zE@ZO7n`1s8coe}=PsF61s36b?VaLHG(H$ae1bhaT*eHZ0M&g7`Kulu1 zk+4Z?j-(xCw0ygpEOmG$(_E4MSR@*-Y38$V%*PB5VqJCHDCV8-xLggKdPJ zgrgFN6NJseafzd?gymsE;$$6RM_^iFzJsvSFe~xYA;MRsJhqdUH&qSw>t!-(61@21p*j;ULWA-^~>VYvw^|RtTcjwwqgn63Lb3 za;4L`(%D?;Os!h-%b=o#hF#C^>7DKF2kD)n z+bp}6GG;j=JUunfx1{H)MGQN_|E!nXZ^-vG%VF3dZq}s+hgYZ`0AR~>S!>%mpI&jk z_-0ux9CP$it?q||1Cgt~mg`L!d&g1?JItTfB~8yxy67>>o&>2^#lHIreUKOa(VG9; z(*K&J8g`Wbqpqu`C-VU=tLZJ@3-cxxW=N^0a1!!>mjHdxSc}?}Q668POrGuXP+&*)+e47rsYW|YKb>w z$W2Q#>;V5;AlcaUfS0?3Lubw59qDk}Vuszojo_&JHTk}5xePnVuLn0gk19o9w%mr@ z%>NZ^#}V$Y5BFZ&%V*r%dvf*}kI;(H-tE1Nb5A7iuXX%xCHNJ~W7tjnQhjghg94%< zc5eY5hoM>z_hii_%WK$v{=7c9xGubwT+=RCQT2K;rzOnv3e&QhSoMiQvY7tQg9F_y zKET|HQ!Hm>1ZJE<5ybER=PeS z`M*{BnB*U-JR$kpDvwD1y2?|Me_!QQJ`(LW~=H{i|x$*^}(ZgO|p#fy<<_UQj_+mUYf137|QR-Iwj@vkB#n*869R?ml( z6gRAZVR!IobSQgu98>#sOt(ajC0yMPW!{vQpf0AqE6?q_%DKs_hzf=&xhO>KK&MKdJj2nLA6GS=RQGnOB#XS!R5vVbpzJwzgu0 z3|r@aZ%DPg2HKC}zGXimC9Z^e@2?#jd&!OO^n&O~3~Y%fV%@%EWuDinrfa+$yY6|f zQukFWY}hUQ+n9-$KaR(6p2y>j!>Od5${QLH@oVB7^XTmEb5h5Gyeu!s%km;PR4CWB z@IfWjRV!lH?fh;$H9ws$9x-Q+K)Q6w%zTb!xw8vdI$!{NZKl)f-HBA<_VaRQ1zBQ2 dps9a8g@*W{|9V#sVo2h diff --git a/libsrc/ffdec_lib/testdata/as3_assembled/abc/as3_assembled-0/as3_assembled-0.main.asasm b/libsrc/ffdec_lib/testdata/as3_assembled/abc/as3_assembled-0/as3_assembled-0.main.asasm index 489896ae4..0f8b76834 100644 --- a/libsrc/ffdec_lib/testdata/as3_assembled/abc/as3_assembled-0/as3_assembled-0.main.asasm +++ b/libsrc/ffdec_lib/testdata/as3_assembled/abc/as3_assembled-0/as3_assembled-0.main.asasm @@ -29,5 +29,6 @@ program #include "tests/TestSwitchGoto.script.asasm" #include "tests/TestTryWhile.script.asasm" #include "tests/TestPushWhile.script.asasm" + #include "tests/TestActivationProps.script.asasm" ; place to add next end ; program diff --git a/libsrc/ffdec_lib/testdata/as3_assembled/abc/as3_assembled-0/tests/TestActivationProps.class.asasm b/libsrc/ffdec_lib/testdata/as3_assembled/abc/as3_assembled-0/tests/TestActivationProps.class.asasm new file mode 100644 index 000000000..f2e11ef7d --- /dev/null +++ b/libsrc/ffdec_lib/testdata/as3_assembled/abc/as3_assembled-0/tests/TestActivationProps.class.asasm @@ -0,0 +1,76 @@ +class + refid "tests:TestActivationProps" + instance QName(PackageNamespace("tests"), "TestActivationProps") + extends QName(PackageNamespace(""), "Object") + flag SEALED + flag PROTECTEDNS + protectedns ProtectedNamespace("tests:TestActivationProps") + iinit + refid "tests:TestActivationProps/instance/init" + body + maxstack 1 + localcount 1 + initscopedepth 4 + maxscopedepth 5 + code + getlocal0 + pushscope + + getlocal0 + constructsuper 0 + + returnvoid + end ; code + end ; body + end ; method + trait method QName(PackageNamespace(""), "run") + method + refid "tests:TestActivationProps/instance/run" + flag HAS_OPTIONAL + flag HAS_PARAM_NAMES + flag NEED_ACTIVATION + param QName(PackageNamespace(""),"int") + paramname "myvar" + returns QName(PackageNamespace(""), "void") + body + maxstack 2 + localcount 4 + initscopedepth 4 + maxscopedepth 5 + trait slot QName(PackageInternalNs("testing"),"myvar") + slotid 1 + type QName(PackageNamespace(""),"int") + end ; trait + code + debug 1, "myvar", 0, 0 + getlocal0 + pushscope + newactivation + dup + setlocal 6 + pushscope + findpropstrict QName(PackageInternalNs("testing"),"myvar") + getlocal1 + setproperty QName(PackageInternalNs("testing"),"myvar") + returnvoid + end ; code + end ; body + end ; method + end ; trait + end ; instance + cinit + refid "tests:TestActivationProps/class/init" + body + maxstack 1 + localcount 1 + initscopedepth 3 + maxscopedepth 4 + code + getlocal0 + pushscope + + returnvoid + end ; code + end ; body + end ; method +end ; class diff --git a/libsrc/ffdec_lib/testdata/as3_assembled/abc/as3_assembled-0/tests/TestActivationProps.script.asasm b/libsrc/ffdec_lib/testdata/as3_assembled/abc/as3_assembled-0/tests/TestActivationProps.script.asasm new file mode 100644 index 000000000..711260a68 --- /dev/null +++ b/libsrc/ffdec_lib/testdata/as3_assembled/abc/as3_assembled-0/tests/TestActivationProps.script.asasm @@ -0,0 +1,29 @@ +script + sinit + refid "tests:TestActivationProps/init" + body + maxstack 2 + localcount 1 + initscopedepth 1 + maxscopedepth 3 + code + getlocal0 + pushscope + + findpropstrict Multiname("TestActivationProps", [PackageNamespace("tests")]) + getlex QName(PackageNamespace(""), "Object") + pushscope + + getlex Multiname("Object", [PrivateNamespace(null, "tests:TestActivationProps"), PackageNamespace(""), PackageNamespace("tests"), PackageInternalNs("tests"), Namespace("http://adobe.com/AS3/2006/builtin")]) + newclass "tests:TestActivationProps" + popscope + initproperty QName(PackageNamespace("tests"), "TestActivationProps") + + returnvoid + end ; code + end ; body + end ; method + trait class QName(PackageNamespace("tests"), "TestActivationProps") + #include "TestActivationProps.class.asasm" + end ; trait +end ; script diff --git a/libsrc/ffdec_lib/testdata/as3_assembled/bin/as3_assembled.swf b/libsrc/ffdec_lib/testdata/as3_assembled/bin/as3_assembled.swf index 6fdb3d7a9f72b16a5eac7e23a0e790f125fd1c45..8025de6d453db8325b3ee94e29dc042bb8e77e6d 100644 GIT binary patch literal 4362 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 literal 4250 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