mirror of
https://github.com/skylot/jadx.git
synced 2024-11-23 04:39:46 +00:00
fix(res): allow jumping backwards to an already processed position (PR #2344)
Use buffered stream to allow going backwards in stream in case the type chunk entries are not ordered properly (see #2343).
This commit is contained in:
parent
1e1036c049
commit
fe9d3bcab7
@ -1,6 +1,5 @@
|
|||||||
package jadx.cli.tools;
|
package jadx.cli.tools;
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
@ -71,7 +70,7 @@ public class ConvertArscFile {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Load resources.arsc from extracted file
|
// Load resources.arsc from extracted file
|
||||||
try (InputStream inputStream = new BufferedInputStream(Files.newInputStream(resFile))) {
|
try (InputStream inputStream = Files.newInputStream(resFile)) {
|
||||||
resTableParser.decode(inputStream);
|
resTableParser.decode(inputStream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ public class ParserStream {
|
|||||||
|
|
||||||
private final InputStream input;
|
private final InputStream input;
|
||||||
private long readPos = 0;
|
private long readPos = 0;
|
||||||
|
private long markPos = 0;
|
||||||
|
|
||||||
public ParserStream(@NotNull InputStream inputStream) {
|
public ParserStream(@NotNull InputStream inputStream) {
|
||||||
this.input = inputStream;
|
this.input = inputStream;
|
||||||
@ -143,10 +144,12 @@ public class ParserStream {
|
|||||||
throw new IOException("Mark not supported for input stream " + input.getClass());
|
throw new IOException("Mark not supported for input stream " + input.getClass());
|
||||||
}
|
}
|
||||||
input.mark(len);
|
input.mark(len);
|
||||||
|
markPos = readPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reset() throws IOException {
|
public void reset() throws IOException {
|
||||||
input.reset();
|
input.reset();
|
||||||
|
readPos = markPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void readFully(byte[] b) throws IOException {
|
public void readFully(byte[] b) throws IOException {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package jadx.core.xmlgen;
|
package jadx.core.xmlgen;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -79,7 +80,7 @@ public class ResTableBinaryParser extends CommonBinaryParser implements IResTabl
|
|||||||
@Override
|
@Override
|
||||||
public void decode(InputStream inputStream) throws IOException {
|
public void decode(InputStream inputStream) throws IOException {
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
is = new ParserStream(inputStream);
|
is = new ParserStream(new BufferedInputStream(inputStream, 32768));
|
||||||
resStorage = new ResourceStorage(root.getArgs().getSecurity());
|
resStorage = new ResourceStorage(root.getArgs().getSecurity());
|
||||||
decodeTableChunk();
|
decodeTableChunk();
|
||||||
resStorage.finish();
|
resStorage.finish();
|
||||||
@ -234,6 +235,7 @@ public class ResTableBinaryParser extends CommonBinaryParser implements IResTabl
|
|||||||
/* int size = */
|
/* int size = */
|
||||||
long chunkSize = is.readUInt32();
|
long chunkSize = is.readUInt32();
|
||||||
long chunkEnd = start + chunkSize;
|
long chunkEnd = start + chunkSize;
|
||||||
|
is.mark((int) chunkSize);
|
||||||
|
|
||||||
// The type identifier this chunk is holding. Type IDs start at 1 (corresponding
|
// 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.
|
// to the value of the type bits in a resource identifier). 0 is invalid.
|
||||||
@ -286,7 +288,12 @@ public class ResTableBinaryParser extends CommonBinaryParser implements IResTabl
|
|||||||
LOG.warn("End of chunk reached - ignoring remaining {} entries", entryCount - index);
|
LOG.warn("End of chunk reached - ignoring remaining {} entries", entryCount - index);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
is.checkPos(entriesStart + offset, "Expected start of entry " + index);
|
long entryStartOffset = entriesStart + offset;
|
||||||
|
if (entryStartOffset < is.getPos()) {
|
||||||
|
// workaround for issue #2343: if the entryStartOffset is located before our current position
|
||||||
|
is.reset();
|
||||||
|
}
|
||||||
|
is.skipToPos(entryStartOffset, "Expected start of entry " + index);
|
||||||
parseEntry(pkg, id, index, config.getQualifiers());
|
parseEntry(pkg, id, index, config.getQualifiers());
|
||||||
}
|
}
|
||||||
if (chunkEnd > is.getPos()) {
|
if (chunkEnd > is.getPos()) {
|
||||||
|
Loading…
Reference in New Issue
Block a user