Search in sources :

Example 71 with ZipEntry

use of java.util.zip.ZipEntry in project tinker by Tencent.

the class DexDiffPatchInternal method extractDexToJar.

/**
     * repack dex to jar
     *
     * @param zipFile
     * @param entryFile
     * @param extractTo
     * @param targetMd5
     * @return boolean
     * @throws IOException
     */
private static boolean extractDexToJar(ZipFile zipFile, ZipEntry entryFile, File extractTo, String targetMd5) throws IOException {
    int numAttempts = 0;
    boolean isExtractionSuccessful = false;
    while (numAttempts < MAX_EXTRACT_ATTEMPTS && !isExtractionSuccessful) {
        numAttempts++;
        FileOutputStream fos = new FileOutputStream(extractTo);
        InputStream in = zipFile.getInputStream(entryFile);
        ZipOutputStream zos = null;
        BufferedInputStream bis = null;
        TinkerLog.i(TAG, "try Extracting " + extractTo.getPath());
        try {
            zos = new ZipOutputStream(new BufferedOutputStream(fos));
            bis = new BufferedInputStream(in);
            byte[] buffer = new byte[ShareConstants.BUFFER_SIZE];
            ZipEntry entry = new ZipEntry(ShareConstants.DEX_IN_JAR);
            zos.putNextEntry(entry);
            int length = bis.read(buffer);
            while (length != -1) {
                zos.write(buffer, 0, length);
                length = bis.read(buffer);
            }
            zos.closeEntry();
        } finally {
            SharePatchFileUtil.closeQuietly(bis);
            SharePatchFileUtil.closeQuietly(zos);
        }
        isExtractionSuccessful = SharePatchFileUtil.verifyDexFileMd5(extractTo, targetMd5);
        TinkerLog.i(TAG, "isExtractionSuccessful: %b", isExtractionSuccessful);
        if (!isExtractionSuccessful) {
            extractTo.delete();
            if (extractTo.exists()) {
                TinkerLog.e(TAG, "Failed to delete corrupted dex " + extractTo.getPath());
            }
        }
    }
    return isExtractionSuccessful;
}
Also used : BufferedInputStream(java.io.BufferedInputStream) BufferedInputStream(java.io.BufferedInputStream) ZipInputStream(java.util.zip.ZipInputStream) InputStream(java.io.InputStream) ZipOutputStream(java.util.zip.ZipOutputStream) FileOutputStream(java.io.FileOutputStream) ZipEntry(java.util.zip.ZipEntry) BufferedOutputStream(java.io.BufferedOutputStream)

Example 72 with ZipEntry

use of java.util.zip.ZipEntry in project tinker by Tencent.

the class ResDiffPatchInternal method checkAndExtractResourceLargeFile.

