33
33
import java .util .ArrayList ;
34
34
import java .util .Arrays ;
35
35
import java .util .HashMap ;
36
+ import java .util .LinkedHashMap ;
36
37
import java .util .List ;
37
38
import java .util .logging .Logger ;
38
39
@@ -250,8 +251,7 @@ private ResType readTableType() throws IOException, AndrolibException {
250
251
/* reserved */ mIn .skipBytes (2 );
251
252
int entryCount = mIn .readInt ();
252
253
int entriesStart = mIn .readInt ();
253
- mMissingResSpecs = new boolean [entryCount ];
254
- Arrays .fill (mMissingResSpecs , true );
254
+ mMissingResSpecMap = new LinkedHashMap ();
255
255
256
256
ResConfigFlags flags = readConfigFlags ();
257
257
int position = (mHeader .startPosition + entriesStart ) - (entryCount * 4 );
@@ -263,10 +263,18 @@ private ResType readTableType() throws IOException, AndrolibException {
263
263
mIn .skipBytes (position - mCountIn .getCount ());
264
264
}
265
265
266
- if (typeFlags == 1 ) {
266
+ if (( typeFlags & 0x01 ) != 0 ) {
267
267
LOGGER .info ("Sparse type flags detected: " + mTypeSpec .getName ());
268
268
}
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
+ }
270
278
271
279
if (flags .isInvalid ) {
272
280
String resName = mTypeSpec .getName () + flags .getQualifiers ();
@@ -278,23 +286,15 @@ private ResType readTableType() throws IOException, AndrolibException {
278
286
}
279
287
280
288
mType = flags .isInvalid && !mKeepBroken ? null : mPkg .getOrCreateConfig (flags );
281
- HashMap <Integer , EntryData > offsetsToEntryData = new HashMap <>();
282
289
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 ) {
285
293
continue ;
286
294
}
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 ());
298
298
}
299
299
300
300
return mType ;
@@ -533,14 +533,12 @@ private void addTypeSpec(ResTypeSpec resTypeSpec) {
533
533
private void addMissingResSpecs () throws AndrolibException {
534
534
int resId = mResId & 0xffff0000 ;
535
535
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 ;
540
538
541
539
ResResSpec spec = new ResResSpec (new ResID (resId | i ), "APKTOOL_DUMMY_" + Integer .toHexString (i ), mPkg , mTypeSpec );
542
540
543
- // If we already have this resID dont add it again.
541
+ // If we already have this resID don't add it again.
544
542
if (! mPkg .hasResSpec (new ResID (resId | i ))) {
545
543
mPkg .addResSpec (spec );
546
544
mTypeSpec .addResSpec (spec );
@@ -598,7 +596,7 @@ private void nextChunkCheckType(int expectedType) throws IOException, AndrolibEx
598
596
private ResType mType ;
599
597
private int mResId ;
600
598
private int mTypeIdOffset = 0 ;
601
- private boolean [] mMissingResSpecs ;
599
+ private HashMap < Integer , Boolean > mMissingResSpecMap ;
602
600
private final HashMap <Integer , ResTypeSpec > mResTypeSpecs = new HashMap <>();
603
601
604
602
private final static short ENTRY_FLAG_COMPLEX = 0x0001 ;
0 commit comments