* core: Implemented parsing RES_TABLE_TYPE_LIBRARY chunks * skip unknown data at the end of type chunk
This commit is contained in:
@@ -28,9 +28,12 @@ public class ParserConstants {
|
||||
protected static final int RES_XML_LAST_CHUNK_TYPE = 0x017f;
|
||||
protected static final int RES_XML_RESOURCE_MAP_TYPE = 0x0180;
|
||||
|
||||
protected static final int RES_TABLE_PACKAGE_TYPE = 0x0200;
|
||||
protected static final int RES_TABLE_TYPE_TYPE = 0x0201;
|
||||
protected static final int RES_TABLE_TYPE_SPEC_TYPE = 0x0202;
|
||||
protected static final int RES_TABLE_PACKAGE_TYPE = 0x0200; // 512
|
||||
protected static final int RES_TABLE_TYPE_TYPE = 0x0201; // 513
|
||||
protected static final int RES_TABLE_TYPE_SPEC_TYPE = 0x0202; // 514
|
||||
protected static final int RES_TABLE_TYPE_LIBRARY = 0x0203; // 515
|
||||
protected static final int RES_TABLE_TYPE_OVERLAY = 0x0204; // 516
|
||||
protected static final int RES_TABLE_TYPE_STAGED_ALIAS = 0x0206; // 517
|
||||
|
||||
/**
|
||||
* Type constants
|
||||
|
||||
@@ -153,13 +153,28 @@ public class ResTableParser extends CommonBinaryParser implements IResParser {
|
||||
while (is.getPos() < endPos) {
|
||||
long chunkStart = is.getPos();
|
||||
int type = is.readInt16();
|
||||
if (type == RES_NULL_TYPE) {
|
||||
continue;
|
||||
}
|
||||
if (type == RES_TABLE_TYPE_SPEC_TYPE) {
|
||||
parseTypeSpecChunk();
|
||||
} else if (type == RES_TABLE_TYPE_TYPE) {
|
||||
parseTypeChunk(chunkStart, pkg);
|
||||
LOG.trace("res package chunk start at {} type {}", chunkStart, type);
|
||||
switch (type) {
|
||||
case RES_NULL_TYPE:
|
||||
LOG.info("Null chunk type encountered at offset {}", chunkStart);
|
||||
break;
|
||||
case RES_TABLE_TYPE_TYPE: // 0x0201
|
||||
parseTypeChunk(chunkStart, pkg);
|
||||
break;
|
||||
case RES_TABLE_TYPE_SPEC_TYPE: // 0x0202
|
||||
parseTypeSpecChunk(chunkStart);
|
||||
break;
|
||||
case RES_TABLE_TYPE_LIBRARY: // 0x0203
|
||||
parseLibraryTypeChunk(chunkStart);
|
||||
break;
|
||||
case RES_TABLE_TYPE_OVERLAY: // 0x0204
|
||||
throw new IOException(
|
||||
String.format("Encountered unsupported chunk type TYPE_OVERLAY at offset 0x%x ", chunkStart));
|
||||
case RES_TABLE_TYPE_STAGED_ALIAS: // 0x0206
|
||||
throw new IOException(
|
||||
String.format("Encountered unsupported chunk type TYPE_STAGED_ALIAS at offset 0x%x ", chunkStart));
|
||||
default:
|
||||
LOG.warn("Unknown chunk type {} encountered at offset {}", type, chunkStart);
|
||||
}
|
||||
}
|
||||
return pkg;
|
||||
@@ -192,10 +207,10 @@ public class ResTableParser extends CommonBinaryParser implements IResParser {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private void parseTypeSpecChunk() throws IOException {
|
||||
private void parseTypeSpecChunk(long chunkStart) throws IOException {
|
||||
is.checkInt16(0x0010, "Unexpected type spec header size");
|
||||
/* int size = */
|
||||
is.readInt32();
|
||||
int chunkSize = is.readInt32();
|
||||
long expectedEndPos = chunkStart + chunkSize;
|
||||
|
||||
int id = is.readInt8();
|
||||
is.skip(3);
|
||||
@@ -203,6 +218,28 @@ public class ResTableParser extends CommonBinaryParser implements IResParser {
|
||||
for (int i = 0; i < entryCount; i++) {
|
||||
int entryFlag = is.readInt32();
|
||||
}
|
||||
if (is.getPos() != expectedEndPos) {
|
||||
throw new IOException(String.format("Error reading type spec chunk at offset 0x%x", chunkStart));
|
||||
}
|
||||
}
|
||||
|
||||
private void parseLibraryTypeChunk(long chunkStart) throws IOException {
|
||||
LOG.trace("parsing library type chunk starting at offset {}", chunkStart);
|
||||
is.checkInt16(12, "Unexpected header size");
|
||||
int chunkSize = is.readInt32();
|
||||
long expectedEndPos = chunkStart + chunkSize;
|
||||
int count = is.readInt32();
|
||||
for (int i = 0; i < count; i++) {
|
||||
int packageId = is.readInt32();
|
||||
String packageName = is.readString16Fixed(128);
|
||||
LOG.info("Found resource shared library {}, pkgId: {}", packageName, packageId);
|
||||
if (is.getPos() > expectedEndPos) {
|
||||
throw new IOException("reading after chunk end");
|
||||
}
|
||||
}
|
||||
if (is.getPos() != expectedEndPos) {
|
||||
throw new IOException(String.format("Error reading library chunk at offset 0x%x", chunkStart));
|
||||
}
|
||||
}
|
||||
|
||||
private void parseTypeChunk(long start, PackageChunk pkg) throws IOException {
|
||||
@@ -241,6 +278,13 @@ public class ResTableParser extends CommonBinaryParser implements IResParser {
|
||||
parseEntry(pkg, id, i, config.getQualifiers());
|
||||
}
|
||||
}
|
||||
if (chunkEnd > is.getPos()) {
|
||||
// Skip remaining unknown data in this chunk (e.g. type 8 entries")
|
||||
long skipSize = chunkEnd - is.getPos();
|
||||
LOG.debug("Unknown data at the end of type chunk encountered, skipping {} bytes and continuing at offset {}", skipSize,
|
||||
chunkEnd);
|
||||
is.skip(skipSize);
|
||||
}
|
||||
}
|
||||
|
||||
private void parseEntry(PackageChunk pkg, int typeId, int entryId, String config) throws IOException {
|
||||
|
||||
Reference in New Issue
Block a user