private static boolean checkAndExtractResourceLargeFile(Context context, String apkPath, File directory, File patchFile, ShareResPatchInfo resPatchInfo, int type) {
    long start = System.currentTimeMillis();
    Tinker manager = Tinker.with(context);
    ZipFile apkFile = null;
    ZipFile patchZipFile = null;
    try {
        //recover resources.arsc first
        apkFile = new ZipFile(apkPath);
        ZipEntry arscEntry = apkFile.getEntry(ShareConstants.RES_ARSC);
        File arscFile = new File(directory, ShareConstants.RES_ARSC);
        if (arscEntry == null) {
            TinkerLog.w(TAG, "resources apk entry is null. path:" + ShareConstants.RES_ARSC);
            manager.getPatchReporter().onPatchTypeExtractFail(patchFile, arscFile, ShareConstants.RES_ARSC, type);
            return false;
        }
        //use base resources.arsc crc to identify base.apk
        String baseArscCrc = String.valueOf(arscEntry.getCrc());
        if (!baseArscCrc.equals(resPatchInfo.arscBaseCrc)) {
            TinkerLog.e(TAG, "resources.arsc's crc is not equal, expect crc: %s, got crc: %s", resPatchInfo.arscBaseCrc, baseArscCrc);
            manager.getPatchReporter().onPatchTypeExtractFail(patchFile, arscFile, ShareConstants.RES_ARSC, type);
            return false;
        }
        //resource arsc is not changed, just return true
        if (resPatchInfo.largeModRes.isEmpty()) {
            TinkerLog.i(TAG, "no large modify resources, just return");
            return true;
        }
        for (String name : resPatchInfo.largeModRes) {
            long largeStart = System.currentTimeMillis();
            ShareResPatchInfo.LargeModeInfo largeModeInfo = resPatchInfo.largeModMap.get(name);
            if (largeModeInfo == null) {
                TinkerLog.w(TAG, "resource not found largeModeInfo, type:%s, name: %s", ShareTinkerInternals.getTypeString(type), name);
                manager.getPatchReporter().onPatchPackageCheckFail(patchFile, BasePatchInternal.getMetaCorruptedCode(type));
                return false;
            }
            largeModeInfo.file = new File(directory, name);
            SharePatchFileUtil.ensureFileDirectory(largeModeInfo.file);
            //we do not check the intermediate files' md5 to save time, use check whether it is 32 length
            if (!SharePatchFileUtil.checkIfMd5Valid(largeModeInfo.md5)) {
                TinkerLog.w(TAG, "resource meta file md5 mismatch, type:%s, name: %s, md5: %s", ShareTinkerInternals.getTypeString(type), name, largeModeInfo.md5);
                manager.getPatchReporter().onPatchPackageCheckFail(patchFile, BasePatchInternal.getMetaCorruptedCode(type));
                return false;
            }
            patchZipFile = new ZipFile(patchFile);
            ZipEntry patchEntry = patchZipFile.getEntry(name);
            if (patchEntry == null) {
                TinkerLog.w(TAG, "large mod patch entry is null. path:" + name);
                manager.getPatchReporter().onPatchTypeExtractFail(patchFile, largeModeInfo.file, name, type);
                return false;
            }
            ZipEntry baseEntry = apkFile.getEntry(name);
            if (baseEntry == null) {
                TinkerLog.w(TAG, "resources apk entry is null. path:" + name);
                manager.getPatchReporter().onPatchTypeExtractFail(patchFile, largeModeInfo.file, name, type);
                return false;
            }
            InputStream oldStream = null;
            InputStream newStream = null;
            try {
                oldStream = apkFile.getInputStream(baseEntry);
                newStream = patchZipFile.getInputStream(patchEntry);
                BSPatch.patchFast(oldStream, newStream, largeModeInfo.file);
            } finally {
                SharePatchFileUtil.closeQuietly(oldStream);
                SharePatchFileUtil.closeQuietly(newStream);
            }
            //go go go bsdiff get the
            if (!SharePatchFileUtil.verifyFileMd5(largeModeInfo.file, largeModeInfo.md5)) {
                TinkerLog.w(TAG, "Failed to recover large modify file:%s", largeModeInfo.file.getPath());
                SharePatchFileUtil.safeDeleteFile(largeModeInfo.file);
                manager.getPatchReporter().onPatchTypeExtractFail(patchFile, largeModeInfo.file, name, type);
                return false;
            }
            TinkerLog.w(TAG, "success recover large modify file:%s, file size:%d, use time:%d", largeModeInfo.file.getPath(), largeModeInfo.file.length(), (System.currentTimeMillis() - largeStart));
        }
        TinkerLog.w(TAG, "success recover all large modify use time:%d", (System.currentTimeMillis() - start));
    } catch (Throwable e) {
        //            e.printStackTrace();
        throw new TinkerRuntimeException("patch " + ShareTinkerInternals.getTypeString(type) + " extract failed (" + e.getMessage() + ").", e);
    } finally {
        SharePatchFileUtil.closeZip(apkFile);
        SharePatchFileUtil.closeZip(patchZipFile);
    }
    return true;
}
Also used : TinkerRuntimeException(com.tencent.tinker.loader.TinkerRuntimeException) TinkerZipFile(com.tencent.tinker.commons.ziputil.TinkerZipFile) ZipFile(java.util.zip.ZipFile) ShareResPatchInfo(com.tencent.tinker.loader.shareutil.ShareResPatchInfo) InputStream(java.io.InputStream) TinkerZipEntry(com.tencent.tinker.commons.ziputil.TinkerZipEntry) ZipEntry(java.util.zip.ZipEntry) Tinker(com.tencent.tinker.lib.tinker.Tinker) TinkerZipFile(com.tencent.tinker.commons.ziputil.TinkerZipFile) File(java.io.File) ZipFile(java.util.zip.ZipFile)

Example 73 with ZipEntry

use of java.util.zip.ZipEntry in project tinker by Tencent.

the class SharePatchFileUtil method verifyDexFileMd5.

/**
     * Returns whether the dex file is a valid file.
     * dex may wrap with jar
     */
public static boolean verifyDexFileMd5(File file, String md5) {
    if (file == null || md5 == null) {
        return false;
    }
    //if it is not the raw dex, we check the stream instead
    String fileMd5;
    if (isRawDexFile(file.getName())) {
        fileMd5 = getMD5(file);
    } else {
        ZipFile dexJar = null;
        try {
            dexJar = new ZipFile(file);
            ZipEntry classesDex = dexJar.getEntry(ShareConstants.DEX_IN_JAR);
            // no code
            if (null == classesDex) {
                Log.e(TAG, "There's no entry named: " + ShareConstants.DEX_IN_JAR + " in " + file.getAbsolutePath());
                return false;
            }
            fileMd5 = getMD5(dexJar.getInputStream(classesDex));
        } catch (Throwable e) {
            Log.e(TAG, "Bad dex jar file: " + file.getAbsolutePath(), e);
            return false;
        } finally {
            // SharePatchFileUtil.closeZip(dexJar);
            if (dexJar != null) {
                try {
                    dexJar.close();
                } catch (Throwable thr) {
                // Ignored.
                }
            }
        }
    }
    return md5.equals(fileMd5);
}
Also used : ZipFile(java.util.zip.ZipFile) ZipEntry(java.util.zip.ZipEntry)

