diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ARSCDecoder.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ARSCDecoder.java index 0e64575b..abcb8eaa 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ARSCDecoder.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ARSCDecoder.java @@ -23,7 +23,7 @@ import brut.androlib.res.data.value.*; import brut.util.Duo; import brut.androlib.res.data.ResTable; import brut.util.ExtDataInput; -import com.peterfranza.LittleEndianDataInputStream; +import com.google.common.io.LittleEndianDataInputStream; import java.io.*; import java.math.BigInteger; import java.util.*; @@ -60,7 +60,10 @@ public class ARSCDecoder { } else { mFlagsOffsets = null; } - mIn = new ExtDataInput(new LittleEndianDataInputStream(arscStream)); + // We need to explicitly cast to DataInput as otherwise the constructor is ambiguous. + // We choose DataInput instead of InputStream as ExtDataInput wraps an InputStream in + // a DataInputStream which is big-endian and ignores the little-endian behavior. + mIn = new ExtDataInput((DataInput) new LittleEndianDataInputStream(arscStream)); mResTable = resTable; mKeepBroken = keepBroken; } diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/AXmlResourceParser.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/AXmlResourceParser.java index 6b2e71d4..8c1fe60e 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/AXmlResourceParser.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/AXmlResourceParser.java @@ -20,7 +20,8 @@ import android.util.TypedValue; import brut.androlib.AndrolibException; import brut.androlib.res.xml.ResXmlEncoders; import brut.util.ExtDataInput; -import com.peterfranza.LittleEndianDataInputStream; +import com.google.common.io.LittleEndianDataInputStream; +import java.io.DataInput; import java.io.IOException; import java.io.InputStream; import java.io.Reader; @@ -69,7 +70,10 @@ public class AXmlResourceParser implements XmlResourceParser { public void open(InputStream stream) { close(); if (stream != null) { - m_reader = new ExtDataInput(new LittleEndianDataInputStream(stream)); + // We need to explicitly cast to DataInput as otherwise the constructor is ambiguous. + // We choose DataInput instead of InputStream as ExtDataInput wraps an InputStream in + // a DataInputStream which is big-endian and ignores the little-endian behavior. + m_reader = new ExtDataInput((DataInput) new LittleEndianDataInputStream(stream)); } } diff --git a/brut.apktool/apktool-lib/src/main/java/com/peterfranza/LittleEndianDataInputStream.java b/brut.apktool/apktool-lib/src/main/java/com/peterfranza/LittleEndianDataInputStream.java deleted file mode 100644 index 8777b9b1..00000000 --- a/brut.apktool/apktool-lib/src/main/java/com/peterfranza/LittleEndianDataInputStream.java +++ /dev/null @@ -1,139 +0,0 @@ -package com.peterfranza; - -import java.io.DataInput; -import java.io.DataInputStream; -import java.io.IOException; -import java.io.InputStream; - -public class LittleEndianDataInputStream implements DataInput { - - public LittleEndianDataInputStream(InputStream in) { - this.in = in; - this.d = new DataInputStream(in); - w = new byte[8]; - } - - public int available() throws IOException { - return d.available(); - } - - - public final short readShort() throws IOException - { - d.readFully(w, 0, 2); - return (short)( - (w[1]&0xff) << 8 | - (w[0]&0xff)); - } - - /** - * Note, returns int even though it reads a short. - */ - public final int readUnsignedShort() throws IOException - { - d.readFully(w, 0, 2); - return ( - (w[1]&0xff) << 8 | - (w[0]&0xff)); - } - - /** - * like DataInputStream.readChar except little endian. - */ - public final char readChar() throws IOException - { - d.readFully(w, 0, 2); - return (char) ( - (w[1]&0xff) << 8 | - (w[0]&0xff)); - } - - /** - * like DataInputStream.readInt except little endian. - */ - public final int readInt() throws IOException - { - d.readFully(w, 0, 4); - return - (w[3]) << 24 | - (w[2]&0xff) << 16 | - (w[1]&0xff) << 8 | - (w[0]&0xff); - } - - /** - * like DataInputStream.readLong except little endian. - */ - public final long readLong() throws IOException - { - d.readFully(w, 0, 8); - return - (long)(w[7]) << 56 | - (long)(w[6]&0xff) << 48 | - (long)(w[5]&0xff) << 40 | - (long)(w[4]&0xff) << 32 | - (long)(w[3]&0xff) << 24 | - (long)(w[2]&0xff) << 16 | - (long)(w[1]&0xff) << 8 | - (long)(w[0]&0xff); - } - - public final float readFloat() throws IOException { - return Float.intBitsToFloat(readInt()); - } - - public final double readDouble() throws IOException { - return Double.longBitsToDouble(readLong()); - } - - public final int read(byte b[], int off, int len) throws IOException { - return in.read(b, off, len); - } - - public final void readFully(byte b[]) throws IOException { - d.readFully(b, 0, b.length); - } - - public final void readFully(byte b[], int off, int len) throws IOException { - d.readFully(b, off, len); - } - - public final int skipBytes(int n) throws IOException { - return d.skipBytes(n); - } - - public final boolean readBoolean() throws IOException { - return d.readBoolean(); - } - - public final byte readByte() throws IOException { - return d.readByte(); - } - - public int read() throws IOException { - return in.read(); - } - - public final int readUnsignedByte() throws IOException { - return d.readUnsignedByte(); - } - - @Deprecated - public final String readLine() throws IOException { - return d.readLine(); - } - - public final String readUTF() throws IOException { - return d.readUTF(); - } - - public final void close() throws IOException { - d.close(); - } - - private DataInputStream d; // to get at high level readFully methods of - // DataInputStream - private InputStream in; // to get at the low-level read methods of - // InputStream - private byte w[]; // work array for buffering input -} diff --git a/brut.j.util/src/main/java/brut/util/ExtDataInput.java b/brut.j.util/src/main/java/brut/util/ExtDataInput.java index 3e8764ca..72ef4140 100644 --- a/brut.j.util/src/main/java/brut/util/ExtDataInput.java +++ b/brut.j.util/src/main/java/brut/util/ExtDataInput.java @@ -76,6 +76,22 @@ public class ExtDataInput extends DataInputDelegate { } } + /** + * The general contract of DataInput doesn't guarantee all the bytes requested will be skipped + * and failure can occur for many reasons. We override this to try harder to skip all the bytes + * requested (this is similar to DataInputStream's wrapper). + */ + public final int skipBytes(int n) throws IOException { + int total = 0; + int cur = 0; + + while ((total < n) && ((cur = (int) super.skipBytes(n - total)) > 0)) { + total += cur; + } + + return total; + } + public String readNullEndedString(int length, boolean fixed) throws IOException { StringBuilder string = new StringBuilder(16);