From 905ad2830489d38ee9ec67fe5579148d95f6c2da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Sat, 31 May 2025 20:50:51 +0200 Subject: [PATCH] Fixed: AS3 incorrect parsing of divide operator vs regexp --- libsrc/ffdec_lib/lexers/actionscript3_script.flex | 12 +++++------- .../avm2/parser/script/ActionScript3Parser.java | 13 ++++++++----- .../parser/script/ActionScript3SimpleParser.java | 14 ++++++++------ .../abc/avm2/parser/script/ActionScriptLexer.java | 12 +++++------- 4 files changed, 26 insertions(+), 25 deletions(-) diff --git a/libsrc/ffdec_lib/lexers/actionscript3_script.flex b/libsrc/ffdec_lib/lexers/actionscript3_script.flex index 55fb7100e..74e19b5c2 100644 --- a/libsrc/ffdec_lib/lexers/actionscript3_script.flex +++ b/libsrc/ffdec_lib/lexers/actionscript3_script.flex @@ -44,6 +44,8 @@ import com.jpexs.decompiler.flash.abc.types.Float4; private boolean enableWhiteSpace = false; + private int yyStartOffset = 0; + private final Pattern float4Pattern = Pattern.compile("float4.*\\([\r\n \t\f]*(?[^\r\n \t\f]+)[\r\n \t\f]*,[\r\n \t\f]*(?[^\r\n \t\f]+)[\r\n \t\f]*,[\r\n \t\f]*(?[^\r\n \t\f]+)[\r\n \t\f]*,[\r\n \t\f]*(?[^\r\n \t\f]+)[\r\n \t\f]*\\)", Pattern.MULTILINE); public ActionScriptLexer(String sourceCode){ @@ -51,10 +53,11 @@ import com.jpexs.decompiler.flash.abc.types.Float4; this.sourceCode = sourceCode; } - public void yypushbackstr(String s, int state) + public void yypushbackstr(String s, int state, int skipNumChars) { int numLines = count(s, "\n"); int newYyline = yyline - numLines; + yyStartOffset = yyStartOffset + skipNumChars + yychar; sourceCode = s + sourceCode.substring(yychar + yylength()); yyreset(new StringReader(sourceCode)); yybegin(state); @@ -72,11 +75,6 @@ import com.jpexs.decompiler.flash.abc.types.Float4; yybegin(state); } - public void yypushbackstr(String s) - { - yypushbackstr(s, YYINITIAL); - } - StringBuilder string = new StringBuilder(); private static String xmlTagName = ""; @@ -84,7 +82,7 @@ import com.jpexs.decompiler.flash.abc.types.Float4; private int startPos = -1; public int yychar() { - return yychar; + return yyStartOffset + yychar; } private Stack pushedBack = new Stack<>(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3Parser.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3Parser.java index 983d0b201..d8e1c0c5f 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3Parser.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3Parser.java @@ -2140,17 +2140,18 @@ public class ActionScript3Parser { */ private void xmlToLowerThanFix(ParsedSymbol symb) { if (symb.isType(SymbolType.XML_STARTVARTAG_BEGIN, SymbolType.XML_STARTTAG_BEGIN)) { - lexer.yypushbackstr(symb.value.toString().substring(1)); //parse again as LOWER_THAN String pb = symb.value.toString().substring(1); symb.type = SymbolType.LOWER_THAN; symb.group = SymbolGroup.OPERATOR; symb.value = "<"; + int pos = 1; if (pb.charAt(0) == '=') { symb.type = SymbolType.LOWER_EQUAL; symb.value = "<="; pb = pb.substring(1); + pos++; } - lexer.yypushbackstr(pb); //parse again as LOWER_THAN + lexer.yypushbackstr(pb, ActionScriptLexer.YYINITIAL, pos); //parse again as LOWER_THAN } } @@ -2160,12 +2161,14 @@ public class ActionScript3Parser { symb.type = SymbolType.DIVIDE; symb.group = SymbolGroup.OPERATOR; symb.value = "/"; + int pos = 1; if (pb.charAt(0) == '=') { symb.type = SymbolType.ASSIGN_DIVIDE; symb.value = "/="; pb = pb.substring(1); + pos++; } - lexer.yypushbackstr(pb); //parse again as DIVIDE + lexer.yypushbackstr(pb, ActionScriptLexer.YYINITIAL, pos); //parse again as DIVIDE } } @@ -2619,7 +2622,7 @@ public class ActionScript3Parser { case FLOAT4: if (!abc.hasFloat4Support()) { //parse again as method call - lexer.yypushbackstr(lexer.yytext().substring("float4".length())); + lexer.yypushbackstr(lexer.yytext().substring("float4".length()), ActionScriptLexer.YYINITIAL, "float4".length()); lexer.pushback(new ParsedSymbol(-1, SymbolGroup.IDENTIFIER, SymbolType.IDENTIFIER, "float4")); ret = name(allOpenedNamespaces, thisType, pkg, needsActivation, false, openedNamespaces, registerVars, inFunction, inMethod, variables, importedClasses, abc); } else { @@ -2663,7 +2666,7 @@ public class ActionScript3Parser { case NEW: s = lex(); if (s.type == SymbolType.XML_STARTTAG_BEGIN) { - lexer.yypushbackstr(s.value.toString().substring(1), ActionScriptLexer.YYINITIAL); + lexer.yypushbackstr(s.value.toString().substring(1), ActionScriptLexer.YYINITIAL, 1); s = new ParsedSymbol(-1, SymbolGroup.OPERATOR, SymbolType.LOWER_THAN); } if (s.type == SymbolType.FUNCTION) { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3SimpleParser.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3SimpleParser.java index e909b98bf..584fe9239 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3SimpleParser.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3SimpleParser.java @@ -41,7 +41,6 @@ import java.io.IOException; import java.util.AbstractMap; import java.util.ArrayList; import java.util.HashMap; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Stack; @@ -1571,17 +1570,18 @@ public class ActionScript3SimpleParser implements SimpleParser { */ private void xmlToLowerThanFix(ParsedSymbol symb) { if (symb.isType(SymbolType.XML_STARTVARTAG_BEGIN, SymbolType.XML_STARTTAG_BEGIN)) { - lexer.yypushbackstr(symb.value.toString().substring(1)); //parse again as LOWER_THAN String pb = symb.value.toString().substring(1); symb.type = SymbolType.LOWER_THAN; symb.group = SymbolGroup.OPERATOR; symb.value = "<"; + int pos = 1; if (pb.charAt(0) == '=') { symb.type = SymbolType.LOWER_EQUAL; symb.value = "<="; pb = pb.substring(1); + pos++; } - lexer.yypushbackstr(pb); //parse again as LOWER_THAN + lexer.yypushbackstr(pb, ActionScriptLexer.YYINITIAL, pos); //parse again as LOWER_THAN } } @@ -1591,12 +1591,14 @@ public class ActionScript3SimpleParser implements SimpleParser { symb.type = SymbolType.DIVIDE; symb.group = SymbolGroup.OPERATOR; symb.value = "/"; + int pos = 1; if (pb.charAt(0) == '=') { symb.type = SymbolType.ASSIGN_DIVIDE; symb.value = "/="; pb = pb.substring(1); + pos++; } - lexer.yypushbackstr(pb); //parse again as DIVIDE + lexer.yypushbackstr(pb, ActionScriptLexer.YYINITIAL, pos); //parse again as DIVIDE } } @@ -1904,7 +1906,7 @@ public class ActionScript3SimpleParser implements SimpleParser { case FLOAT4: if (!abc.hasFloat4Support()) { //parse again as method call - lexer.yypushbackstr(lexer.yytext().substring("float4".length())); + lexer.yypushbackstr(lexer.yytext().substring("float4".length()), ActionScriptLexer.YYINITIAL, "float4".length()); lexer.pushback(new ParsedSymbol(lexer.yychar() /*???*/, SymbolGroup.IDENTIFIER, SymbolType.IDENTIFIER, "float4")); ret = name(errors, thisType, needsActivation, openedNamespaces, registerVars, inFunction, inMethod, isStatic, variables, importedClasses, abc); } else { @@ -1940,7 +1942,7 @@ public class ActionScript3SimpleParser implements SimpleParser { case NEW: s = lex(); if (s.type == SymbolType.XML_STARTTAG_BEGIN) { - lexer.yypushbackstr(s.value.toString().substring(1), ActionScriptLexer.YYINITIAL); + lexer.yypushbackstr(s.value.toString().substring(1), ActionScriptLexer.YYINITIAL, 1); s = new ParsedSymbol(s.position, SymbolGroup.OPERATOR, SymbolType.LOWER_THAN); } if (s.type == SymbolType.FUNCTION) { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScriptLexer.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScriptLexer.java index 3b5bb0473..a5bf1318a 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScriptLexer.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScriptLexer.java @@ -1059,6 +1059,8 @@ public final class ActionScriptLexer { private boolean enableWhiteSpace = false; + private int yyStartOffset = 0; + private final Pattern float4Pattern = Pattern.compile("float4.*\\([\r\n \t\f]*(?[^\r\n \t\f]+)[\r\n \t\f]*,[\r\n \t\f]*(?[^\r\n \t\f]+)[\r\n \t\f]*,[\r\n \t\f]*(?[^\r\n \t\f]+)[\r\n \t\f]*,[\r\n \t\f]*(?[^\r\n \t\f]+)[\r\n \t\f]*\\)", Pattern.MULTILINE); public ActionScriptLexer(String sourceCode){ @@ -1066,10 +1068,11 @@ public final class ActionScriptLexer { this.sourceCode = sourceCode; } - public void yypushbackstr(String s, int state) + public void yypushbackstr(String s, int state, int skipNumChars) { int numLines = count(s, "\n"); int newYyline = yyline - numLines; + yyStartOffset = yyStartOffset + skipNumChars + yychar; sourceCode = s + sourceCode.substring(yychar + yylength()); yyreset(new StringReader(sourceCode)); yybegin(state); @@ -1087,11 +1090,6 @@ public final class ActionScriptLexer { yybegin(state); } - public void yypushbackstr(String s) - { - yypushbackstr(s, YYINITIAL); - } - StringBuilder string = new StringBuilder(); private static String xmlTagName = ""; @@ -1099,7 +1097,7 @@ public final class ActionScriptLexer { private int startPos = -1; public int yychar() { - return yychar; + return yyStartOffset + yychar; } private Stack pushedBack = new Stack<>();