未验证 提交 b5070650 编写于 作者: J Jan S 提交者: GitHub

fix(res): implemented parsing RES_TABLE_TYPE_LIBRARY chunks (#1663)(PR #1664)

* core: Implemented parsing RES_TABLE_TYPE_LIBRARY chunks

* skip unknown data at the end of type chunk
上级 9114821f
...@@ -28,9 +28,12 @@ public class ParserConstants { ...@@ -28,9 +28,12 @@ public class ParserConstants {
protected static final int RES_XML_LAST_CHUNK_TYPE = 0x017f; 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_XML_RESOURCE_MAP_TYPE = 0x0180;
protected static final int RES_TABLE_PACKAGE_TYPE = 0x0200; protected static final int RES_TABLE_PACKAGE_TYPE = 0x0200; // 512
protected static final int RES_TABLE_TYPE_TYPE = 0x0201; protected static final int RES_TABLE_TYPE_TYPE = 0x0201; // 513
protected static final int RES_TABLE_TYPE_SPEC_TYPE = 0x0202; 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 * Type constants
......
...@@ -153,13 +153,28 @@ public class ResTableParser extends CommonBinaryParser implements IResParser { ...@@ -153,13 +153,28 @@ public class ResTableParser extends CommonBinaryParser implements IResParser {
while (is.getPos() < endPos) { while (is.getPos() < endPos) {
long chunkStart = is.getPos(); long chunkStart = is.getPos();
int type = is.readInt16(); int type = is.readInt16();
if (type == RES_NULL_TYPE) { LOG.trace("res package chunk start at {} type {}", chunkStart, type);
continue; switch (type) {
} case RES_NULL_TYPE:
if (type == RES_TABLE_TYPE_SPEC_TYPE) { LOG.info("Null chunk type encountered at offset {}", chunkStart);
parseTypeSpecChunk(); break;
} else if (type == RES_TABLE_TYPE_TYPE) { case RES_TABLE_TYPE_TYPE: // 0x0201
parseTypeChunk(chunkStart, pkg); 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; return pkg;
...@@ -192,10 +207,10 @@ public class ResTableParser extends CommonBinaryParser implements IResParser { ...@@ -192,10 +207,10 @@ public class ResTableParser extends CommonBinaryParser implements IResParser {
} }
@SuppressWarnings("unused") @SuppressWarnings("unused")
private void parseTypeSpecChunk() throws IOException { private void parseTypeSpecChunk(long chunkStart) throws IOException {
is.checkInt16(0x0010, "Unexpected type spec header size"); is.checkInt16(0x0010, "Unexpected type spec header size");
/* int size = */ int chunkSize = is.readInt32();
is.readInt32(); long expectedEndPos = chunkStart + chunkSize;
int id = is.readInt8(); int id = is.readInt8();
is.skip(3); is.skip(3);
...@@ -203,6 +218,28 @@ public class ResTableParser extends CommonBinaryParser implements IResParser { ...@@ -203,6 +218,28 @@ public class ResTableParser extends CommonBinaryParser implements IResParser {
for (int i = 0; i < entryCount; i++) { for (int i = 0; i < entryCount; i++) {
int entryFlag = is.readInt32(); 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 { private void parseTypeChunk(long start, PackageChunk pkg) throws IOException {
...@@ -241,6 +278,13 @@ public class ResTableParser extends CommonBinaryParser implements IResParser { ...@@ -241,6 +278,13 @@ public class ResTableParser extends CommonBinaryParser implements IResParser {
parseEntry(pkg, id, i, config.getQualifiers()); 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 { private void parseEntry(PackageChunk pkg, int typeId, int entryId, String config) throws IOException {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册