mirror of
https://github.com/revanced/Apktool.git
synced 2025-05-01 06:34:25 +02:00
[skip] update changelog, code style fixes
This commit is contained in:
parent
62db52fe7b
commit
06bcff5b6f
1
CHANGES
1
CHANGES
@ -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)
|
||||||
|
@ -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];
|
||||||
|
@ -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() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user