use of com.taobao.android.dx.cf.iface.ParseException in project atlas by alibaba.
the class ConstantPoolParser method parseUtf8.
/**
* Parses a utf8 constant.
*
* @param at offset to the start of the constant (where the tag byte is)
* @return {@code non-null;} the parsed value
*/
private CstString parseUtf8(int at) {
int length = bytes.getUnsignedShort(at + 1);
// Skip to the data.
at += 3;
ByteArray ubytes = bytes.slice(at, at + length);
try {
return new CstString(ubytes);
} catch (IllegalArgumentException ex) {
// Translate the exception
throw new ParseException(ex);
}
}
use of com.taobao.android.dx.cf.iface.ParseException in project atlas by alibaba.
the class AttributeFactory method parse.
/**
* Parses and makes an attribute based on the bytes at the
* indicated position in the given array. This method figures out
* the name, and then does all the setup to call on to {@link #parse0},
* which does the actual construction.
*
* @param cf {@code non-null;} class file to parse from
* @param context context to parse in; one of the {@code CTX_*}
* constants
* @param offset offset into {@code dcf}'s {@code bytes}
* to start parsing at
* @param observer {@code null-ok;} parse observer to report to, if any
* @return {@code non-null;} an appropriately-constructed {@link Attribute}
*/
public final Attribute parse(DirectClassFile cf, int context, int offset, ParseObserver observer) {
if (cf == null) {
throw new NullPointerException("cf == null");
}
if ((context < 0) || (context >= CTX_COUNT)) {
throw new IllegalArgumentException("bad context");
}
CstString name = null;
try {
ByteArray bytes = cf.getBytes();
ConstantPool pool = cf.getConstantPool();
int nameIdx = bytes.getUnsignedShort(offset);
int length = bytes.getInt(offset + 2);
name = (CstString) pool.get(nameIdx);
if (observer != null) {
observer.parsed(bytes, offset, 2, "name: " + name.toHuman());
observer.parsed(bytes, offset + 2, 4, "length: " + Hex.u4(length));
}
return parse0(cf, context, name.getString(), offset + 6, length, observer);
} catch (ParseException ex) {
ex.addContext("...while parsing " + ((name != null) ? (name.toHuman() + " ") : "") + "attribute at offset " + Hex.u4(offset));
throw ex;
}
}
use of com.taobao.android.dx.cf.iface.ParseException in project atlas by alibaba.
the class DirectClassFile method parse0.
/**
* Does the actual parsing.
*/
private void parse0() {
if (bytes.size() < 10) {
throw new ParseException("severely truncated class file");
}
if (observer != null) {
observer.parsed(bytes, 0, 0, "begin classfile");
observer.parsed(bytes, 0, 4, "magic: " + Hex.u4(getMagic0()));
observer.parsed(bytes, 4, 2, "minor_version: " + Hex.u2(getMinorVersion0()));
observer.parsed(bytes, 6, 2, "major_version: " + Hex.u2(getMajorVersion0()));
}
if (strictParse) {
/* Make sure that this looks like a valid class file with a
* version that we can handle.
*/
if (!isGoodMagic(getMagic0())) {
throw new ParseException("bad class file magic (" + Hex.u4(getMagic0()) + ")");
}
if (!isGoodVersion(getMinorVersion0(), getMajorVersion0())) {
throw new ParseException("unsupported class file version " + getMajorVersion0() + "." + getMinorVersion0());
}
}
ConstantPoolParser cpParser = new ConstantPoolParser(bytes);
cpParser.setObserver(observer);
pool = cpParser.getPool();
pool.setImmutable();
int at = cpParser.getEndOffset();
// u2 access_flags;
int accessFlags = bytes.getUnsignedShort(at);
// u2 this_class;
int cpi = bytes.getUnsignedShort(at + 2);
thisClass = (CstType) pool.get(cpi);
// u2 super_class;
cpi = bytes.getUnsignedShort(at + 4);
superClass = (CstType) pool.get0Ok(cpi);
// u2 interfaces_count
int count = bytes.getUnsignedShort(at + 6);
if (observer != null) {
observer.parsed(bytes, at, 2, "access_flags: " + AccessFlags.classString(accessFlags));
observer.parsed(bytes, at + 2, 2, "this_class: " + thisClass);
observer.parsed(bytes, at + 4, 2, "super_class: " + stringOrNone(superClass));
observer.parsed(bytes, at + 6, 2, "interfaces_count: " + Hex.u2(count));
if (count != 0) {
observer.parsed(bytes, at + 8, 0, "interfaces:");
}
}
at += 8;
interfaces = makeTypeList(at, count);
at += count * 2;
if (strictParse) {
/*
* Make sure that the file/jar path matches the declared
* package/class name.
*/
String thisClassName = thisClass.getClassType().getClassName();
if (!(filePath.endsWith(".class") && filePath.startsWith(thisClassName) && (filePath.length() == (thisClassName.length() + 6)))) {
throw new ParseException("class name (" + thisClassName + ") does not match path (" + filePath + ")");
}
}
/*
* Only set the instance variable accessFlags here, since
* that's what signals a successful parse of the first part of
* the file (through the interfaces list).
*/
this.accessFlags = accessFlags;
FieldListParser flParser = new FieldListParser(this, thisClass, at, attributeFactory);
flParser.setObserver(observer);
fields = flParser.getList();
at = flParser.getEndOffset();
MethodListParser mlParser = new MethodListParser(this, thisClass, at, attributeFactory);
mlParser.setObserver(observer);
methods = mlParser.getList();
at = mlParser.getEndOffset();
AttributeListParser alParser = new AttributeListParser(this, AttributeFactory.CTX_CLASS, at, attributeFactory);
alParser.setObserver(observer);
attributes = alParser.getList();
attributes.setImmutable();
at = alParser.getEndOffset();
if (at != bytes.size()) {
throw new ParseException("extra bytes at end of class file, " + "at offset " + Hex.u4(at));
}
if (observer != null) {
observer.parsed(bytes, at, 0, "end classfile");
}
}
use of com.taobao.android.dx.cf.iface.ParseException in project atlas by alibaba.
the class Main method processClass.
/**
* Processes one classfile.
*
* @param name {@code non-null;} name of the file, clipped such that it
* <i>should</i> correspond to the name of the class it contains
* @param bytes {@code non-null;} contents of the file
* @return whether processing was successful
*/
private boolean processClass(String name, byte[] bytes) {
if (!args.coreLibrary) {
checkClassName(name);
}
DirectClassFile cf = new DirectClassFile(bytes, name, args.cfOptions.strictNameCheck);
cf.setAttributeFactory(StdAttributeFactory.THE_ONE);
cf.getMagic();
int numMethodIds = outputDex.getMethodIds().items().size();
int numFieldIds = outputDex.getFieldIds().items().size();
int constantPoolSize = cf.getConstantPool().size();
int maxMethodIdsInDex = numMethodIds + constantPoolSize + cf.getMethods().size() + MAX_METHOD_ADDED_DURING_DEX_CREATION;
int maxFieldIdsInDex = numFieldIds + constantPoolSize + cf.getFields().size() + MAX_FIELD_ADDED_DURING_DEX_CREATION;
if (args.multiDex && // Never switch to the next dex if current dex is already empty
(outputDex.getClassDefs().items().size() > 0) && ((maxMethodIdsInDex > args.maxNumberOfIdxPerDex) || (maxFieldIdsInDex > args.maxNumberOfIdxPerDex))) {
DexFile completeDex = outputDex;
createDexFile();
assert (completeDex.getMethodIds().items().size() <= numMethodIds + MAX_METHOD_ADDED_DURING_DEX_CREATION) && (completeDex.getFieldIds().items().size() <= numFieldIds + MAX_FIELD_ADDED_DURING_DEX_CREATION);
}
try {
ClassDefItem clazz = CfTranslator.translate(cf, bytes, args.cfOptions, args.dexOptions, args.optimizerOptions, outputDex);
synchronized (outputDex) {
outputDex.add(clazz);
}
return true;
} catch (ParseException ex) {
dxConsole.err.println("\ntrouble processing:");
if (args.debug) {
ex.printStackTrace(dxConsole.err);
} else {
ex.printContext(dxConsole.err);
}
}
errors.incrementAndGet();
return false;
}
use of com.taobao.android.dx.cf.iface.ParseException in project atlas by alibaba.
the class MemberListParser method parse.
/**
* Does the actual parsing.
*/
private void parse() {
int attributeContext = getAttributeContext();
int count = getCount();
// Skip the count.
int at = offset + 2;
ByteArray bytes = cf.getBytes();
ConstantPool pool = cf.getConstantPool();
if (observer != null) {
observer.parsed(bytes, offset, 2, humanName() + "s_count: " + Hex.u2(count));
}
for (int i = 0; i < count; i++) {
try {
int accessFlags = bytes.getUnsignedShort(at);
int nameIdx = bytes.getUnsignedShort(at + 2);
int descIdx = bytes.getUnsignedShort(at + 4);
CstString name = (CstString) pool.get(nameIdx);
CstString desc = (CstString) pool.get(descIdx);
if (observer != null) {
observer.startParsingMember(bytes, at, name.getString(), desc.getString());
observer.parsed(bytes, at, 0, "\n" + humanName() + "s[" + i + "]:\n");
observer.changeIndent(1);
observer.parsed(bytes, at, 2, "access_flags: " + humanAccessFlags(accessFlags));
observer.parsed(bytes, at + 2, 2, "name: " + name.toHuman());
observer.parsed(bytes, at + 4, 2, "descriptor: " + desc.toHuman());
}
at += 6;
AttributeListParser parser = new AttributeListParser(cf, attributeContext, at, attributeFactory);
parser.setObserver(observer);
at = parser.getEndOffset();
StdAttributeList attributes = parser.getList();
attributes.setImmutable();
CstNat nat = new CstNat(name, desc);
Member member = set(i, accessFlags, nat, attributes);
if (observer != null) {
observer.changeIndent(-1);
observer.parsed(bytes, at, 0, "end " + humanName() + "s[" + i + "]\n");
observer.endParsingMember(bytes, at, name.getString(), desc.getString(), member);
}
} catch (ParseException ex) {
ex.addContext("...while parsing " + humanName() + "s[" + i + "]");
throw ex;
} catch (RuntimeException ex) {
ParseException pe = new ParseException(ex);
pe.addContext("...while parsing " + humanName() + "s[" + i + "]");
throw pe;
}
}
endOffset = at;
}
Aggregations