From 2df49d32a71818227e80a8628688906f2ede8a6a Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Tue, 2 Sep 2014 20:56:03 +0400 Subject: java-decompiler: fixes and cleanups - unified attribute loading code - common methods for checking member flags - verifying skip() - correct resource closing - typos --- .../java/decompiler/struct/lazy/LazyLoader.java | 155 ++++++++++----------- 1 file changed, 72 insertions(+), 83 deletions(-) (limited to 'src/org/jetbrains/java/decompiler/struct/lazy') diff --git a/src/org/jetbrains/java/decompiler/struct/lazy/LazyLoader.java b/src/org/jetbrains/java/decompiler/struct/lazy/LazyLoader.java index 8673c21..f610900 100644 --- a/src/org/jetbrains/java/decompiler/struct/lazy/LazyLoader.java +++ b/src/org/jetbrains/java/decompiler/struct/lazy/LazyLoader.java @@ -24,11 +24,11 @@ import org.jetbrains.java.decompiler.util.DataInputFullStream; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; +import java.util.Map; public class LazyLoader { - private HashMap mapClassLinks = new HashMap(); - + private Map mapClassLinks = new HashMap(); private IBytecodeProvider provider; public LazyLoader(IBytecodeProvider provider) { @@ -47,98 +47,88 @@ public class LazyLoader { return mapClassLinks.get(classname); } - public ConstantPool loadPool(String classname) { - try { - DataInputFullStream in = getClassStream(classname); - if (in == null) { - return null; - } - - in.skip(8); + if (in == null) return null; - return new ConstantPool(in); + try { + in.discard(8); + return new ConstantPool(in); + } + finally { + in.close(); + } } catch (IOException ex) { throw new RuntimeException(ex); } } - public byte[] loadBytecode(StructMethod mt, int code_fulllength) { + public byte[] loadBytecode(StructMethod mt, int codeFullLength) { + String className = mt.getClassStruct().qualifiedName; try { + DataInputFullStream in = getClassStream(className); + if (in == null) return null; - DataInputFullStream in = getClassStream(mt.getClassStruct().qualifiedName); - if (in == null) { - return null; - } - - byte[] res = null; - - in.skip(8); - - ConstantPool pool = mt.getClassStruct().getPool(); - if (pool == null) { - pool = new ConstantPool(in); - } - else { - ConstantPool.skipPool(in); - } + try { + in.discard(8); - in.skip(2); - int this_class = in.readUnsignedShort(); - in.skip(2); - - // interfaces - in.skip(in.readUnsignedShort() * 2); - - // fields - int size = in.readUnsignedShort(); - for (int i = 0; i < size; i++) { - in.skip(6); - skipAttributes(in); - } - - // methods - size = in.readUnsignedShort(); - for (int i = 0; i < size; i++) { - in.skip(2); + ConstantPool pool = mt.getClassStruct().getPool(); + if (pool == null) { + pool = new ConstantPool(in); + } + else { + ConstantPool.skipPool(in); + } - int name_index = in.readUnsignedShort(); - int descriptor_index = in.readUnsignedShort(); + in.discard(6); - String[] elem_arr = pool.getClassElement(ConstantPool.METHOD, this_class, name_index, descriptor_index); - String name = elem_arr[0]; + // interfaces + in.discard(in.readUnsignedShort() * 2); - if (mt.getName().equals(name)) { - String descriptor = elem_arr[1]; - if (mt.getDescriptor().equals(descriptor)) { + // fields + int size = in.readUnsignedShort(); + for (int i = 0; i < size; i++) { + in.discard(6); + skipAttributes(in); + } - int len = in.readUnsignedShort(); - for (int j = 0; j < len; j++) { + // methods + size = in.readUnsignedShort(); + for (int i = 0; i < size; i++) { + in.discard(2); - int attr_nameindex = in.readUnsignedShort(); - String attrname = pool.getPrimitiveConstant(attr_nameindex).getString(); + int nameIndex = in.readUnsignedShort(); + int descriptorIndex = in.readUnsignedShort(); - if (StructGeneralAttribute.ATTRIBUTE_CODE.equals(attrname)) { - in.skip(12); + String[] values = pool.getClassElement(ConstantPool.METHOD, className, nameIndex, descriptorIndex); + if (!mt.getName().equals(values[0]) || !mt.getDescriptor().equals(values[1])) { + skipAttributes(in); + continue; + } - res = new byte[code_fulllength]; - in.readFull(res); - return res; - } - else { - in.skip(in.readInt()); - } + int attrSize = in.readUnsignedShort(); + for (int j = 0; j < attrSize; j++) { + int attrNameIndex = in.readUnsignedShort(); + String attrName = pool.getPrimitiveConstant(attrNameIndex).getString(); + if (!StructGeneralAttribute.ATTRIBUTE_CODE.equals(attrName)) { + in.discard(in.readInt()); + continue; } - return null; + in.discard(12); + byte[] code = new byte[codeFullLength]; + in.readFull(code); + return code; } - } - skipAttributes(in); + break; + } + } + finally { + in.close(); } return null; @@ -148,39 +138,38 @@ public class LazyLoader { } } - public DataInputFullStream getClassStream(String externPath, String internPath) throws IOException { - InputStream instream = provider.getBytecodeStream(externPath, internPath); - return instream == null ? null : new DataInputFullStream(instream); + @SuppressWarnings("IOResourceOpenedButNotSafelyClosed") + public DataInputFullStream getClassStream(String externalPath, String internalPath) throws IOException { + InputStream stream = provider.getBytecodeStream(externalPath, internalPath); + return stream == null ? null : new DataInputFullStream(stream); } public DataInputFullStream getClassStream(String qualifiedClassName) throws IOException { Link link = mapClassLinks.get(qualifiedClassName); - return link == null ? null : getClassStream(link.externPath, link.internPath); + return link == null ? null : getClassStream(link.externalPath, link.internalPath); } - private static void skipAttributes(DataInputFullStream in) throws IOException { - + public static void skipAttributes(DataInputFullStream in) throws IOException { int length = in.readUnsignedShort(); for (int i = 0; i < length; i++) { - in.skip(2); - in.skip(in.readInt()); + in.discard(2); + in.discard(in.readInt()); } } public static class Link { - public static final int CLASS = 1; public static final int ENTRY = 2; public int type; - public String externPath; - public String internPath; + public String externalPath; + public String internalPath; - public Link(int type, String externPath, String internPath) { + public Link(int type, String externalPath, String internalPath) { this.type = type; - this.externPath = externPath; - this.internPath = internPath; + this.externalPath = externalPath; + this.internalPath = internalPath; } } } -- cgit v1.2.3