mirror of
https://github.com/revanced/smali.git
synced 2025-05-29 20:20:12 +02:00
Tweak ZipDexContainer so it doesn't keep an open ZipFile
This commit is contained in:
parent
ab20c37fd0
commit
dbd9db303a
@ -41,6 +41,7 @@ import org.jf.dexlib2.dexbacked.OatFile;
|
|||||||
import org.jf.dexlib2.dexbacked.OatFile.NotAnOatFileException;
|
import org.jf.dexlib2.dexbacked.OatFile.NotAnOatFileException;
|
||||||
import org.jf.dexlib2.dexbacked.OatFile.OatDexFile;
|
import org.jf.dexlib2.dexbacked.OatFile.OatDexFile;
|
||||||
import org.jf.dexlib2.dexbacked.ZipDexContainer;
|
import org.jf.dexlib2.dexbacked.ZipDexContainer;
|
||||||
|
import org.jf.dexlib2.dexbacked.ZipDexContainer.NotAZipFileException;
|
||||||
import org.jf.dexlib2.iface.DexFile;
|
import org.jf.dexlib2.iface.DexFile;
|
||||||
import org.jf.dexlib2.iface.MultiDexContainer;
|
import org.jf.dexlib2.iface.MultiDexContainer;
|
||||||
import org.jf.dexlib2.writer.pool.DexPool;
|
import org.jf.dexlib2.writer.pool.DexPool;
|
||||||
@ -50,7 +51,6 @@ import javax.annotation.Nonnull;
|
|||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.zip.ZipFile;
|
|
||||||
|
|
||||||
public final class DexFileFactory {
|
public final class DexFileFactory {
|
||||||
|
|
||||||
@ -81,21 +81,12 @@ public final class DexFileFactory {
|
|||||||
throw new DexFileNotFoundException("%s does not exist", file.getName());
|
throw new DexFileNotFoundException("%s does not exist", file.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
ZipFile zipFile = null;
|
|
||||||
try {
|
|
||||||
zipFile = new ZipFile(file);
|
|
||||||
} catch (IOException ex) {
|
|
||||||
// ignore and continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if (zipFile != null) {
|
try {
|
||||||
ZipDexContainer container = new ZipDexContainer(zipFile, opcodes);
|
ZipDexContainer container = new ZipDexContainer(file, opcodes);
|
||||||
try {
|
return new DexEntryFinder(file.getPath(), container).findEntry("classes.dex", true);
|
||||||
return new DexEntryFinder(file.getPath(), container)
|
} catch (NotAZipFileException ex) {
|
||||||
.findEntry("classes.dex", true);
|
// eat it and continue
|
||||||
} finally {
|
|
||||||
container.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
InputStream inputStream = new BufferedInputStream(new FileInputStream(file));
|
InputStream inputStream = new BufferedInputStream(new FileInputStream(file));
|
||||||
@ -188,20 +179,11 @@ public final class DexFileFactory {
|
|||||||
throw new DexFileNotFoundException("Container file %s does not exist", file.getName());
|
throw new DexFileNotFoundException("Container file %s does not exist", file.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
ZipFile zipFile = null;
|
|
||||||
try {
|
try {
|
||||||
zipFile = new ZipFile(file);
|
ZipDexContainer container = new ZipDexContainer(file, opcodes);
|
||||||
} catch (IOException ex) {
|
return new DexEntryFinder(file.getPath(), container).findEntry(dexEntry, exactMatch);
|
||||||
// ignore and continue
|
} catch (NotAZipFileException ex) {
|
||||||
}
|
// eat it and continue
|
||||||
|
|
||||||
if (zipFile != null) {
|
|
||||||
ZipDexContainer container = new ZipDexContainer(zipFile, opcodes);
|
|
||||||
try {
|
|
||||||
return new DexEntryFinder(file.getPath(), container).findEntry(dexEntry, exactMatch);
|
|
||||||
} finally {
|
|
||||||
container.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
InputStream inputStream = new BufferedInputStream(new FileInputStream(file));
|
InputStream inputStream = new BufferedInputStream(new FileInputStream(file));
|
||||||
@ -251,15 +233,9 @@ public final class DexFileFactory {
|
|||||||
throw new DexFileNotFoundException("%s does not exist", file.getName());
|
throw new DexFileNotFoundException("%s does not exist", file.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
ZipFile zipFile = null;
|
ZipDexContainer zipDexContainer = new ZipDexContainer(file, opcodes);
|
||||||
try {
|
if (zipDexContainer.isZipFile()) {
|
||||||
zipFile = new ZipFile(file);
|
return zipDexContainer;
|
||||||
} catch (IOException ex) {
|
|
||||||
// ignore and continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if (zipFile != null) {
|
|
||||||
return new ZipDexContainer(zipFile, opcodes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
InputStream inputStream = new BufferedInputStream(new FileInputStream(file));
|
InputStream inputStream = new BufferedInputStream(new FileInputStream(file));
|
||||||
|
@ -40,8 +40,8 @@ import org.jf.dexlib2.iface.MultiDexContainer;
|
|||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.io.Closeable;
|
|
||||||
import java.io.EOFException;
|
import java.io.EOFException;
|
||||||
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
@ -54,19 +54,19 @@ import static org.jf.dexlib2.dexbacked.DexBackedDexFile.verifyMagicAndByteOrder;
|
|||||||
/**
|
/**
|
||||||
* Represents a zip file that contains dex files (i.e. an apk or jar file)
|
* Represents a zip file that contains dex files (i.e. an apk or jar file)
|
||||||
*/
|
*/
|
||||||
public class ZipDexContainer implements MultiDexContainer<ZipDexFile>, Closeable {
|
public class ZipDexContainer implements MultiDexContainer<ZipDexFile> {
|
||||||
|
|
||||||
private final ZipFile zipFile;
|
private final File zipFilePath;
|
||||||
private final Opcodes opcodes;
|
private final Opcodes opcodes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new ZipDexContainer for the given zip file
|
* Constructs a new ZipDexContainer for the given zip file
|
||||||
*
|
*
|
||||||
* @param zipFile A Zip
|
* @param zipFilePath The path to the zip file
|
||||||
* @param opcodes The Opcodes instance to use when loading dex files from this container
|
* @param opcodes The Opcodes instance to use when loading dex files from this container
|
||||||
*/
|
*/
|
||||||
public ZipDexContainer(@Nonnull ZipFile zipFile, @Nonnull Opcodes opcodes) {
|
public ZipDexContainer(@Nonnull File zipFilePath, @Nonnull Opcodes opcodes) {
|
||||||
this.zipFile = zipFile;
|
this.zipFilePath = zipFilePath;
|
||||||
this.opcodes = opcodes;
|
this.opcodes = opcodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,19 +77,24 @@ public class ZipDexContainer implements MultiDexContainer<ZipDexFile>, Closeable
|
|||||||
*/
|
*/
|
||||||
@Nonnull @Override public List<String> getDexEntryNames() throws IOException {
|
@Nonnull @Override public List<String> getDexEntryNames() throws IOException {
|
||||||
List<String> entryNames = Lists.newArrayList();
|
List<String> entryNames = Lists.newArrayList();
|
||||||
Enumeration<? extends ZipEntry> entriesEnumeration = zipFile.entries();
|
ZipFile zipFile = getZipFile();
|
||||||
|
try {
|
||||||
|
Enumeration<? extends ZipEntry> entriesEnumeration = zipFile.entries();
|
||||||
|
|
||||||
while (entriesEnumeration.hasMoreElements()) {
|
while (entriesEnumeration.hasMoreElements()) {
|
||||||
ZipEntry entry = entriesEnumeration.nextElement();
|
ZipEntry entry = entriesEnumeration.nextElement();
|
||||||
|
|
||||||
if (!isDex(entry)) {
|
if (!isDex(zipFile, entry)) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
entryNames.add(entry.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
entryNames.add(entry.getName());
|
return entryNames;
|
||||||
|
} finally {
|
||||||
|
zipFile.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
return entryNames;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -100,16 +105,28 @@ public class ZipDexContainer implements MultiDexContainer<ZipDexFile>, Closeable
|
|||||||
* @throws NotADexFile If the entry isn't a dex file
|
* @throws NotADexFile If the entry isn't a dex file
|
||||||
*/
|
*/
|
||||||
@Nullable @Override public ZipDexFile getEntry(@Nonnull String entryName) throws IOException {
|
@Nullable @Override public ZipDexFile getEntry(@Nonnull String entryName) throws IOException {
|
||||||
ZipEntry entry = zipFile.getEntry(entryName);
|
ZipFile zipFile = getZipFile();
|
||||||
if (entry == null) {
|
try {
|
||||||
return null;
|
ZipEntry entry = zipFile.getEntry(entryName);
|
||||||
}
|
if (entry == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return loadEntry(entry);
|
return loadEntry(zipFile, entry);
|
||||||
|
} finally {
|
||||||
|
zipFile.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void close() throws IOException {
|
public boolean isZipFile() {
|
||||||
zipFile.close();
|
try {
|
||||||
|
getZipFile();
|
||||||
|
return true;
|
||||||
|
} catch (IOException ex) {
|
||||||
|
return false;
|
||||||
|
} catch (NotAZipFileException ex) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ZipDexFile extends DexBackedDexFile implements MultiDexContainer.MultiDexFile {
|
public class ZipDexFile extends DexBackedDexFile implements MultiDexContainer.MultiDexFile {
|
||||||
@ -130,7 +147,7 @@ public class ZipDexContainer implements MultiDexContainer<ZipDexFile>, Closeable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isDex(@Nonnull ZipEntry zipEntry) throws IOException {
|
private boolean isDex(@Nonnull ZipFile zipFile, @Nonnull ZipEntry zipEntry) throws IOException {
|
||||||
InputStream inputStream = zipFile.getInputStream(zipEntry);
|
InputStream inputStream = zipFile.getInputStream(zipEntry);
|
||||||
try {
|
try {
|
||||||
inputStream.mark(44);
|
inputStream.mark(44);
|
||||||
@ -138,7 +155,7 @@ public class ZipDexContainer implements MultiDexContainer<ZipDexFile>, Closeable
|
|||||||
try {
|
try {
|
||||||
ByteStreams.readFully(inputStream, partialHeader);
|
ByteStreams.readFully(inputStream, partialHeader);
|
||||||
} catch (EOFException ex) {
|
} catch (EOFException ex) {
|
||||||
throw new NotADexFile("File is too short");
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -152,9 +169,16 @@ public class ZipDexContainer implements MultiDexContainer<ZipDexFile>, Closeable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ZipFile getZipFile() throws IOException {
|
||||||
|
try {
|
||||||
|
return new ZipFile(zipFilePath);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
throw new NotAZipFileException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
private ZipDexFile loadEntry(@Nonnull ZipEntry zipEntry)
|
private ZipDexFile loadEntry(@Nonnull ZipFile zipFile, @Nonnull ZipEntry zipEntry) throws IOException {
|
||||||
throws IOException {
|
|
||||||
InputStream inputStream = zipFile.getInputStream(zipEntry);
|
InputStream inputStream = zipFile.getInputStream(zipEntry);
|
||||||
try {
|
try {
|
||||||
byte[] buf = ByteStreams.toByteArray(inputStream);
|
byte[] buf = ByteStreams.toByteArray(inputStream);
|
||||||
@ -163,4 +187,7 @@ public class ZipDexContainer implements MultiDexContainer<ZipDexFile>, Closeable
|
|||||||
inputStream.close();
|
inputStream.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class NotAZipFileException extends RuntimeException {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user