mirror of
https://github.com/revanced/Apktool.git
synced 2025-05-01 14:44:26 +02:00
Support Spare Flags (#2887)
* support sparse flag * style: cs changes Co-authored-by: R0S <41138521+iamr0s@users.noreply.github.com>
This commit is contained in:
parent
3fff2f128e
commit
dc3667dbd0
@ -33,6 +33,7 @@ import java.math.BigInteger;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
@ -250,8 +251,7 @@ public class ARSCDecoder {
|
|||||||
/* reserved */mIn.skipBytes(2);
|
/* reserved */mIn.skipBytes(2);
|
||||||
int entryCount = mIn.readInt();
|
int entryCount = mIn.readInt();
|
||||||
int entriesStart = mIn.readInt();
|
int entriesStart = mIn.readInt();
|
||||||
mMissingResSpecs = new boolean[entryCount];
|
mMissingResSpecMap = new LinkedHashMap();
|
||||||
Arrays.fill(mMissingResSpecs, true);
|
|
||||||
|
|
||||||
ResConfigFlags flags = readConfigFlags();
|
ResConfigFlags flags = readConfigFlags();
|
||||||
int position = (mHeader.startPosition + entriesStart) - (entryCount * 4);
|
int position = (mHeader.startPosition + entriesStart) - (entryCount * 4);
|
||||||
@ -263,10 +263,18 @@ public class ARSCDecoder {
|
|||||||
mIn.skipBytes(position - mCountIn.getCount());
|
mIn.skipBytes(position - mCountIn.getCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeFlags == 1) {
|
if ((typeFlags & 0x01) != 0) {
|
||||||
LOGGER.info("Sparse type flags detected: " + mTypeSpec.getName());
|
LOGGER.info("Sparse type flags detected: " + mTypeSpec.getName());
|
||||||
}
|
}
|
||||||
int[] entryOffsets = mIn.readIntArray(entryCount);
|
|
||||||
|
HashMap<Integer, Integer> entryOffsetMap = new LinkedHashMap();
|
||||||
|
for (int i = 0; i < entryCount; i++) {
|
||||||
|
if ((typeFlags & 0x01) != 0) {
|
||||||
|
entryOffsetMap.put(mIn.readUnsignedShort(), mIn.readUnsignedShort());
|
||||||
|
} else {
|
||||||
|
entryOffsetMap.put(i, mIn.readInt());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (flags.isInvalid) {
|
if (flags.isInvalid) {
|
||||||
String resName = mTypeSpec.getName() + flags.getQualifiers();
|
String resName = mTypeSpec.getName() + flags.getQualifiers();
|
||||||
@ -278,23 +286,15 @@ public class ARSCDecoder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mType = flags.isInvalid && !mKeepBroken ? null : mPkg.getOrCreateConfig(flags);
|
mType = flags.isInvalid && !mKeepBroken ? null : mPkg.getOrCreateConfig(flags);
|
||||||
HashMap<Integer, EntryData> offsetsToEntryData = new HashMap<>();
|
|
||||||
|
|
||||||
for (int offset : entryOffsets) {
|
for (int i : entryOffsetMap.keySet()) {
|
||||||
if (offset == -1 || offsetsToEntryData.containsKey(offset)) {
|
int offset = entryOffsetMap.get(i);
|
||||||
|
if (offset == -1) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
mMissingResSpecMap.put(i, false);
|
||||||
offsetsToEntryData.put(offset, readEntryData());
|
mResId = (mResId & 0xffff0000) | i;
|
||||||
}
|
readEntry(readEntryData());
|
||||||
|
|
||||||
for (int i = 0; i < entryOffsets.length; i++) {
|
|
||||||
if (entryOffsets[i] != -1) {
|
|
||||||
mMissingResSpecs[i] = false;
|
|
||||||
mResId = (mResId & 0xffff0000) | i;
|
|
||||||
EntryData entryData = offsetsToEntryData.get(entryOffsets[i]);
|
|
||||||
readEntry(entryData);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return mType;
|
return mType;
|
||||||
@ -533,14 +533,12 @@ public class ARSCDecoder {
|
|||||||
private void addMissingResSpecs() throws AndrolibException {
|
private void addMissingResSpecs() throws AndrolibException {
|
||||||
int resId = mResId & 0xffff0000;
|
int resId = mResId & 0xffff0000;
|
||||||
|
|
||||||
for (int i = 0; i < mMissingResSpecs.length; i++) {
|
for (int i : mMissingResSpecMap.keySet()) {
|
||||||
if (!mMissingResSpecs[i]) {
|
if (mMissingResSpecMap.get(i)) continue;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ResResSpec spec = new ResResSpec(new ResID(resId | i), "APKTOOL_DUMMY_" + Integer.toHexString(i), mPkg, mTypeSpec);
|
ResResSpec spec = new ResResSpec(new ResID(resId | i), "APKTOOL_DUMMY_" + Integer.toHexString(i), mPkg, mTypeSpec);
|
||||||
|
|
||||||
// If we already have this resID dont add it again.
|
// If we already have this resID don't add it again.
|
||||||
if (! mPkg.hasResSpec(new ResID(resId | i))) {
|
if (! mPkg.hasResSpec(new ResID(resId | i))) {
|
||||||
mPkg.addResSpec(spec);
|
mPkg.addResSpec(spec);
|
||||||
mTypeSpec.addResSpec(spec);
|
mTypeSpec.addResSpec(spec);
|
||||||
@ -598,7 +596,7 @@ public class ARSCDecoder {
|
|||||||
private ResType mType;
|
private ResType mType;
|
||||||
private int mResId;
|
private int mResId;
|
||||||
private int mTypeIdOffset = 0;
|
private int mTypeIdOffset = 0;
|
||||||
private boolean[] mMissingResSpecs;
|
private HashMap<Integer, Boolean> mMissingResSpecMap;
|
||||||
private final HashMap<Integer, ResTypeSpec> mResTypeSpecs = new HashMap<>();
|
private final HashMap<Integer, ResTypeSpec> mResTypeSpecs = new HashMap<>();
|
||||||
|
|
||||||
private final static short ENTRY_FLAG_COMPLEX = 0x0001;
|
private final static short ENTRY_FLAG_COMPLEX = 0x0001;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user