Skip to content

Commit

Permalink
Support Spare Flags (#2887)
Browse files Browse the repository at this point in the history
* support sparse flag

* style: cs changes

Co-authored-by: R0S <41138521+iamr0s@users.noreply.github.com>
  • Loading branch information
iBotPeaches and iamr0s committed Sep 19, 2022
1 parent 3fff2f1 commit dc3667d
Showing 1 changed file with 22 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.logging.Logger;

Expand Down Expand Up @@ -250,8 +251,7 @@ private ResType readTableType() throws IOException, AndrolibException {
/* reserved */mIn.skipBytes(2);
int entryCount = mIn.readInt();
int entriesStart = mIn.readInt();
mMissingResSpecs = new boolean[entryCount];
Arrays.fill(mMissingResSpecs, true);
mMissingResSpecMap = new LinkedHashMap();

ResConfigFlags flags = readConfigFlags();
int position = (mHeader.startPosition + entriesStart) - (entryCount * 4);
Expand All @@ -263,10 +263,18 @@ private ResType readTableType() throws IOException, AndrolibException {
mIn.skipBytes(position - mCountIn.getCount());
}

if (typeFlags == 1) {
if ((typeFlags & 0x01) != 0) {
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) {
String resName = mTypeSpec.getName() + flags.getQualifiers();
Expand All @@ -278,23 +286,15 @@ private ResType readTableType() throws IOException, AndrolibException {
}

mType = flags.isInvalid && !mKeepBroken ? null : mPkg.getOrCreateConfig(flags);
HashMap<Integer, EntryData> offsetsToEntryData = new HashMap<>();

for (int offset : entryOffsets) {
if (offset == -1 || offsetsToEntryData.containsKey(offset)) {
for (int i : entryOffsetMap.keySet()) {
int offset = entryOffsetMap.get(i);
if (offset == -1) {
continue;
}

offsetsToEntryData.put(offset, 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);
}
mMissingResSpecMap.put(i, false);
mResId = (mResId & 0xffff0000) | i;
readEntry(readEntryData());
}

return mType;
Expand Down Expand Up @@ -533,14 +533,12 @@ private void addTypeSpec(ResTypeSpec resTypeSpec) {
private void addMissingResSpecs() throws AndrolibException {
int resId = mResId & 0xffff0000;

for (int i = 0; i < mMissingResSpecs.length; i++) {
if (!mMissingResSpecs[i]) {
continue;
}
for (int i : mMissingResSpecMap.keySet()) {
if (mMissingResSpecMap.get(i)) continue;

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))) {
mPkg.addResSpec(spec);
mTypeSpec.addResSpec(spec);
Expand Down Expand Up @@ -598,7 +596,7 @@ private void nextChunkCheckType(int expectedType) throws IOException, AndrolibEx
private ResType mType;
private int mResId;
private int mTypeIdOffset = 0;
private boolean[] mMissingResSpecs;
private HashMap<Integer, Boolean> mMissingResSpecMap;
private final HashMap<Integer, ResTypeSpec> mResTypeSpecs = new HashMap<>();

private final static short ENTRY_FLAG_COMPLEX = 0x0001;
Expand Down

0 comments on commit dc3667d

Please sign in to comment.