Return-Path: X-Original-To: apmail-flex-commits-archive@www.apache.org Delivered-To: apmail-flex-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 743C21066F for ; Fri, 11 Oct 2013 06:46:16 +0000 (UTC) Received: (qmail 11815 invoked by uid 500); 11 Oct 2013 06:46:05 -0000 Delivered-To: apmail-flex-commits-archive@flex.apache.org Received: (qmail 11716 invoked by uid 500); 11 Oct 2013 06:45:59 -0000 Mailing-List: contact commits-help@flex.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@flex.apache.org Delivered-To: mailing list commits@flex.apache.org Received: (qmail 11452 invoked by uid 99); 11 Oct 2013 06:45:55 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 11 Oct 2013 06:45:55 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id 7F468915128; Fri, 11 Oct 2013 06:45:55 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: aharui@apache.org To: commits@flex.apache.org Date: Fri, 11 Oct 2013 06:46:01 -0000 Message-Id: <343d6e2c45414849aeccd7265bd21221@git.apache.org> In-Reply-To: References: X-Mailer: ASF-Git Admin Mailer Subject: [07/11] git commit: [flex-sdk] [refs/heads/release4.11.0] - add more details to abc output add more details to abc output Project: http://git-wip-us.apache.org/repos/asf/flex-sdk/repo Commit: http://git-wip-us.apache.org/repos/asf/flex-sdk/commit/23d9fda8 Tree: http://git-wip-us.apache.org/repos/asf/flex-sdk/tree/23d9fda8 Diff: http://git-wip-us.apache.org/repos/asf/flex-sdk/diff/23d9fda8 Branch: refs/heads/release4.11.0 Commit: 23d9fda8b21fef66527c52fd5813de9057f06976 Parents: 1a4df28 Author: Alex Harui Authored: Wed Oct 9 20:39:20 2013 -0700 Committer: Alex Harui Committed: Thu Oct 10 23:18:38 2013 -0700 ---------------------------------------------------------------------- .../src/java/flash/swf/tools/AbcPrinter.java | 141 +++++++++++++++++-- 1 file changed, 129 insertions(+), 12 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/23d9fda8/modules/swfutils/src/java/flash/swf/tools/AbcPrinter.java ---------------------------------------------------------------------- diff --git a/modules/swfutils/src/java/flash/swf/tools/AbcPrinter.java b/modules/swfutils/src/java/flash/swf/tools/AbcPrinter.java index 8baafa0..4fe4198 100644 --- a/modules/swfutils/src/java/flash/swf/tools/AbcPrinter.java +++ b/modules/swfutils/src/java/flash/swf/tools/AbcPrinter.java @@ -29,11 +29,13 @@ import java.util.HashMap; public class AbcPrinter { private byte[] abc; + private int abcEnd; private PrintWriter out; private boolean showOffset; private boolean showByteCode; private int indent; private int offset = 0; + private long numMetadata; private int[] intConstants; private long[] uintConstants; @@ -42,14 +44,18 @@ public class AbcPrinter private String[] namespaceConstants; private String[][] namespaceSetConstants; private MultiName[] multiNameConstants; + private String kAbcCorrupt = "Verify Error: ABC Corrupt"; + private MethodInfo[] methods; private String[] instanceNames; + private String[] Names; private String indentString; public AbcPrinter(byte[] abc, PrintWriter out, boolean showOffset, int indent, boolean showByteCode) { this.abc = abc; + this.abcEnd = abc.length; this.out = out; this.showOffset = showOffset; this.showByteCode = showByteCode; @@ -583,6 +589,8 @@ public class AbcPrinter long n = readU32(); printOffset(); out.println(n + " Integer Constant Pool Entries"); + if (n > abcEnd - offset) + out.println(kAbcCorrupt); intConstants = new int[(n > 0) ? (int)n : 1]; intConstants[0] = 0; for (int i = 1; i < n; i++) @@ -599,6 +607,8 @@ public class AbcPrinter long n = readU32(); printOffset(); out.println(n + " Unsigned Integer Constant Pool Entries"); + if (n > abcEnd - offset) + out.println(kAbcCorrupt); uintConstants = new long[(n > 0) ? (int)n : 1]; uintConstants[0] = 0; for (int i = 1; i < n; i++) @@ -615,6 +625,8 @@ public class AbcPrinter long n = readU32(); printOffset(); out.println(n + " Floating Point Constant Pool Entries"); + if (n > abcEnd - offset) + out.println(kAbcCorrupt); if (n > 0) offset += (n - 1) * 8; } @@ -624,13 +636,21 @@ public class AbcPrinter long n = readU32(); printOffset(); out.println(n + " String Constant Pool Entries"); + if (n > abcEnd - offset) + out.println(kAbcCorrupt); stringConstants = new String[(n > 0) ? (int)n : 1]; stringConstants[0] = ""; for (int i = 1; i < n; i++) { printOffset(); - String s = readUTFBytes(readU32()); + long strlen = readU32(); + if (((strlen & 0xc0000000) != 0) || abcEnd <= offset + strlen) + out.println(kAbcCorrupt + "strlen"); + String s = readUTFBytes(strlen); stringConstants[i] = s; + s = s.replace("\r\n", "\\r\\n"); + s = s.replace("\n", "\\n"); + s = s.replace("\r", "\\r"); out.println(" " + s); } } @@ -640,6 +660,8 @@ public class AbcPrinter long n = readU32(); printOffset(); out.println(n + " Namespace Constant Pool Entries"); + if (n > abcEnd - offset) + out.println(kAbcCorrupt); namespaceConstants = new String[(n > 0) ? (int)n : 1]; namespaceConstants[0] = "public"; for (int i = 1; i < n; i++) @@ -666,11 +688,15 @@ public class AbcPrinter long n = readU32(); printOffset(); out.println(n + " Namespace Set Constant Pool Entries"); + if (n > abcEnd - offset) + out.println(kAbcCorrupt); namespaceSetConstants = new String[(n > 0) ? (int)n : 1][]; namespaceSetConstants[0] = new String[0]; for (int i = 1; i < n; i++) { long val = readU32(); + if (val > abcEnd - offset) + out.println(kAbcCorrupt); String[] nsset = new String[(int)val]; namespaceSetConstants[i] = nsset; for (int j = 0; j < val; j++) @@ -685,6 +711,8 @@ public class AbcPrinter long n = readU32(); printOffset(); out.println(n + " MultiName Constant Pool Entries"); + if (n > abcEnd - offset) + out.println(kAbcCorrupt); multiNameConstants = new MultiName[(n > 0) ? (int)n : 1]; multiNameConstants[0] = new MultiName(); for (int i = 1; i < n; i++) @@ -723,6 +751,8 @@ public class AbcPrinter int nameIndex = (int)readU32(); MultiName mn = multiNameConstants[nameIndex]; int count = (int)readU32(); + if (count != 1) + out.println(kAbcCorrupt + "more than one typename"); MultiName types[] = new MultiName[count]; for (int t = 0; t < count; t++) { @@ -734,6 +764,27 @@ public class AbcPrinter } out.println(multiNameConstants[i]); } + // verify vectors (yes, the AVM does this) + for (int i = 1; i < n; i++) + { + MultiName mn = multiNameConstants[i]; + if (mn.kind != 0x1D) + continue; + MultiName typeName = mn.typeName; + if (typeName.kind == 0x1D) + out.println(kAbcCorrupt + "typename is also a typename"); + HashMap seenMap = new HashMap(); + MultiName type = mn.types[0]; + while (type != null) + { + if (type.kind != 0x1D) + break; + seenMap.put(type, type.toString()); + type = type.types[0]; + if (seenMap.containsKey(type)) + out.println(kAbcCorrupt + "type cycle"); + } + } } void printMethods() @@ -741,6 +792,8 @@ public class AbcPrinter long n = readU32(); printOffset(); out.println(n + " Method Entries"); + if (n > abcEnd - offset) + out.println(kAbcCorrupt); methods = new MethodInfo[(int)n]; for (int i = 0; i < n; i++) { @@ -772,6 +825,8 @@ public class AbcPrinter m.optionIndex[k] = (int)readU32(); m.optionKinds[k] = abc[offset++]; } + if (m.optionCount == 0 || m.optionCount > m.paramCount) + out.println(kAbcCorrupt); } if ((m.flags & 0x80) == 0x80) { @@ -807,6 +862,9 @@ public class AbcPrinter long n = readU32(); printOffset(); out.println(n + " Metadata Entries"); + if (n > abcEnd - offset) + out.println(kAbcCorrupt); + numMetadata = n; for (int i = 0; i < n; i++) { int start = offset; @@ -837,6 +895,8 @@ public class AbcPrinter long n = readU32(); printOffset(); out.println(n + " Instance Entries"); + if (n > abcEnd - offset) + out.println(kAbcCorrupt); instanceNames = new String[(int)n]; for (int i = 0; i < n; i++) { @@ -849,6 +909,8 @@ public class AbcPrinter if ((b & 0x8) == 0x8) readU32(); // eat protected namespace long val = readU32(); + if (val >= 0x10000000) + out.println(kAbcCorrupt); String s = ""; for (int j = 0; j < val; j++) { @@ -866,7 +928,7 @@ public class AbcPrinter out.print(hex(abc[(int)x]) + " "); } } - out.print(name + " "); + out.print("Instance Traits for: " + name + " "); if (base.length() > 0) out.print("extends " + base + " "); if (s.length() > 0) @@ -876,6 +938,8 @@ public class AbcPrinter int numTraits = (int)readU32(); // number of traits printOffset(); out.println(numTraits + " Traits Entries"); + if (numTraits > abcEnd - offset) + out.println(kAbcCorrupt); for (int j = 0; j < numTraits; j++) { printOffset(); @@ -897,20 +961,30 @@ public class AbcPrinter readU32(); // id readU32(); // value; break; - default: + case 0x01: + case 0x02: + case 0x03: + case 0x05: readU32(); // id mi = methods[(int)readU32()]; // method mi.name = s; mi.className = name; mi.kind = kind; + if (mi.sawTraits) + out.println(kAbcCorrupt + "sawTraits"); + mi.sawTraits = true; break; + default: + out.println(kAbcCorrupt + "Unknown Trait"); } if ((b >> 4 & 0x4) == 0x4) { val = readU32(); // metadata count for (int k = 0; k < val; k++) { - readU32(); // metadata + long index = readU32(); // metadata + if (index >= numMetadata) + out.println(kAbcCorrupt); } } if (showByteCode) @@ -942,7 +1016,7 @@ public class AbcPrinter out.print(hex(abc[(int)x]) + " "); } } - out.print(name + " "); + out.print("Class Traits for: " + name + " "); if (base.length() > 0) out.print("extends " + base + " "); out.println(""); @@ -950,6 +1024,8 @@ public class AbcPrinter int numTraits = (int)readU32(); // number of traits printOffset(); out.println(numTraits + " Traits Entries"); + if (numTraits > abcEnd - offset) + out.println(kAbcCorrupt); for (int j = 0; j < numTraits; j++) { printOffset(); @@ -971,20 +1047,30 @@ public class AbcPrinter readU32(); // id readU32(); // value; break; - default: + case 0x01: + case 0x02: + case 0x03: + case 0x05: readU32(); // id mi = methods[(int)readU32()]; // method mi.name = s; mi.className = name; mi.kind = kind; + if (mi.sawTraits) + out.println(kAbcCorrupt + "sawTraits"); + mi.sawTraits = true; break; + default: + out.println(kAbcCorrupt); } if ((b >> 4 & 0x4) == 0x4) { int val = (int)readU32(); // metadata count for (int k = 0; k < val; k++) { - readU32(); // metadata + long index = readU32(); // metadata + if (index > numMetadata) + out.println(kAbcCorrupt); } } if (showByteCode) @@ -1004,6 +1090,8 @@ public class AbcPrinter long n = readU32(); printOffset(); out.println(n + " Script Entries"); + if (n > abcEnd - offset) + out.println(kAbcCorrupt); for (int i = 0; i < n; i++) { int start = offset; @@ -1026,6 +1114,8 @@ public class AbcPrinter int numTraits = (int)readU32(); // number of traits printOffset(); out.println(numTraits + " Traits Entries"); + if (numTraits > abcEnd - offset) + out.println(kAbcCorrupt); for (int j = 0; j < numTraits; j++) { printOffset(); @@ -1037,6 +1127,10 @@ public class AbcPrinter { case 0x00: // slot case 0x06: // const + if (kind == 0x00) + s = "slot trait: " + s; + else + s = "const trait: " + s; readU32(); // id readU32(); // type int index = (int)readU32(); // index; @@ -1044,23 +1138,34 @@ public class AbcPrinter offset++; // kind break; case 0x04: // class + s = "class trait: " + s; readU32(); // id - readU32(); // value; + s += " " + instanceNames[(int)readU32()]; // value; break; - default: + case 0x01: + case 0x02: + case 0x03: + case 0x05: readU32(); // id mi = methods[(int)readU32()]; // method mi.name = s; mi.className = name; mi.kind = kind; + if (mi.sawTraits) + out.println(kAbcCorrupt + "sawTraits"); + mi.sawTraits = true; break; + default: + out.println(kAbcCorrupt + "Unknown trait"); } if ((b >> 4 & 0x4) == 0x4) { int val = (int)readU32(); // metadata count for (int k = 0; k < val; k++) { - readU32(); // metadata + long index = readU32(); // metadata + if (index > numMetadata) + out.println(kAbcCorrupt); } } if (showByteCode) @@ -1103,6 +1208,8 @@ public class AbcPrinter out.print(" "); } } + if (abcEnd < codeLength + offset) + out.println(kAbcCorrupt); MethodInfo mi = methods[methodIndex]; out.print(traitKinds[mi.kind] + " "); out.print(mi.className + "::" + mi.name + "("); @@ -1308,6 +1415,8 @@ public class AbcPrinter int numTraits = (int)readU32(); // number of traits printOffset(); out.println(numTraits + " Traits Entries"); + if (numTraits > abcEnd - offset) + out.println(kAbcCorrupt); for (int j = 0; j < numTraits; j++) { printOffset(); @@ -1329,17 +1438,24 @@ public class AbcPrinter readU32(); // id readU32(); // value; break; - default: + case 0x01: + case 0x02: + case 0x03: + case 0x05: readU32(); // id readU32(); // method break; + default: + out.println(kAbcCorrupt); } if ((b >> 4 & 0x4) == 0x4) { int val = (int)readU32(); // metadata count for (int k = 0; k < val; k++) { - readU32(); // metadata + long index = readU32(); // metadata + if (index > numMetadata) + out.println(kAbcCorrupt); } } if (showByteCode) @@ -1447,6 +1563,7 @@ public class AbcPrinter int[] optionIndex; int[] paramNames; String className; + boolean sawTraits; } class LabelMgr