Search in sources :

Example 1 with ParseException

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);
    }
}
Also used : CstString(com.taobao.android.dx.rop.cst.CstString) ByteArray(com.taobao.android.dx.util.ByteArray) ParseException(com.taobao.android.dx.cf.iface.ParseException)

Example 2 with ParseException

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;
    }
}
Also used : ConstantPool(com.taobao.android.dx.rop.cst.ConstantPool) CstString(com.taobao.android.dx.rop.cst.CstString) ByteArray(com.taobao.android.dx.util.ByteArray) ParseException(com.taobao.android.dx.cf.iface.ParseException)

Example 3 with ParseException

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");
    }
}
Also used : ParseException(com.taobao.android.dx.cf.iface.ParseException) CstString(com.taobao.android.dx.rop.cst.CstString) ConstantPoolParser(com.taobao.android.dx.cf.cst.ConstantPoolParser)

Example 4 with ParseException

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;
}
Also used : DirectClassFile(com.taobao.android.dx.cf.direct.DirectClassFile) ClassDefItem(com.taobao.android.dx.dex.file.ClassDefItem) ParseException(com.taobao.android.dx.cf.iface.ParseException) DexFile(com.taobao.android.dx.dex.file.DexFile)

Example 5 with ParseException

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;
}
Also used : StdAttributeList(com.taobao.android.dx.cf.iface.StdAttributeList) CstNat(com.taobao.android.dx.rop.cst.CstNat) ConstantPool(com.taobao.android.dx.rop.cst.ConstantPool) CstString(com.taobao.android.dx.rop.cst.CstString) ByteArray(com.taobao.android.dx.util.ByteArray) ParseException(com.taobao.android.dx.cf.iface.ParseException) Member(com.taobao.android.dx.cf.iface.Member)

Aggregations

ParseException (com.taobao.android.dx.cf.iface.ParseException)10 CstString (com.taobao.android.dx.rop.cst.CstString)6 ByteArray (com.taobao.android.dx.util.ByteArray)4 CstNat (com.taobao.android.dx.rop.cst.CstNat)3 Constant (com.taobao.android.dx.rop.cst.Constant)2 ConstantPool (com.taobao.android.dx.rop.cst.ConstantPool)2 CstInteger (com.taobao.android.dx.rop.cst.CstInteger)2 CstType (com.taobao.android.dx.rop.cst.CstType)2 ConstantPoolParser (com.taobao.android.dx.cf.cst.ConstantPoolParser)1 DirectClassFile (com.taobao.android.dx.cf.direct.DirectClassFile)1 Attribute (com.taobao.android.dx.cf.iface.Attribute)1 Member (com.taobao.android.dx.cf.iface.Member)1 StdAttributeList (com.taobao.android.dx.cf.iface.StdAttributeList)1 ClassDefItem (com.taobao.android.dx.dex.file.ClassDefItem)1 DexFile (com.taobao.android.dx.dex.file.DexFile)1 Annotation (com.taobao.android.dx.rop.annotation.Annotation)1 AnnotationsList (com.taobao.android.dx.rop.annotation.AnnotationsList)1 CstAnnotation (com.taobao.android.dx.rop.cst.CstAnnotation)1 CstArray (com.taobao.android.dx.rop.cst.CstArray)1 CstDouble (com.taobao.android.dx.rop.cst.CstDouble)1