Trickle the 'WrappingMultiDexFile' to 'DexEntry' change

This commit is contained in:
Lanchon 2019-10-24 21:45:39 -03:00
parent f24abb66b8
commit 14b5795926
6 changed files with 30 additions and 34 deletions

View File

@ -20,12 +20,12 @@ import org.jf.dexlib2.iface.MultiDexContainer;
public abstract class AbstractMultiDexContainer<T extends DexFile> implements MultiDexContainer<T> {
private Map<String, T> entryMap;
private Map<String, DexEntry<T>> entryMap;
private List<String> entryNames;
protected AbstractMultiDexContainer() {}
protected void initialize(Map<String, T> entryMap) {
protected void initialize(Map<String, DexEntry<T>> entryMap) {
if (entryMap == null) throw new NullPointerException("entryMap");
if (this.entryMap != null) throw new IllegalStateException("Already initialized");
this.entryMap = entryMap;
@ -39,7 +39,7 @@ public abstract class AbstractMultiDexContainer<T extends DexFile> implements Mu
}
@Override
public T getEntry(String entryName) {
public DexEntry<T> getEntry(String entryName) {
return entryMap.get(entryName);
}

View File

@ -18,18 +18,18 @@ import java.util.TreeMap;
import org.jf.dexlib2.Opcodes;
import org.jf.dexlib2.dexbacked.DexBackedDexFile;
public class DirectoryDexContainer extends AbstractMultiDexContainer<WrappingMultiDexFile<DexBackedDexFile>> {
public class DirectoryDexContainer extends AbstractMultiDexContainer<DexBackedDexFile> {
public DirectoryDexContainer(File directory, DexFileNamer namer, Opcodes opcodes) throws IOException {
Map<String, WrappingMultiDexFile<DexBackedDexFile>> entryMap = new TreeMap<>(new DexFileNameComparator(namer));
Map<String, DexEntry<DexBackedDexFile>> entryMap = new TreeMap<>(new DexFileNameComparator(namer));
String[] names = directory.list();
if (names == null) throw new IOException("Cannot access directory: " + directory);
for (String entryName : names) {
File file = new File(directory, entryName);
if (file.isFile() && namer.isValidName(entryName)) {
DexBackedDexFile dexFile = RawDexIO.readRawDexFile(file, opcodes);
WrappingMultiDexFile<DexBackedDexFile> multiDexFile = new BasicMultiDexFile<>(this, entryName, dexFile);
if (entryMap.put(entryName, multiDexFile) != null) throw duplicateEntryName(entryName);
DexEntry<DexBackedDexFile> entry = new BasicDexEntry<>(this, entryName, dexFile);
if (entryMap.put(entryName, entry) != null) throw duplicateEntryName(entryName);
}
}
initialize(entryMap);

View File

@ -30,18 +30,18 @@ public class MultiDexContainerBackedDexFile<T extends DexFile> implements DexFil
List<String> entryNames = container.getDexEntryNames();
if (entryNames.size() == 1) {
String entryName = entryNames.get(0);
T entry = container.getEntry(entryName);
classes = Collections.unmodifiableSet(entry.getClasses());
opcodes = entry.getOpcodes();
T entryDex = container.getEntry(entryName).getDexFile();
classes = Collections.unmodifiableSet(entryDex.getClasses());
opcodes = entryDex.getOpcodes();
} else {
LinkedHashSet<ClassDef> accumulatedClasses = new LinkedHashSet<>();
Opcodes resolvedOpcodes = null;
for (String entryName : entryNames) {
T entry = container.getEntry(entryName);
for (ClassDef entryClass : entry.getClasses()) {
T entryDex = container.getEntry(entryName).getDexFile();
for (ClassDef entryClass : entryDex.getClasses()) {
if (!accumulatedClasses.add(entryClass)) throw new DuplicateTypeException(entryClass.getType());
}
resolvedOpcodes = OpcodeUtils.getNewestOpcodes(resolvedOpcodes, entry.getOpcodes(), true);
resolvedOpcodes = OpcodeUtils.getNewestOpcodes(resolvedOpcodes, entryDex.getOpcodes(), true);
}
classes = Collections.unmodifiableSet(accumulatedClasses);
opcodes = resolvedOpcodes;

View File

@ -30,35 +30,32 @@ public class MultiDexIO {
public static DexFile readDexFile(boolean multiDex, File file, DexFileNamer namer, Opcodes opcodes,
DexIO.Logger logger) throws IOException {
MultiDexContainer<WrappingMultiDexFile<DexBackedDexFile>> container =
readMultiDexContainer(multiDex, file, namer, opcodes, logger);
MultiDexContainer<DexBackedDexFile> container = readMultiDexContainer(multiDex, file, namer, opcodes, logger);
return new MultiDexContainerBackedDexFile<>(container);
}
public static MultiDexContainer<WrappingMultiDexFile<DexBackedDexFile>> readMultiDexContainer(boolean multiDex,
File file, DexFileNamer namer, Opcodes opcodes, DexIO.Logger logger) throws IOException {
MultiDexContainer<WrappingMultiDexFile<DexBackedDexFile>> container =
readMultiDexContainer(file, namer, opcodes, logger);
public static MultiDexContainer<DexBackedDexFile> readMultiDexContainer(boolean multiDex, File file,
DexFileNamer namer, Opcodes opcodes, DexIO.Logger logger) throws IOException {
MultiDexContainer<DexBackedDexFile> container = readMultiDexContainer(file, namer, opcodes, logger);
int entries = container.getDexEntryNames().size();
if (entries == 0) throw new EmptyMultiDexContainerException(file.toString());
if (!multiDex && entries > 1) throw new MultiDexDetectedException(file.toString());
return container;
}
public static MultiDexContainer<WrappingMultiDexFile<DexBackedDexFile>> readMultiDexContainer(File file,
DexFileNamer namer, Opcodes opcodes, DexIO.Logger logger) throws IOException {
MultiDexContainer<WrappingMultiDexFile<DexBackedDexFile>> container =
readMultiDexContainer(file, namer, opcodes);
public static MultiDexContainer<DexBackedDexFile> readMultiDexContainer(File file, DexFileNamer namer,
Opcodes opcodes, DexIO.Logger logger) throws IOException {
MultiDexContainer<DexBackedDexFile> container = readMultiDexContainer(file, namer, opcodes);
if (logger != null) {
for (String name : container.getDexEntryNames()) {
logger.log(file, name, container.getEntry(name).getClasses().size());
logger.log(file, name, container.getEntry(name).getDexFile().getClasses().size());
}
}
return container;
}
public static MultiDexContainer<WrappingMultiDexFile<DexBackedDexFile>> readMultiDexContainer(File file,
DexFileNamer namer, Opcodes opcodes) throws IOException {
public static MultiDexContainer<DexBackedDexFile> readMultiDexContainer(File file, DexFileNamer namer,
Opcodes opcodes) throws IOException {
if (file.isDirectory()) return new DirectoryDexContainer(file, namer, opcodes);
if (!file.isFile()) throw new FileNotFoundException(file.toString());
if (ZipFileDexContainer.isZipFile(file)) return new ZipFileDexContainer(file, namer, opcodes);

View File

@ -15,7 +15,7 @@ import java.util.Map;
import org.jf.dexlib2.iface.DexFile;
public class SingletonDexContainer<T extends DexFile> extends AbstractMultiDexContainer<WrappingMultiDexFile<T>> {
public class SingletonDexContainer<T extends DexFile> extends AbstractMultiDexContainer<T> {
// I insist that some dex container entries do not have names
// even though dexlib2 does not allow null entry names.
@ -30,8 +30,8 @@ public class SingletonDexContainer<T extends DexFile> extends AbstractMultiDexCo
}
public SingletonDexContainer(String entryName, T dexFile) {
WrappingMultiDexFile<T> multiDexFile = new BasicMultiDexFile<>(this, entryName, dexFile);
Map<String, WrappingMultiDexFile<T>> entryMap = Collections.singletonMap(entryName, multiDexFile);
DexEntry<T> entry = new BasicDexEntry<>(this, entryName, dexFile);
Map<String, DexEntry<T>> entryMap = Collections.singletonMap(entryName, entry);
initialize(entryMap);
}

View File

@ -22,7 +22,7 @@ import java.util.zip.ZipFile;
import org.jf.dexlib2.Opcodes;
import org.jf.dexlib2.dexbacked.DexBackedDexFile;
public class ZipFileDexContainer extends AbstractMultiDexContainer<WrappingMultiDexFile<DexBackedDexFile>> {
public class ZipFileDexContainer extends AbstractMultiDexContainer<DexBackedDexFile> {
public static boolean isZipFile(File zip) {
if (!zip.isFile()) return false;
@ -36,7 +36,7 @@ public class ZipFileDexContainer extends AbstractMultiDexContainer<WrappingMulti
}
public ZipFileDexContainer(File zip, DexFileNamer namer, Opcodes opcodes) throws IOException {
Map<String, WrappingMultiDexFile<DexBackedDexFile>> entryMap = new TreeMap<>(new DexFileNameComparator(namer));
Map<String, DexEntry<DexBackedDexFile>> entryMap = new TreeMap<>(new DexFileNameComparator(namer));
try (ZipFile zipFile = new ZipFile(zip)) {
Enumeration<? extends ZipEntry> zipEntries = zipFile.entries();
while (zipEntries.hasMoreElements()) {
@ -47,9 +47,8 @@ public class ZipFileDexContainer extends AbstractMultiDexContainer<WrappingMulti
try (InputStream inputStream = zipFile.getInputStream(zipEntry)) {
dexFile = RawDexIO.readRawDexFile(inputStream, zipEntry.getSize(), opcodes);
}
WrappingMultiDexFile<DexBackedDexFile> multiDexFile =
new BasicMultiDexFile<>(this, entryName, dexFile);
if (entryMap.put(entryName, multiDexFile) != null) throw duplicateEntryName(entryName);
DexEntry<DexBackedDexFile> entry = new BasicDexEntry<>(this, entryName, dexFile);
if (entryMap.put(entryName, entry) != null) throw duplicateEntryName(entryName);
}
}
}