Use temporary files to process zips

Fix #96
This commit is contained in:
topjohnwu 2017-02-15 23:43:30 +08:00
parent 21b11f1b48
commit d1c939f48a
5 changed files with 904 additions and 552 deletions

View File

@ -12,6 +12,10 @@ import com.topjohnwu.magisk.utils.Shell;
import com.topjohnwu.magisk.utils.Utils; import com.topjohnwu.magisk.utils.Utils;
import com.topjohnwu.magisk.utils.ZipUtils; import com.topjohnwu.magisk.utils.ZipUtils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream; import java.io.OutputStream;
public class ProcessRepoZip extends ParallelTask<Void, Void, Boolean> { public class ProcessRepoZip extends ParallelTask<Void, Void, Boolean> {
@ -33,26 +37,59 @@ public class ProcessRepoZip extends ParallelTask<Void, Void, Boolean> {
@Override @Override
protected Boolean doInBackground(Void... params) { protected Boolean doInBackground(Void... params) {
// Create a buffer in memory for input/output
ByteArrayInOutStream buffer = new ByteArrayInOutStream(); FileInputStream in;
FileOutputStream out;
try { try {
// First remove top folder (the folder with the repo name) in Github source zip
ZipUtils.removeTopFolder(activity.getContentResolver().openInputStream(mUri), buffer);
// Then sign the zip for the first time // Create temp file
ZipUtils.signZip(activity, buffer.getInputStream(), buffer, false); File temp1 = new File(magiskManager.getCacheDir(), "1.zip");
File temp2 = new File(magiskManager.getCacheDir(), "2.zip");
// Adjust the zip to prevent unzip issues if (magiskManager.getCacheDir().mkdirs()) {
ZipUtils.adjustZip(buffer); temp1.createNewFile();
temp2.createNewFile();
// Finally, sign the whole zip file again
ZipUtils.signZip(activity, buffer.getInputStream(), buffer, true);
// Write it back to the downloaded zip
try (OutputStream out = activity.getContentResolver().openOutputStream(mUri)) {
buffer.writeTo(out);
} }
out = new FileOutputStream(temp1);
// First remove top folder in Github source zip, Uri -> temp1
ZipUtils.removeTopFolder(activity.getContentResolver().openInputStream(mUri), out);
out.flush();
out.close();
out = new FileOutputStream(temp2);
// Then sign the zip for the first time, temp1 -> temp2
ZipUtils.signZip(activity, temp1, out, false);
out.flush();
out.close();
// Adjust the zip to prevent unzip issues, temp2 -> temp2
ZipUtils.adjustZip(temp2);
out = new FileOutputStream(temp1);
// Finally, sign the whole zip file again, temp2 -> temp1
ZipUtils.signZip(activity, temp2, out, true);
out.flush();
out.close();
in = new FileInputStream(temp1);
// Write it back to the downloaded zip, temp1 -> Uri
try (OutputStream target = activity.getContentResolver().openOutputStream(mUri)) {
byte[] buffer = new byte[4096];
int length;
if (target == null) throw new FileNotFoundException();
while ((length = in.read(buffer)) > 0)
target.write(buffer, 0, length);
}
// Delete the temp file
temp1.delete();
temp2.delete();
return true; return true;
} catch (Exception e) { } catch (Exception e) {
Logger.error("ProcessRepoZip: Error!"); Logger.error("ProcessRepoZip: Error!");

File diff suppressed because it is too large Load Diff

View File

@ -4,10 +4,15 @@
#include <jni.h> #include <jni.h>
#include <stdlib.h> #include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "zipadjust.h" #include "zipadjust.h"
JNIEXPORT jbyteArray JNICALL JNIEXPORT jbyteArray JNICALL
Java_com_topjohnwu_magisk_utils_ZipUtils_zipAdjust(JNIEnv *env, jclass type, jbyteArray jbytes, jint size) { Java_com_topjohnwu_magisk_utils_ZipUtils_zipAdjust___3BI(JNIEnv *env, jclass type,
jbyteArray jbytes, jint size) {
fin = (*env)->GetPrimitiveArrayCritical(env, jbytes, NULL); fin = (*env)->GetPrimitiveArrayCritical(env, jbytes, NULL);
insize = (size_t) size; insize = (size_t) size;
@ -21,3 +26,37 @@ Java_com_topjohnwu_magisk_utils_ZipUtils_zipAdjust(JNIEnv *env, jclass type, jby
return ret; return ret;
} }
JNIEXPORT void JNICALL
Java_com_topjohnwu_magisk_utils_ZipUtils_zipAdjust__Ljava_lang_String_2(JNIEnv *env, jclass type, jstring name) {
const char *filename = (*env)->GetStringUTFChars(env, name, NULL);
int fd = open(filename, O_RDONLY);
if (fd < 0)
return;
// Load the file to memory
insize = lseek(fd, 0, SEEK_END);
lseek(fd, 0, SEEK_SET);
fin = malloc(insize);
read(fd, fin, insize);
zipadjust(0);
close(fd);
// Open file for output
fd = open(filename, O_WRONLY | O_TRUNC);
if (fd < 0)
return;
(*env)->ReleaseStringUTFChars(env, name, filename);
// Write back to file
lseek(fd, 0, SEEK_SET);
write(fd, fout, outsize);
close(fd);
free(fin);
free(fout);
}

View File

@ -1,14 +1,8 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <zlib.h> #include <zlib.h>
#include <android/log.h>
#include "zipadjust.h" #include "zipadjust.h"
#define LOG_TAG "zipadjust"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
size_t insize = 0, outsize = 0, alloc = 0; size_t insize = 0, outsize = 0, alloc = 0;
unsigned char *fin = NULL, *fout = NULL; unsigned char *fin = NULL, *fout = NULL;

View File

@ -1,9 +1,16 @@
#ifndef MAGISKMANAGER_ZIPADJUST_H_H #ifndef MAGISKMANAGER_ZIPADJUST_H_H
#define MAGISKMANAGER_ZIPADJUST_H_H #define MAGISKMANAGER_ZIPADJUST_H_H
#include <android/log.h>
int zipadjust(int decompress); int zipadjust(int decompress);
extern size_t insize, outsize, alloc; extern size_t insize, outsize, alloc;
extern unsigned char *fin, *fout; extern unsigned char *fin, *fout;
#define LOG_TAG "zipadjust"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
#endif //MAGISKMANAGER_ZIPADJUST_H_H #endif //MAGISKMANAGER_ZIPADJUST_H_H