Skip to content

Commit dc3667d

Browse files
iBotPeachesiamr0s
andauthored
Support Spare Flags (#2887)
* support sparse flag * style: cs changes Co-authored-by: R0S <[email protected]>
1 parent 3fff2f1 commit dc3667d

File tree

1 file changed

+22
-24
lines changed
  • brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder

1 file changed

+22
-24
lines changed

brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ARSCDecoder.java

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import java.util.ArrayList;
3434
import java.util.Arrays;
3535
import java.util.HashMap;
36+
import java.util.LinkedHashMap;
3637
import java.util.List;
3738
import java.util.logging.Logger;
3839

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

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

266-
if (typeFlags == 1) {
266+
if ((typeFlags & 0x01) != 0) {
267267
LOGGER.info("Sparse type flags detected: " + mTypeSpec.getName());
268268
}
269-
int[] entryOffsets = mIn.readIntArray(entryCount);
269+
270+
HashMap<Integer, Integer> entryOffsetMap = new LinkedHashMap();
271+
for (int i = 0; i < entryCount; i++) {
272+
if ((typeFlags & 0x01) != 0) {
273+
entryOffsetMap.put(mIn.readUnsignedShort(), mIn.readUnsignedShort());
274+
} else {
275+
entryOffsetMap.put(i, mIn.readInt());
276+
}
277+
}
270278

271279
if (flags.isInvalid) {
272280
String resName = mTypeSpec.getName() + flags.getQualifiers();
@@ -278,23 +286,15 @@ private ResType readTableType() throws IOException, AndrolibException {
278286
}
279287

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

283-
for (int offset : entryOffsets) {
284-
if (offset == -1 || offsetsToEntryData.containsKey(offset)) {
290+
for (int i : entryOffsetMap.keySet()) {
291+
int offset = entryOffsetMap.get(i);
292+
if (offset == -1) {
285293
continue;
286294
}
287-
288-
offsetsToEntryData.put(offset, readEntryData());
289-
}
290-
291-
for (int i = 0; i < entryOffsets.length; i++) {
292-
if (entryOffsets[i] != -1) {
293-
mMissingResSpecs[i] = false;
294-
mResId = (mResId & 0xffff0000) | i;
295-
EntryData entryData = offsetsToEntryData.get(entryOffsets[i]);
296-
readEntry(entryData);
297-
}
295+
mMissingResSpecMap.put(i, false);
296+
mResId = (mResId & 0xffff0000) | i;
297+
readEntry(readEntryData());
298298
}
299299

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

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

541539
ResResSpec spec = new ResResSpec(new ResID(resId | i), "APKTOOL_DUMMY_" + Integer.toHexString(i), mPkg, mTypeSpec);
542540

543-
// If we already have this resID dont add it again.
541+
// If we already have this resID don't add it again.
544542
if (! mPkg.hasResSpec(new ResID(resId | i))) {
545543
mPkg.addResSpec(spec);
546544
mTypeSpec.addResSpec(spec);
@@ -598,7 +596,7 @@ private void nextChunkCheckType(int expectedType) throws IOException, AndrolibEx
598596
private ResType mType;
599597
private int mResId;
600598
private int mTypeIdOffset = 0;
601-
private boolean[] mMissingResSpecs;
599+
private HashMap<Integer, Boolean> mMissingResSpecMap;
602600
private final HashMap<Integer, ResTypeSpec> mResTypeSpecs = new HashMap<>();
603601

604602
private final static short ENTRY_FLAG_COMPLEX = 0x0001;

0 commit comments

Comments
 (0)