[skip] update changelog, code style fixes

This commit is contained in:
Connor Tumbleson 2014-10-05 12:09:57 -05:00
parent 62db52fe7b
commit 06bcff5b6f
3 changed files with 33 additions and 48 deletions

View File

@ -45,6 +45,7 @@ v2.0.0 (TBA)
-Fixed (issue #675) - Fixed multiple overlapping catches. -Fixed (issue #675) - Fixed multiple overlapping catches.
-Fixed (issue #684) - Fixed issue with multiple ResPackages in ARSC file. -Fixed (issue #684) - Fixed issue with multiple ResPackages in ARSC file.
-Fixed (issue #682) - Fixed handling renamed manifests with ("yi") -Fixed (issue #682) - Fixed handling renamed manifests with ("yi")
-Fixed (issue #664) - Fixed issue with apks with large StringPools failing to decode.
-Fixed issue with APKs with multiple dex files. -Fixed issue with APKs with multiple dex files.
-Fixed issue with using Apktool without smali/baksmali for ApktoolProperties (Thanks teprrr) -Fixed issue with using Apktool without smali/baksmali for ApktoolProperties (Thanks teprrr)
-Fixed issue with non-URI standard characters in apk name (Thanks rover12421) -Fixed issue with non-URI standard characters in apk name (Thanks rover12421)

View File

@ -34,29 +34,26 @@ import org.apache.commons.io.input.CountingInputStream;
* @author Ryszard Wiśniewski <brut.alll@gmail.com> * @author Ryszard Wiśniewski <brut.alll@gmail.com>
*/ */
public class ARSCDecoder { public class ARSCDecoder {
public static ARSCData decode(InputStream arscStream, public static ARSCData decode(InputStream arscStream, boolean findFlagsOffsets, boolean keepBroken)
boolean findFlagsOffsets, boolean keepBroken)
throws AndrolibException { throws AndrolibException {
return decode(arscStream, findFlagsOffsets, keepBroken, new ResTable()); return decode(arscStream, findFlagsOffsets, keepBroken, new ResTable());
} }
public static ARSCData decode(InputStream arscStream, public static ARSCData decode(InputStream arscStream, boolean findFlagsOffsets, boolean keepBroken,
boolean findFlagsOffsets, boolean keepBroken, ResTable resTable) ResTable resTable)
throws AndrolibException { throws AndrolibException {
try { try {
ARSCDecoder decoder = new ARSCDecoder(arscStream, resTable, ARSCDecoder decoder = new ARSCDecoder(arscStream, resTable, findFlagsOffsets, keepBroken);
findFlagsOffsets, keepBroken);
ResPackage[] pkgs = decoder.readTable(); ResPackage[] pkgs = decoder.readTable();
return new ARSCData(pkgs, decoder.mFlagsOffsets == null ? null return new ARSCData(pkgs, decoder.mFlagsOffsets == null
: decoder.mFlagsOffsets.toArray(new FlagsOffset[0]), ? null
resTable); : decoder.mFlagsOffsets.toArray(new FlagsOffset[0]), resTable);
} catch (IOException ex) { } catch (IOException ex) {
throw new AndrolibException("Could not decode arsc file", ex); throw new AndrolibException("Could not decode arsc file", ex);
} }
} }
private ARSCDecoder(InputStream arscStream, ResTable resTable, private ARSCDecoder(InputStream arscStream, ResTable resTable, boolean storeFlagsOffsets, boolean keepBroken) {
boolean storeFlagsOffsets, boolean keepBroken) {
if (storeFlagsOffsets) { if (storeFlagsOffsets) {
arscStream = mCountIn = new CountingInputStream(arscStream); arscStream = mCountIn = new CountingInputStream(arscStream);
mFlagsOffsets = new ArrayList<FlagsOffset>(); mFlagsOffsets = new ArrayList<FlagsOffset>();
@ -87,10 +84,10 @@ public class ARSCDecoder {
checkChunkType(Header.TYPE_PACKAGE); checkChunkType(Header.TYPE_PACKAGE);
int id = (byte) mIn.readInt(); int id = (byte) mIn.readInt();
String name = mIn.readNullEndedString(128, true); String name = mIn.readNullEndedString(128, true);
/* typeNameStrings */mIn.skipInt(); /* typeStrings */mIn.skipInt();
/* typeNameCount */mIn.skipInt(); /* lastPublicType */mIn.skipInt();
/* specNameStrings */mIn.skipInt(); /* keyStrings */mIn.skipInt();
/* specNameCount */mIn.skipInt(); /* lastPublicKey */mIn.skipInt();
mTypeNames = StringBlock.read(mIn); mTypeNames = StringBlock.read(mIn);
mSpecNames = StringBlock.read(mIn); mSpecNames = StringBlock.read(mIn);
@ -147,13 +144,11 @@ public class ARSCDecoder {
if (mKeepBroken) { if (mKeepBroken) {
LOGGER.warning("Invalid config flags detected: " + resName); LOGGER.warning("Invalid config flags detected: " + resName);
} else { } else {
LOGGER.warning("Invalid config flags detected. Dropping resources: " LOGGER.warning("Invalid config flags detected. Dropping resources: " + resName);
+ resName);
} }
} }
mConfig = flags.isInvalid && !mKeepBroken ? null : mPkg mConfig = flags.isInvalid && !mKeepBroken ? null : mPkg.getOrCreateConfig(flags);
.getOrCreateConfig(flags);
for (int i = 0; i < entryOffsets.length; i++) { for (int i = 0; i < entryOffsets.length; i++) {
if (entryOffsets[i] != -1) { if (entryOffsets[i] != -1) {
@ -171,8 +166,7 @@ public class ARSCDecoder {
short flags = mIn.readShort(); short flags = mIn.readShort();
int specNamesId = mIn.readInt(); int specNamesId = mIn.readInt();
ResValue value = (flags & ENTRY_FLAG_COMPLEX) == 0 ? readValue() ResValue value = (flags & ENTRY_FLAG_COMPLEX) == 0 ? readValue() : readComplexEntry();
: readComplexEntry();
if (mConfig == null) { if (mConfig == null) {
return; return;
@ -183,8 +177,7 @@ public class ARSCDecoder {
if (mPkg.hasResSpec(resId)) { if (mPkg.hasResSpec(resId)) {
spec = mPkg.getResSpec(resId); spec = mPkg.getResSpec(resId);
} else { } else {
spec = new ResResSpec(resId, mSpecNames.getString(specNamesId), spec = new ResResSpec(resId, mSpecNames.getString(specNamesId), mPkg, mType);
mPkg, mType);
mPkg.addResSpec(spec); mPkg.addResSpec(spec);
mType.addResSpec(spec); mType.addResSpec(spec);
} }
@ -203,8 +196,7 @@ public class ARSCDecoder {
ResValueFactory factory = mPkg.getValueFactory(); ResValueFactory factory = mPkg.getValueFactory();
Duo<Integer, ResScalarValue>[] items = new Duo[count]; Duo<Integer, ResScalarValue>[] items = new Duo[count];
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
items[i] = new Duo<Integer, ResScalarValue>(mIn.readInt(), items[i] = new Duo<Integer, ResScalarValue>(mIn.readInt(), (ResScalarValue) readValue());
(ResScalarValue) readValue());
} }
return factory.bagFactory(parent, items); return factory.bagFactory(parent, items);
@ -216,9 +208,9 @@ public class ARSCDecoder {
byte type = mIn.readByte(); byte type = mIn.readByte();
int data = mIn.readInt(); int data = mIn.readInt();
return type == TypedValue.TYPE_STRING ? mPkg.getValueFactory().factory( return type == TypedValue.TYPE_STRING
mTableStrings.getHTML(data)) : mPkg.getValueFactory().factory( ? mPkg.getValueFactory().factory(mTableStrings.getHTML(data))
type, data, null); : mPkg.getValueFactory().factory(type, data, null);
} }
private ResConfigFlags readConfigFlags() throws IOException, private ResConfigFlags readConfigFlags() throws IOException,
@ -233,10 +225,8 @@ public class ARSCDecoder {
short mcc = mIn.readShort(); short mcc = mIn.readShort();
short mnc = mIn.readShort(); short mnc = mIn.readShort();
char[] language = new char[] { (char) mIn.readByte(), char[] language = new char[] { (char) mIn.readByte(), (char) mIn.readByte() };
(char) mIn.readByte() }; char[] country = new char[] { (char) mIn.readByte(), (char) mIn.readByte() };
char[] country = new char[] { (char) mIn.readByte(),
(char) mIn.readByte() };
byte orientation = mIn.readByte(); byte orientation = mIn.readByte();
byte touchscreen = mIn.readByte(); byte touchscreen = mIn.readByte();
@ -286,8 +276,7 @@ public class ARSCDecoder {
.format("Config flags size > %d, but exceeding bytes are all zero, so it should be ok.", .format("Config flags size > %d, but exceeding bytes are all zero, so it should be ok.",
KNOWN_CONFIG_BYTES)); KNOWN_CONFIG_BYTES));
} else { } else {
LOGGER.warning(String.format( LOGGER.warning(String.format("Config flags size > %d. Exceeding bytes: 0x%X.",
"Config flags size > %d. Exceeding bytes: 0x%X.",
KNOWN_CONFIG_BYTES, exceedingBI)); KNOWN_CONFIG_BYTES, exceedingBI));
isInvalid = true; isInvalid = true;
} }
@ -308,8 +297,7 @@ public class ARSCDecoder {
continue; continue;
} }
ResResSpec spec = new ResResSpec(new ResID(resId | i), ResResSpec spec = new ResResSpec(new ResID(resId | i), String.format("APKTOOL_DUMMY_%04x", i), mPkg, mType);
String.format("APKTOOL_DUMMY_%04x", i), mPkg, mType);
mPkg.addResSpec(spec); mPkg.addResSpec(spec);
mType.addResSpec(spec); mType.addResSpec(spec);
@ -332,8 +320,7 @@ public class ARSCDecoder {
private void checkChunkType(int expectedType) throws AndrolibException { private void checkChunkType(int expectedType) throws AndrolibException {
if (mHeader.type != expectedType) { if (mHeader.type != expectedType) {
throw new AndrolibException(String.format( throw new AndrolibException(String.format("Invalid chunk type: expected=0x%08x, got=0x%08x",
"Invalid chunk type: expected=0x%08x, got=0x%08x",
expectedType, mHeader.type)); expectedType, mHeader.type));
} }
} }
@ -397,14 +384,12 @@ public class ARSCDecoder {
} }
} }
private static final Logger LOGGER = Logger.getLogger(ARSCDecoder.class private static final Logger LOGGER = Logger.getLogger(ARSCDecoder.class.getName());
.getName());
private static final int KNOWN_CONFIG_BYTES = 38; private static final int KNOWN_CONFIG_BYTES = 38;
public static class ARSCData { public static class ARSCData {
public ARSCData(ResPackage[] packages, FlagsOffset[] flagsOffsets, public ARSCData(ResPackage[] packages, FlagsOffset[] flagsOffsets, ResTable resTable) {
ResTable resTable) {
mPackages = packages; mPackages = packages;
mFlagsOffsets = flagsOffsets; mFlagsOffsets = flagsOffsets;
mResTable = resTable; mResTable = resTable;
@ -420,11 +405,12 @@ public class ARSCDecoder {
public ResPackage getOnePackage() throws AndrolibException { public ResPackage getOnePackage() throws AndrolibException {
if (mPackages.length <= 0) { if (mPackages.length <= 0) {
throw new AndrolibException( throw new AndrolibException("Arsc file contains zero packages");
"Arsc file contains zero packages");
} else if (mPackages.length != 1) { } else if (mPackages.length != 1) {
int id = findPackageWithMostResSpecs(); int id = findPackageWithMostResSpecs();
LOGGER.warning("Arsc file contains multiple packages. Using package " + mPackages[id].getName() + " as default."); LOGGER.info("Arsc file contains multiple packages. Using package "
+ mPackages[id].getName() + " as default.");
return mPackages[id]; return mPackages[id];
} }
return mPackages[0]; return mPackages[0];

View File

@ -61,8 +61,7 @@ public class StringBlock {
block.m_styleOffsets = reader.readIntArray(styleCount); block.m_styleOffsets = reader.readIntArray(styleCount);
} }
{ {
int size = ((stylesOffset == 0) ? chunkSize : stylesOffset) int size = ((stylesOffset == 0) ? chunkSize : stylesOffset) - stringsOffset;
- stringsOffset;
if ((size % 4) != 0) { if ((size % 4) != 0) {
throw new IOException("String data size is not multiple of 4 (" + size + ")."); throw new IOException("String data size is not multiple of 4 (" + size + ").");
} }
@ -240,7 +239,6 @@ public class StringBlock {
return -1; return -1;
} }
// /////////////////////////////////////////// implementation
private StringBlock() { private StringBlock() {
} }