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> { 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; private List<String> entryNames;
protected AbstractMultiDexContainer() {} 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 (entryMap == null) throw new NullPointerException("entryMap");
if (this.entryMap != null) throw new IllegalStateException("Already initialized"); if (this.entryMap != null) throw new IllegalStateException("Already initialized");
this.entryMap = entryMap; this.entryMap = entryMap;
@ -39,7 +39,7 @@ public abstract class AbstractMultiDexContainer<T extends DexFile> implements Mu
} }
@Override @Override
public T getEntry(String entryName) { public DexEntry<T> getEntry(String entryName) {
return entryMap.get(entryName); return entryMap.get(entryName);
} }

View File

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

View File

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

View File

@ -30,35 +30,32 @@ public class MultiDexIO {
public static DexFile readDexFile(boolean multiDex, File file, DexFileNamer namer, Opcodes opcodes, public static DexFile readDexFile(boolean multiDex, File file, DexFileNamer namer, Opcodes opcodes,
DexIO.Logger logger) throws IOException { DexIO.Logger logger) throws IOException {
MultiDexContainer<WrappingMultiDexFile<DexBackedDexFile>> container = MultiDexContainer<DexBackedDexFile> container = readMultiDexContainer(multiDex, file, namer, opcodes, logger);
readMultiDexContainer(multiDex, file, namer, opcodes, logger);
return new MultiDexContainerBackedDexFile<>(container); return new MultiDexContainerBackedDexFile<>(container);
} }
public static MultiDexContainer<WrappingMultiDexFile<DexBackedDexFile>> readMultiDexContainer(boolean multiDex, public static MultiDexContainer<DexBackedDexFile> readMultiDexContainer(boolean multiDex, File file,
File file, DexFileNamer namer, Opcodes opcodes, DexIO.Logger logger) throws IOException { DexFileNamer namer, Opcodes opcodes, DexIO.Logger logger) throws IOException {
MultiDexContainer<WrappingMultiDexFile<DexBackedDexFile>> container = MultiDexContainer<DexBackedDexFile> container = readMultiDexContainer(file, namer, opcodes, logger);
readMultiDexContainer(file, namer, opcodes, logger);
int entries = container.getDexEntryNames().size(); int entries = container.getDexEntryNames().size();
if (entries == 0) throw new EmptyMultiDexContainerException(file.toString()); if (entries == 0) throw new EmptyMultiDexContainerException(file.toString());
if (!multiDex && entries > 1) throw new MultiDexDetectedException(file.toString()); if (!multiDex && entries > 1) throw new MultiDexDetectedException(file.toString());
return container; return container;
} }
public static MultiDexContainer<WrappingMultiDexFile<DexBackedDexFile>> readMultiDexContainer(File file, public static MultiDexContainer<DexBackedDexFile> readMultiDexContainer(File file, DexFileNamer namer,
DexFileNamer namer, Opcodes opcodes, DexIO.Logger logger) throws IOException { Opcodes opcodes, DexIO.Logger logger) throws IOException {
MultiDexContainer<WrappingMultiDexFile<DexBackedDexFile>> container = MultiDexContainer<DexBackedDexFile> container = readMultiDexContainer(file, namer, opcodes);
readMultiDexContainer(file, namer, opcodes);
if (logger != null) { if (logger != null) {
for (String name : container.getDexEntryNames()) { 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; return container;
} }
public static MultiDexContainer<WrappingMultiDexFile<DexBackedDexFile>> readMultiDexContainer(File file, public static MultiDexContainer<DexBackedDexFile> readMultiDexContainer(File file, DexFileNamer namer,
DexFileNamer namer, Opcodes opcodes) throws IOException { Opcodes opcodes) throws IOException {
if (file.isDirectory()) return new DirectoryDexContainer(file, namer, opcodes); if (file.isDirectory()) return new DirectoryDexContainer(file, namer, opcodes);
if (!file.isFile()) throw new FileNotFoundException(file.toString()); if (!file.isFile()) throw new FileNotFoundException(file.toString());
if (ZipFileDexContainer.isZipFile(file)) return new ZipFileDexContainer(file, namer, opcodes); 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; 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 // I insist that some dex container entries do not have names
// even though dexlib2 does not allow null entry 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) { public SingletonDexContainer(String entryName, T dexFile) {
WrappingMultiDexFile<T> multiDexFile = new BasicMultiDexFile<>(this, entryName, dexFile); DexEntry<T> entry = new BasicDexEntry<>(this, entryName, dexFile);
Map<String, WrappingMultiDexFile<T>> entryMap = Collections.singletonMap(entryName, multiDexFile); Map<String, DexEntry<T>> entryMap = Collections.singletonMap(entryName, entry);
initialize(entryMap); initialize(entryMap);
} }

View File

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