feat(res): improve error message for unsupported ResTable flags (PR #2266)
This commit is contained in:
@@ -145,8 +145,20 @@ public class ParserConstants {
|
||||
protected static final int SORTED_FLAG = 1;
|
||||
protected static final int UTF8_FLAG = 1 << 8;
|
||||
|
||||
/**
|
||||
* ResTable_type
|
||||
*/
|
||||
protected static final int NO_ENTRY = 0xFFFFFFFF;
|
||||
|
||||
// If set, the entry is sparse, and encodes both the entry ID and offset into each entry,
|
||||
// and a binary search is used to find the key. Only available on platforms >= O.
|
||||
// Mark any types that use this with a v26 qualifier to prevent runtime issues on older
|
||||
// platforms.
|
||||
protected static final int FLAG_SPARSE = 0x01;
|
||||
// If set, the offsets to the entries are encoded in 16-bit, real_offset = offset * 4u
|
||||
// An 16-bit offset of 0xffffu means a NO_ENTRY
|
||||
protected static final int FLAG_OFFSET16 = 0x02;
|
||||
|
||||
/**
|
||||
* ResTable_entry
|
||||
*/
|
||||
@@ -158,6 +170,9 @@ public class ParserConstants {
|
||||
// If set, this is a weak resource and may be overridden by strong resources of the same name/type.
|
||||
// This is only useful during linking with other resource tables.
|
||||
protected static final int FLAG_WEAK = 0x0004;
|
||||
// If set, this is a compact entry with data type and value directly
|
||||
// encoded in the entry, see ResTable_entry::compact
|
||||
protected static final int FLAG_COMPACT = 0x0008;
|
||||
|
||||
/**
|
||||
* ResTable_map
|
||||
|
||||
@@ -274,8 +274,14 @@ public class ResTableBinaryParser extends CommonBinaryParser implements IResTabl
|
||||
// The type identifier this chunk is holding. Type IDs start at 1 (corresponding
|
||||
// to the value of the type bits in a resource identifier). 0 is invalid.
|
||||
int id = is.readInt8();
|
||||
int flags = is.readInt8(); // 0 or 1
|
||||
boolean flagSparse = flags == 1;
|
||||
|
||||
int flags = is.readInt8();
|
||||
boolean isSparse = (flags & FLAG_SPARSE) != 0;
|
||||
boolean isOffset16 = (flags & FLAG_OFFSET16) != 0;
|
||||
|
||||
if (isOffset16) {
|
||||
throw new JadxRuntimeException("16-bit entry offsets are not supported yet");
|
||||
}
|
||||
|
||||
is.checkInt16(0, "type chunk, reserved");
|
||||
int entryCount = is.readInt32();
|
||||
@@ -289,7 +295,7 @@ public class ResTableBinaryParser extends CommonBinaryParser implements IResTabl
|
||||
}
|
||||
|
||||
Map<Integer, Integer> entryOffsetMap = new LinkedHashMap<>(entryCount);
|
||||
if (flagSparse) {
|
||||
if (isSparse) {
|
||||
for (int i = 0; i < entryCount; i++) {
|
||||
int idx = is.readInt16();
|
||||
int offset = is.readInt16() * 4; // The offset in ResTable_sparseTypeEntry::offset is stored divided by 4.
|
||||
@@ -357,7 +363,15 @@ public class ResTableBinaryParser extends CommonBinaryParser implements IResTabl
|
||||
|
||||
private void parseEntry(PackageChunk pkg, int typeId, int entryId, String config) throws IOException {
|
||||
int size = is.readInt16();
|
||||
|
||||
int flags = is.readInt16();
|
||||
boolean isComplex = (flags & FLAG_COMPLEX) != 0;
|
||||
boolean isCompact = (flags & FLAG_COMPACT) != 0;
|
||||
|
||||
if (isCompact) {
|
||||
throw new JadxRuntimeException("Compact resource entries are not supported yet");
|
||||
}
|
||||
|
||||
int key = is.readInt32();
|
||||
if (key == -1) {
|
||||
return;
|
||||
@@ -368,7 +382,7 @@ public class ResTableBinaryParser extends CommonBinaryParser implements IResTabl
|
||||
String origKeyName = pkg.getKeyStrings().get(key);
|
||||
|
||||
ResourceEntry newResEntry = buildResourceEntry(pkg, config, resRef, typeName, origKeyName);
|
||||
if ((flags & FLAG_COMPLEX) != 0 || size == 16) {
|
||||
if (isComplex || size == 16) {
|
||||
int parentRef = is.readInt32();
|
||||
int count = is.readInt32();
|
||||
newResEntry.setParentRef(parentRef);
|
||||
|
||||
Reference in New Issue
Block a user