Fixed #1894 AS3 - XML filters in some corner cases

This commit is contained in:
Jindra Petřík
2022-11-30 19:36:16 +01:00
parent a41926a662
commit e588cbda3a
8 changed files with 41 additions and 2 deletions

View File

@@ -23,6 +23,7 @@ All notable changes to this project will be documented in this file.
- AS3 - XML - get descendants operator parenthesis
- Switch decompilation in some corner cases
- [#1894] Switches vs loops decompilation (now with two passes)
- [#1894] AS3 - XML filters in some corner cases
## [17.0.2] - 2022-11-22
### Fixed

View File

@@ -1656,6 +1656,9 @@ public class AVM2Graph extends Graph {
@Override
protected GraphTargetItem checkLoop(List<GraphTargetItem> output, LoopItem loopItem, BaseLocalData localData, List<Loop> loops, List<ThrowState> throwStates, TranslateStack stack) {
if (debugDoNotProcess) {
return loopItem;
}
AVM2LocalData aLocalData = (AVM2LocalData) localData;
if (loopItem instanceof WhileItem) {
WhileItem w = (WhileItem) loopItem;
@@ -1775,6 +1778,8 @@ public class AVM2Graph extends Graph {
regIndex = setLocal.regIndex;
}
}
} else if (output.get(i) instanceof PushItem) {
//ignored
} else {
break;
}
@@ -1795,6 +1800,8 @@ public class AVM2Graph extends Graph {
setLocalIp = avm2code.adr2pos(setLocal.getSrc().getAddress());
break;
}
} else if (output.get(i) instanceof PushItem){
//allowed
} else {
break;
}
@@ -1818,11 +1825,21 @@ public class AVM2Graph extends Graph {
if (setLocal.regIndex == regIndex) {
setLocal.value = filter;
}
} else if (output.get(i) instanceof PushItem) {
//ignored
} else {
break;
}
}
for (int i = output.size() - 2 /*last is loop*/; i >= 0; i--) {
if (output.get(i) instanceof PushItem) {
PushItem pu = (PushItem)output.remove(i);
stack.push(pu.value);
} else {
break;
}
}
if (usages.isEmpty()) {
output.add(filter);
} else {
@@ -2010,7 +2027,9 @@ public class AVM2Graph extends Graph {
@Override
protected void finalProcess(List<GraphTargetItem> list, int level, FinalProcessLocalData localData, String path) throws InterruptedException {
if (debugDoNotProcess) {
return;
}
if (level == 0) {
if (!list.isEmpty()) {
if (list.get(list.size() - 1) instanceof ReturnVoidAVM2Item) {

View File

@@ -90,6 +90,7 @@ public class Graph {
private boolean debugPrintLoopList = false;
private boolean debugGetLoops = false;
private boolean debugPrintGraph = false;
protected boolean debugDoNotProcess = false;
private static final Logger logger = Logger.getLogger(Graph.class.getName());
@@ -913,6 +914,9 @@ public class Graph {
}
private void finalProcessAll(List<GraphTargetItem> list, int level, FinalProcessLocalData localData, String path) throws InterruptedException {
if (debugDoNotProcess) {
return;
}
finalProcess(list, level, localData, path);
for (GraphTargetItem item : list) {
if (item instanceof Block) {
@@ -1191,6 +1195,9 @@ public class Graph {
}
protected void processIfs(List<GraphTargetItem> list) {
if (debugDoNotProcess) {
return;
}
for (int i = 0; i < list.size(); i++) {
GraphTargetItem item = list.get(i);
if ((item instanceof LoopItem) && (item instanceof Block)) {

View File

@@ -1875,6 +1875,9 @@ public class ActionScript3ClassicAirDecompileTest extends ActionScript3Decompile
+ "var all:String = myXML.@*.toXMLString();\r\n"
+ "k = myXML.book;\r\n"
+ "k = myXML.book.(@isbn == \"12345\");\r\n"
+ "var list:Vector.<int> = new Vector.<int>();\r\n"
+ "var i:int = Math.random();\r\n"
+ "list[i] = myXML.book.(@isbn == i + 1);\r\n"
+ "var g:XML = <script>\r\n"
+ "<![CDATA[\r\n"
+ "function() {\r\n"

View File

@@ -1864,7 +1864,9 @@ public class ActionScript3ClassicDecompileTest extends ActionScript3DecompileTes
@Test
public void testXml() {
decompileMethod("classic", "testXml", "var g:XML = null;\r\n"
decompileMethod("classic", "testXml", "var list:Vector.<int> = null;\r\n"
+ "var i:int = 0;\r\n"
+ "var g:XML = null;\r\n"
+ "var testCdata:XML = null;\r\n"
+ "var testComment:XML = null;\r\n"
+ "var name:String = \"ahoj\";\r\n"
@@ -1877,6 +1879,9 @@ public class ActionScript3ClassicDecompileTest extends ActionScript3DecompileTes
+ "var all:String = myXML.@*.toXMLString();\r\n"
+ "k = myXML.book;\r\n"
+ "k = myXML.book.(@isbn == \"12345\");\r\n"
+ "list = new Vector.<int>();\r\n"
+ "i = int(Math.random());\r\n"
+ "list[i] = myXML.book.(@isbn == i + 1);\r\n"
+ "g = <script>\r\n"
+ "<![CDATA[\r\n"
+ "function() {\r\n"

View File

@@ -16,6 +16,10 @@ package tests
var all:String=myXML.@*.toXMLString();
k=myXML.book;
k=myXML.book.(@isbn=="12345");
var list:Vector.<int> = new Vector.<int>();
var i:int = int(Math.random());
list[i] = myXML.book.(@isbn == i + 1);
var g:XML = new XML("<script>\n\t\t\t\t<![CDATA[\n\t\t\t\t\tfunction() {\n\t\t\t\n\t\t\t\t\t\tFBAS = {\n\t\t\t\n\t\t\t\t\t\t\tsetSWFObjectID: function( swfObjectID ) {\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\tFBAS.swfObjectID = swfObjectID;\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\tinit: function( opts ) {\n\t\t\t\t\t\t\t\tFB.init( FB.JSON.parse( opts ) );\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\tFB.Event.subscribe( \'auth.sessionChange\', function( response ) {\n\t\t\t\t\t\t\t\t\tFBAS.updateSwfSession( response.session );\n\t\t\t\t\t\t\t\t} );\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\tsetCanvasAutoResize: function( autoSize, interval ) {\n\t\t\t\t\t\t\t\tFB.Canvas.setAutoResize( autoSize, interval );\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\tsetCanvasSize: function( width, height ) {\n\t\t\t\t\t\t\t\tFB.Canvas.setSize( { width: width, height: height } );\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\tlogin: function( opts ) {\n\t\t\t\t\t\t\t\tFB.login( FBAS.handleUserLogin, FB.JSON.parse( opts ) );\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\taddEventListener: function( event ) {\n\t\t\t\t\t\t\t\tFB.Event.subscribe( event, function( response ) {\n\t\t\t\t\t\t\t\t\tFBAS.getSwf().handleJsEvent( event, FB.JSON.stringify( response ) );\n\t\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\thandleUserLogin: function( response ) {\n\t\t\t\t\t\t\t\tif( response.session == null ) {\n\t\t\t\t\t\t\t\t\tFBAS.updateSwfSession( null );\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\tif( response.perms != null ) {\n\t\t\t\t\t\t\t\t\t// user is logged in and granted some permissions.\n\t\t\t\t\t\t\t\t\t// perms is a comma separated list of granted permissions\n\t\t\t\t\t\t\t\t\tFBAS.updateSwfSession( response.session, response.perms );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tFBAS.updateSwfSession( response.session );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\tlogout: function() {\n\t\t\t\t\t\t\t\tFB.logout( FBAS.handleUserLogout );\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\thandleUserLogout: function( response ) {\n\t\t\t\t\t\t\t\tswf = FBAS.getSwf();\n\t\t\t\t\t\t\t\tswf.logout();\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\tui: function( params ) {\n\t\t\t\t\t\t\t\tobj = FB.JSON.parse( params );\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\tmethod = obj.method;\n\t\t\t\t\t\t\t\tcb = function( response ) { FBAS.getSwf().uiResponse( FB.JSON.stringify( response ), method ); }\n\t\t\t\t\t\t\t\tFB.ui( obj, cb );\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\tgetSession: function() {\n\t\t\t\t\t\t\t\tsession = FB.getSession();\n\t\t\t\t\t\t\t\treturn FB.JSON.stringify( session );\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\tgetLoginStatus: function() {\n\t\t\t\t\t\t\t\tFB.getLoginStatus( function( response ) {\n\t\t\t\t\t\t\t\t\tif( response.session ) {\n\t\t\t\t\t\t\t\t\t\tFBAS.updateSwfSession( response.session );\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tFBAS.updateSwfSession( null );\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\tgetSwf: function getSwf() {\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\treturn document.getElementById( FBAS.swfObjectID );\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\tupdateSwfSession: function( session, extendedPermissions ) {\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\tswf = FBAS.getSwf();\n\t\t\t\t\t\t\t\textendedPermissions = ( extendedPermissions == null ) ? \'\' : extendedPermissions;\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\tif( session == null ) {\n\t\t\t\t\t\t\t\t\tswf.sessionChange( null );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tswf.sessionChange( FB.JSON.stringify( session ), FB.JSON.stringify( extendedPermissions.split( \',\' ) ) );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t]]>\n\t\t\t</script>");