Use zipfile
This commit is contained in:
parent
2a1915c50c
commit
13cf53974e
@ -19,15 +19,13 @@ import java.io.BufferedInputStream;
|
|||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Enumeration;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipEntry;
|
||||||
import java.util.zip.ZipInputStream;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
import okio.BufferedSink;
|
import okio.BufferedSink;
|
||||||
@ -138,19 +136,6 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
|
|||||||
|
|
||||||
private static native byte[] hdiffPatch(byte[] origin, byte[] patch);
|
private static native byte[] hdiffPatch(byte[] origin, byte[] patch);
|
||||||
|
|
||||||
private void unzipToFile(ZipInputStream zis, File fmd) throws IOException {
|
|
||||||
int count;
|
|
||||||
|
|
||||||
FileOutputStream fout = new FileOutputStream(fmd);
|
|
||||||
|
|
||||||
while ((count = zis.read(buffer)) != -1)
|
|
||||||
{
|
|
||||||
fout.write(buffer, 0, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
fout.close();
|
|
||||||
zis.closeEntry();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void copyFile(File from, File fmd) throws IOException {
|
private void copyFile(File from, File fmd) throws IOException {
|
||||||
int count;
|
int count;
|
||||||
@ -167,7 +152,7 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
|
|||||||
in.close();
|
in.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] readBytes(ZipInputStream zis) throws IOException {
|
private byte[] readBytes(InputStream zis) throws IOException {
|
||||||
int count;
|
int count;
|
||||||
|
|
||||||
ByteArrayOutputStream fout = new ByteArrayOutputStream();
|
ByteArrayOutputStream fout = new ByteArrayOutputStream();
|
||||||
@ -177,7 +162,7 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fout.close();
|
fout.close();
|
||||||
zis.closeEntry();
|
zis.close();
|
||||||
return fout.toByteArray();
|
return fout.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -246,15 +231,14 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
|
|||||||
private void doFullPatch(DownloadTaskParams param) throws IOException {
|
private void doFullPatch(DownloadTaskParams param) throws IOException {
|
||||||
downloadFile(param);
|
downloadFile(param);
|
||||||
|
|
||||||
ZipInputStream zis = new ZipInputStream(new BufferedInputStream(new FileInputStream(param.targetFile)));
|
|
||||||
ZipEntry ze;
|
|
||||||
String filename;
|
|
||||||
|
|
||||||
removeDirectory(param.unzipDirectory);
|
removeDirectory(param.unzipDirectory);
|
||||||
param.unzipDirectory.mkdirs();
|
param.unzipDirectory.mkdirs();
|
||||||
|
|
||||||
while ((ze = zis.getNextEntry()) != null)
|
SafeZipFile zipFile = new SafeZipFile(param.targetFile);
|
||||||
{
|
Enumeration<? extends ZipEntry> entries = zipFile.entries();
|
||||||
|
while (entries.hasMoreElements()) {
|
||||||
|
ZipEntry ze = entries.nextElement();
|
||||||
|
|
||||||
String fn = ze.getName();
|
String fn = ze.getName();
|
||||||
File fmd = new File(param.unzipDirectory, fn);
|
File fmd = new File(param.unzipDirectory, fn);
|
||||||
|
|
||||||
@ -267,10 +251,11 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
unzipToFile(zis, fmd);
|
zipFile.unzipToFile(ze, fmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
zis.close();
|
zipFile.close();
|
||||||
|
|
||||||
|
|
||||||
if (UpdateContext.DEBUG) {
|
if (UpdateContext.DEBUG) {
|
||||||
Log.d("RNUpdate", "Unzip finished");
|
Log.d("RNUpdate", "Unzip finished");
|
||||||
@ -278,9 +263,11 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void copyFromResource(HashMap<String, ArrayList<File> > resToCopy) throws IOException {
|
private void copyFromResource(HashMap<String, ArrayList<File> > resToCopy) throws IOException {
|
||||||
ZipInputStream zis = new ZipInputStream(new BufferedInputStream(new FileInputStream(context.getPackageResourcePath())));
|
SafeZipFile zipFile = new SafeZipFile(new File(context.getPackageResourcePath()));
|
||||||
ZipEntry ze;
|
Enumeration<? extends ZipEntry> entries = zipFile.entries();
|
||||||
while ((ze = zis.getNextEntry()) != null) {
|
while (entries.hasMoreElements()) {
|
||||||
|
ZipEntry ze = entries.nextElement();
|
||||||
|
|
||||||
String fn = ze.getName();
|
String fn = ze.getName();
|
||||||
ArrayList<File> targets = resToCopy.get(fn);
|
ArrayList<File> targets = resToCopy.get(fn);
|
||||||
if (targets != null) {
|
if (targets != null) {
|
||||||
@ -292,37 +279,35 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
|
|||||||
if (lastTarget != null) {
|
if (lastTarget != null) {
|
||||||
copyFile(lastTarget, target);
|
copyFile(lastTarget, target);
|
||||||
} else {
|
} else {
|
||||||
unzipToFile(zis, target);
|
zipFile.unzipToFile(ze, target);
|
||||||
lastTarget = target;
|
lastTarget = target;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
zipFile.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doPatchFromApk(DownloadTaskParams param) throws IOException, JSONException {
|
private void doPatchFromApk(DownloadTaskParams param) throws IOException, JSONException {
|
||||||
downloadFile(param);
|
downloadFile(param);
|
||||||
|
|
||||||
ZipInputStream zis = new ZipInputStream(new BufferedInputStream(new FileInputStream(param.targetFile)));
|
removeDirectory(param.unzipDirectory);
|
||||||
ZipEntry ze;
|
param.unzipDirectory.mkdirs();
|
||||||
int count;
|
HashMap<String, ArrayList<File>> copyList = new HashMap<String, ArrayList<File>>();
|
||||||
String filename;
|
|
||||||
boolean foundDiff = false;
|
boolean foundDiff = false;
|
||||||
boolean foundBundlePatch = false;
|
boolean foundBundlePatch = false;
|
||||||
|
|
||||||
removeDirectory(param.unzipDirectory);
|
SafeZipFile zipFile = new SafeZipFile(param.targetFile);
|
||||||
param.unzipDirectory.mkdirs();
|
Enumeration<? extends ZipEntry> entries = zipFile.entries();
|
||||||
|
while (entries.hasMoreElements()) {
|
||||||
HashMap<String, ArrayList<File>> copyList = new HashMap<String, ArrayList<File>>();
|
ZipEntry ze = entries.nextElement();
|
||||||
|
|
||||||
while ((ze = zis.getNextEntry()) != null)
|
|
||||||
{
|
|
||||||
String fn = ze.getName();
|
String fn = ze.getName();
|
||||||
|
|
||||||
if (fn.equals("__diff.json")) {
|
if (fn.equals("__diff.json")) {
|
||||||
foundDiff = true;
|
foundDiff = true;
|
||||||
// copy files from assets
|
// copy files from assets
|
||||||
byte[] bytes = readBytes(zis);
|
byte[] bytes = readBytes(zipFile.getInputStream(ze));
|
||||||
String json = new String(bytes, "UTF-8");
|
String json = new String(bytes, "UTF-8");
|
||||||
JSONObject obj = (JSONObject)new JSONTokener(json).nextValue();
|
JSONObject obj = (JSONObject)new JSONTokener(json).nextValue();
|
||||||
|
|
||||||
@ -349,7 +334,7 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
|
|||||||
if (fn.equals("index.bundlejs.patch")) {
|
if (fn.equals("index.bundlejs.patch")) {
|
||||||
foundBundlePatch = true;
|
foundBundlePatch = true;
|
||||||
|
|
||||||
byte[] patched = hdiffPatch(readOriginBundle(), readBytes(zis));
|
byte[] patched = hdiffPatch(readOriginBundle(), readBytes(zipFile.getInputStream(ze)));
|
||||||
|
|
||||||
FileOutputStream fout = new FileOutputStream(new File(param.unzipDirectory, "index.bundlejs"));
|
FileOutputStream fout = new FileOutputStream(new File(param.unzipDirectory, "index.bundlejs"));
|
||||||
fout.write(patched);
|
fout.write(patched);
|
||||||
@ -367,10 +352,12 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
unzipToFile(zis, fmd);
|
zipFile.unzipToFile(ze, fmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
zis.close();
|
zipFile.close();
|
||||||
|
|
||||||
|
|
||||||
if (!foundDiff) {
|
if (!foundDiff) {
|
||||||
throw new Error("diff.json not found");
|
throw new Error("diff.json not found");
|
||||||
}
|
}
|
||||||
@ -389,24 +376,25 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
|
|||||||
private void doPatchFromPpk(DownloadTaskParams param) throws IOException, JSONException {
|
private void doPatchFromPpk(DownloadTaskParams param) throws IOException, JSONException {
|
||||||
downloadFile(param);
|
downloadFile(param);
|
||||||
|
|
||||||
ZipInputStream zis = new ZipInputStream(new BufferedInputStream(new FileInputStream(param.targetFile)));
|
removeDirectory(param.unzipDirectory);
|
||||||
ZipEntry ze;
|
param.unzipDirectory.mkdirs();
|
||||||
|
|
||||||
int count;
|
int count;
|
||||||
String filename;
|
String filename;
|
||||||
boolean foundDiff = false;
|
boolean foundDiff = false;
|
||||||
boolean foundBundlePatch = false;
|
boolean foundBundlePatch = false;
|
||||||
|
|
||||||
removeDirectory(param.unzipDirectory);
|
|
||||||
param.unzipDirectory.mkdirs();
|
|
||||||
|
|
||||||
while ((ze = zis.getNextEntry()) != null)
|
SafeZipFile zipFile = new SafeZipFile(param.targetFile);
|
||||||
{
|
Enumeration<? extends ZipEntry> entries = zipFile.entries();
|
||||||
|
while (entries.hasMoreElements()) {
|
||||||
|
ZipEntry ze = entries.nextElement();
|
||||||
String fn = ze.getName();
|
String fn = ze.getName();
|
||||||
|
|
||||||
if (fn.equals("__diff.json")) {
|
if (fn.equals("__diff.json")) {
|
||||||
foundDiff = true;
|
foundDiff = true;
|
||||||
// copy files from assets
|
// copy files from assets
|
||||||
byte[] bytes = readBytes(zis);
|
byte[] bytes = readBytes(zipFile.getInputStream(ze));
|
||||||
String json = new String(bytes, "UTF-8");
|
String json = new String(bytes, "UTF-8");
|
||||||
JSONObject obj = (JSONObject)new JSONTokener(json).nextValue();
|
JSONObject obj = (JSONObject)new JSONTokener(json).nextValue();
|
||||||
|
|
||||||
@ -426,7 +414,7 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
|
|||||||
}
|
}
|
||||||
if (fn.equals("index.bundlejs.patch")) {
|
if (fn.equals("index.bundlejs.patch")) {
|
||||||
foundBundlePatch = true;
|
foundBundlePatch = true;
|
||||||
byte[] patched = hdiffPatch(readFile(new File(param.originDirectory, "index.bundlejs")), readBytes(zis));
|
byte[] patched = hdiffPatch(readFile(new File(param.originDirectory, "index.bundlejs")), readBytes(zipFile.getInputStream(ze)));
|
||||||
|
|
||||||
FileOutputStream fout = new FileOutputStream(new File(param.unzipDirectory, "index.bundlejs"));
|
FileOutputStream fout = new FileOutputStream(new File(param.unzipDirectory, "index.bundlejs"));
|
||||||
fout.write(patched);
|
fout.write(patched);
|
||||||
@ -444,10 +432,10 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
unzipToFile(zis, fmd);
|
zipFile.unzipToFile(ze, fmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
zis.close();
|
zipFile.close();
|
||||||
|
|
||||||
if (!foundDiff) {
|
if (!foundDiff) {
|
||||||
throw new Error("diff.json not found");
|
throw new Error("diff.json not found");
|
||||||
|
@ -0,0 +1,82 @@
|
|||||||
|
package cn.reactnative.modules.update;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.BufferedOutputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
|
import java.util.zip.ZipFile;
|
||||||
|
|
||||||
|
public class SafeZipFile extends ZipFile {
|
||||||
|
|
||||||
|
public SafeZipFile(File file) throws IOException {
|
||||||
|
super(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Enumeration<? extends ZipEntry> entries() {
|
||||||
|
return new SafeZipEntryIterator(super.entries());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class SafeZipEntryIterator implements Enumeration<ZipEntry> {
|
||||||
|
|
||||||
|
final private Enumeration<? extends ZipEntry> delegate;
|
||||||
|
|
||||||
|
private SafeZipEntryIterator(Enumeration<? extends ZipEntry> delegate) {
|
||||||
|
this.delegate = delegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasMoreElements() {
|
||||||
|
return delegate.hasMoreElements();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ZipEntry nextElement() {
|
||||||
|
ZipEntry entry = delegate.nextElement();
|
||||||
|
if (null != entry) {
|
||||||
|
String name = entry.getName();
|
||||||
|
/**
|
||||||
|
* avoid ZipperDown
|
||||||
|
*/
|
||||||
|
if (null != name && (name.contains("../") || name.contains("..\\"))) {
|
||||||
|
throw new SecurityException("illegal entry: " + entry.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void unzipToFile(ZipEntry entry, File output) throws IOException {
|
||||||
|
InputStream inputStream = null;
|
||||||
|
try {
|
||||||
|
inputStream = getInputStream(entry);
|
||||||
|
writeOutInputStream(output, inputStream);
|
||||||
|
} finally {
|
||||||
|
if (inputStream != null) {
|
||||||
|
inputStream.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeOutInputStream(File file, InputStream inputStream) throws IOException {
|
||||||
|
BufferedOutputStream output = null;
|
||||||
|
try {
|
||||||
|
output = new BufferedOutputStream(
|
||||||
|
new FileOutputStream(file));
|
||||||
|
BufferedInputStream input = new BufferedInputStream(inputStream);
|
||||||
|
byte b[] = new byte[8192];
|
||||||
|
int n;
|
||||||
|
while ((n = input.read(b, 0, 8192)) >= 0) {
|
||||||
|
output.write(b, 0, n);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if (output != null) {
|
||||||
|
output.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user