diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/Action.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/Action.java index ee94b7834..3aad24553 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/Action.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/Action.java @@ -392,7 +392,7 @@ public abstract class Action implements GraphSourceItem { return new ByteArrayRange(bytes); } - public static void setConstantPools(ASMSource src, List> constantPools) { + public static void setConstantPools(ASMSource src, List> constantPools, boolean tryInline) throws ConstantPoolTooBigException { try { ActionList actions = src.getActions(); int poolIdx = 0; @@ -400,6 +400,24 @@ public abstract class Action implements GraphSourceItem { if (action instanceof ActionConstantPool) { ActionConstantPool cPool = (ActionConstantPool) action; List constantPool = constantPools.get(poolIdx); + + int size = ActionConstantPool.calculateSize(constantPool); + if (size > 0xffff && tryInline) { + for (int i = 0; i < constantPool.size(); i++) { + int refCount = actions.getConstantPoolIndexReferenceCount(i); + if (refCount == 1) { + actions.inlineConstantPoolString(i, constantPool.get(i)); + constantPool.set(i, ""); + } + } + + size = ActionConstantPool.calculateSize(constantPool); + } + + if (size > 0xffff) { + throw new ConstantPoolTooBigException(poolIdx, size); + } + cPool.constantPool = constantPool; poolIdx++; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ActionList.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ActionList.java index 882cf7ed4..7cc758444 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ActionList.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ActionList.java @@ -21,6 +21,8 @@ import com.jpexs.decompiler.flash.action.special.ActionNop; import com.jpexs.decompiler.flash.action.special.ActionStore; import com.jpexs.decompiler.flash.action.swf4.ActionIf; import com.jpexs.decompiler.flash.action.swf4.ActionJump; +import com.jpexs.decompiler.flash.action.swf4.ActionPush; +import com.jpexs.decompiler.flash.action.swf4.ConstantIndex; import com.jpexs.decompiler.flash.configuration.Configuration; import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; import com.jpexs.decompiler.flash.helpers.FileTextWriter; @@ -143,6 +145,42 @@ public class ActionList extends ArrayList { }; } + public int getConstantPoolIndexReferenceCount(int index) { + int count = 0; + for (Action action : this) { + if (action instanceof ActionPush) { + ActionPush push = (ActionPush) action; + for (Object value : push.values) { + if (value instanceof ConstantIndex) { + ConstantIndex constantIndex = (ConstantIndex) value; + if (constantIndex.index == index) { + count++; + } + } + } + } + } + + return count; + } + + public void inlineConstantPoolString(int index, String str) { + for (Action action : this) { + if (action instanceof ActionPush) { + ActionPush push = (ActionPush) action; + for (int i = 0; i < push.values.size(); i++) { + Object value = push.values.get(i); + if (value instanceof ConstantIndex) { + ConstantIndex constantIndex = (ConstantIndex) value; + if (constantIndex.index == index) { + push.values.set(i, str); + } + } + } + } + } + } + public void removeNops() { for (int i = 0; i < size(); i++) { if (get(i) instanceof ActionNop) { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ConstantPoolTooBigException.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ConstantPoolTooBigException.java new file mode 100644 index 000000000..5d5fa5bc2 --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ConstantPoolTooBigException.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.action; + +/** + * + * @author JPEXS + */ +public class ConstantPoolTooBigException extends Exception { + + public int index; + + public int size; + + public ConstantPoolTooBigException(int index, int size) { + super("Constant pool too big. index=" + index + ", size=" + size); + this.index = index; + this.size = size; + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/AS2ScriptImporter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/AS2ScriptImporter.java index 9226cb348..a08e10c54 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/AS2ScriptImporter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/AS2ScriptImporter.java @@ -16,6 +16,7 @@ */ package com.jpexs.decompiler.flash.importers; +import com.jpexs.decompiler.flash.action.ConstantPoolTooBigException; import com.jpexs.decompiler.flash.action.parser.ActionParseException; import com.jpexs.decompiler.flash.action.parser.pcode.ASMParser; import com.jpexs.decompiler.flash.action.parser.script.ActionScript2Parser; @@ -116,7 +117,11 @@ public class AS2ScriptImporter { if (new File(fileName).exists()) { String txt = Helper.readTextFile(fileName); - asm.setConstantPools(Helper.getConstantPoolsFromText(txt)); + try { + asm.setConstantPools(Helper.getConstantPoolsFromText(txt)); + } catch (ConstantPoolTooBigException ex) { + logger.log(Level.SEVERE, null, ex); + } asm.setModified(); importCount++; } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineButtonTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineButtonTag.java index 8cc5afeb5..82750f296 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineButtonTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineButtonTag.java @@ -23,6 +23,7 @@ import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.action.Action; import com.jpexs.decompiler.flash.action.ActionList; import com.jpexs.decompiler.flash.action.ActionListReader; +import com.jpexs.decompiler.flash.action.ConstantPoolTooBigException; import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.flash.tags.base.ASMSource; @@ -212,8 +213,8 @@ public class DefineButtonTag extends ButtonTag implements ASMSource { } @Override - public void setConstantPools(List> constantPools) { - Action.setConstantPools(this, constantPools); + public void setConstantPools(List> constantPools) throws ConstantPoolTooBigException { + Action.setConstantPools(this, constantPools, false); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DoActionTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DoActionTag.java index 20499336a..e262e1b57 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DoActionTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DoActionTag.java @@ -23,6 +23,7 @@ import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.action.Action; import com.jpexs.decompiler.flash.action.ActionList; import com.jpexs.decompiler.flash.action.ActionListReader; +import com.jpexs.decompiler.flash.action.ConstantPoolTooBigException; import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.flash.tags.base.ASMSource; @@ -165,8 +166,8 @@ public class DoActionTag extends Tag implements ASMSource { } @Override - public void setConstantPools(List> constantPools) { - Action.setConstantPools(this, constantPools); + public void setConstantPools(List> constantPools) throws ConstantPoolTooBigException { + Action.setConstantPools(this, constantPools, false); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DoInitActionTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DoInitActionTag.java index 53c4bafe9..8a8b7d8ea 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DoInitActionTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DoInitActionTag.java @@ -23,6 +23,7 @@ import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.action.Action; import com.jpexs.decompiler.flash.action.ActionList; import com.jpexs.decompiler.flash.action.ActionListReader; +import com.jpexs.decompiler.flash.action.ConstantPoolTooBigException; import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.flash.tags.base.ASMSource; @@ -163,8 +164,8 @@ public class DoInitActionTag extends Tag implements CharacterIdTag, ASMSource { } @Override - public void setConstantPools(List> constantPools) { - Action.setConstantPools(this, constantPools); + public void setConstantPools(List> constantPools) throws ConstantPoolTooBigException { + Action.setConstantPools(this, constantPools, false); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/ASMSource.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/ASMSource.java index 675b0462f..e4a81aa90 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/ASMSource.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/ASMSource.java @@ -19,6 +19,7 @@ package com.jpexs.decompiler.flash.tags.base; import com.jpexs.decompiler.flash.DisassemblyListener; import com.jpexs.decompiler.flash.action.Action; import com.jpexs.decompiler.flash.action.ActionList; +import com.jpexs.decompiler.flash.action.ConstantPoolTooBigException; import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.flash.tags.Tag; @@ -70,7 +71,7 @@ public interface ASMSource extends Exportable { public void setActionBytes(byte[] actionBytes); - public void setConstantPools(List> constantPools); + public void setConstantPools(List> constantPools) throws ConstantPoolTooBigException; public GraphTextWriter getActionBytesAsHex(GraphTextWriter writer); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/BUTTONCONDACTION.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/BUTTONCONDACTION.java index f31ccfd27..97b9af475 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/BUTTONCONDACTION.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/BUTTONCONDACTION.java @@ -22,6 +22,7 @@ import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.action.Action; import com.jpexs.decompiler.flash.action.ActionList; import com.jpexs.decompiler.flash.action.ActionListReader; +import com.jpexs.decompiler.flash.action.ConstantPoolTooBigException; import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.flash.tags.Tag; @@ -240,8 +241,8 @@ public class BUTTONCONDACTION implements ASMSource, Serializable { } @Override - public void setConstantPools(List> constantPools) { - Action.setConstantPools(this, constantPools); + public void setConstantPools(List> constantPools) throws ConstantPoolTooBigException { + Action.setConstantPools(this, constantPools, false); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/CLIPACTIONRECORD.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/CLIPACTIONRECORD.java index a58f5e5c1..4c486f759 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/CLIPACTIONRECORD.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/CLIPACTIONRECORD.java @@ -22,6 +22,7 @@ import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.action.Action; import com.jpexs.decompiler.flash.action.ActionList; import com.jpexs.decompiler.flash.action.ActionListReader; +import com.jpexs.decompiler.flash.action.ConstantPoolTooBigException; import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.flash.tags.Tag; @@ -226,8 +227,8 @@ public class CLIPACTIONRECORD implements ASMSource, Serializable { } @Override - public void setConstantPools(List> constantPools) { - Action.setConstantPools(this, constantPools); + public void setConstantPools(List> constantPools) throws ConstantPoolTooBigException { + Action.setConstantPools(this, constantPools, false); } @Override diff --git a/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java b/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java index 511e1e50f..ea6ea73e1 100644 --- a/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java @@ -22,6 +22,7 @@ import com.jpexs.decompiler.flash.action.Action; import com.jpexs.decompiler.flash.action.ActionGraph; import com.jpexs.decompiler.flash.action.ActionList; import com.jpexs.decompiler.flash.action.CachedScript; +import com.jpexs.decompiler.flash.action.ConstantPoolTooBigException; import com.jpexs.decompiler.flash.action.parser.ActionParseException; import com.jpexs.decompiler.flash.action.parser.pcode.ASMParser; import com.jpexs.decompiler.flash.action.parser.script.ActionScript2Parser; @@ -30,7 +31,6 @@ import com.jpexs.decompiler.flash.action.parser.script.ParsedSymbol; import com.jpexs.decompiler.flash.action.parser.script.SymbolType; import com.jpexs.decompiler.flash.action.swf4.ActionPush; import com.jpexs.decompiler.flash.action.swf4.ConstantIndex; -import com.jpexs.decompiler.flash.action.swf5.ActionConstantPool; import com.jpexs.decompiler.flash.configuration.Configuration; import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; import com.jpexs.decompiler.flash.gui.AppStrings; @@ -788,15 +788,11 @@ public class ActionPanel extends JPanel implements SearchListener> constantPools = Helper.getConstantPoolsFromText(text); - for (int i = 0; i < constantPools.size(); i++) { - List constantPool = constantPools.get(i); - int size = ActionConstantPool.calculateSize(constantPool); - if (size > 0xffff) { - View.showMessageDialog(this, AppStrings.translate("error.constantPoolTooBig").replace("%index%", Integer.toString(i)).replace("%size%", Integer.toString(size)), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE); - } + try { + Action.setConstantPools(src, constantPools, true); + } catch (ConstantPoolTooBigException ex) { + View.showMessageDialog(this, AppStrings.translate("error.constantPoolTooBig").replace("%index%", Integer.toString(ex.index)).replace("%size%", Integer.toString(ex.size)), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE); } - - src.setConstantPools(constantPools); } else { src.setActions(ASMParser.parse(0, true, text, src.getSwf().version, false)); }