Example 74 with ZipEntry

use of java.util.zip.ZipEntry in project tinker by Tencent.

the class SharePatchFileUtil method checkResourceArscMd5.

public static boolean checkResourceArscMd5(File resOutput, String destMd5) {
    ZipFile resourceZip = null;
    try {
        resourceZip = new ZipFile(resOutput);
        ZipEntry arscEntry = resourceZip.getEntry(ShareConstants.RES_ARSC);
        if (arscEntry == null) {
            Log.i(TAG, "checkResourceArscMd5 resources.arsc not found");
            return false;
        }
        InputStream inputStream = null;
        try {
            inputStream = resourceZip.getInputStream(arscEntry);
            String md5 = SharePatchFileUtil.getMD5(inputStream);
            if (md5 != null && md5.equals(destMd5)) {
                return true;
            }
        } finally {
            SharePatchFileUtil.closeQuietly(inputStream);
        }
    } catch (Throwable e) {
        Log.i(TAG, "checkResourceArscMd5 throwable:" + e.getMessage());
    } finally {
        SharePatchFileUtil.closeZip(resourceZip);
    }
    return false;
}
Also used : ZipFile(java.util.zip.ZipFile) BufferedInputStream(java.io.BufferedInputStream) FileInputStream(java.io.FileInputStream) InputStream(java.io.InputStream) ZipEntry(java.util.zip.ZipEntry)

Example 75 with ZipEntry

use of java.util.zip.ZipEntry in project tinker by Tencent.

the class FileUtil method differZip.

/**
     * differ zip
     *
     * @param differentOutputFullFilename
     * @param oldZipFullFilename
     * @param newZipFullFilename
     */
public static void differZip(String differentOutputFullFilename, String oldZipFullFilename, String newZipFullFilename) {
    Map<String, String> map = getZipEntryHashMap(oldZipFullFilename);
    ZipFile newZipFile = null;
    ZipOutputStream zipOutputStream = null;
    try {
        newZipFile = new ZipFile(newZipFullFilename);
        Enumeration<? extends ZipEntry> entries = newZipFile.entries();
        FileUtil.createFile(differentOutputFullFilename);
        zipOutputStream = new ZipOutputStream(new FileOutputStream(differentOutputFullFilename));
        while (entries.hasMoreElements()) {
            ZipEntry zipEntry = entries.nextElement();
            if (!zipEntry.isDirectory()) {
                String zipEntryName = zipEntry.getName();
                String oldZipEntryHash = map.get(zipEntryName);
                String newZipEntryHash = zipEntry.getCrc() + Constant.Symbol.DOT + zipEntry.getSize();
                // is a modified zip entry
                if (oldZipEntryHash == null || (!newZipEntryHash.equals(oldZipEntryHash))) {
                    System.out.println(String.format("found modified entry, key=%s(%s/%s)", new Object[] { zipEntryName, oldZipEntryHash, newZipEntryHash }));
                    addZipEntry(zipOutputStream, zipEntry, newZipFile.getInputStream(zipEntry));
                }
            }
        }
    } catch (Exception e) {
        throw new FileUtilException(e);
    } finally {
        if (newZipFile != null) {
            try {
                newZipFile.close();
            } catch (IOException e) {
                throw new FileUtilException(e);
            }
        }
        if (zipOutputStream != null) {
            try {
                zipOutputStream.finish();
            } catch (IOException e) {
                throw new FileUtilException(e);
            }
        }
    }
}
Also used : ZipFile(java.util.zip.ZipFile) ZipOutputStream(java.util.zip.ZipOutputStream) FileOutputStream(java.io.FileOutputStream) ZipEntry(java.util.zip.ZipEntry) IOException(java.io.IOException) ZipException(java.util.zip.ZipException) IOException(java.io.IOException) FileNotFoundException(java.io.FileNotFoundException)

Aggregations

ZipEntry (java.util.zip.ZipEntry)1367 ZipFile (java.util.zip.ZipFile)479 File (java.io.File)469 IOException (java.io.IOException)361 ZipOutputStream (java.util.zip.ZipOutputStream)321 ZipInputStream (java.util.zip.ZipInputStream)300 InputStream (java.io.InputStream)282 FileOutputStream (java.io.FileOutputStream)278 FileInputStream (java.io.FileInputStream)270 Test (org.junit.Test)124 BufferedInputStream (java.io.BufferedInputStream)122 JarFile (java.util.jar.JarFile)122 BufferedOutputStream (java.io.BufferedOutputStream)99 ByteArrayOutputStream (java.io.ByteArrayOutputStream)97 ArrayList (java.util.ArrayList)84 ByteArrayInputStream (java.io.ByteArrayInputStream)78 OutputStream (java.io.OutputStream)67 JarOutputStream (java.util.jar.JarOutputStream)59 Path (java.nio.file.Path)56 Enumeration (java.util.Enumeration)56