Skip to content

Commit 0f9b45e

Browse files
committed
resolve aab package image hot update issue
1 parent 89eca8e commit 0f9b45e

File tree

1 file changed

+41
-3
lines changed

1 file changed

+41
-3
lines changed

android/src/main/java/cn/reactnative/modules/update/DownloadTask.java

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import java.util.Enumeration;
2626
import java.util.Iterator;
2727
import java.util.zip.ZipEntry;
28+
import java.util.zip.CRC32;
2829
import java.util.HashMap;
2930

3031
import okio.BufferedSink;
@@ -68,6 +69,7 @@ private void removeDirectory(File file) throws IOException {
6869

6970
private void downloadFile(DownloadTaskParams param) throws IOException {
7071
String url = param.url;
72+
Log.d("😁downloadFile", url);
7173
File writePath = param.targetFile;
7274
this.hash = param.hash;
7375
OkHttpClient client = new OkHttpClient();
@@ -100,7 +102,7 @@ private void downloadFile(DownloadTaskParams param) throws IOException {
100102
if (UpdateContext.DEBUG) {
101103
Log.d("react-native-update", "Progress " + received + "/" + contentLength);
102104
}
103-
105+
104106
int percentage = (int)(received * 100.0 / contentLength + 0.5);
105107
if (percentage > currentPercentage) {
106108
currentPercentage = percentage;
@@ -198,6 +200,10 @@ private byte[] readFile(File file) throws IOException {
198200
return fout.toByteArray();
199201
}
200202

203+
private String getCRC32AsDecimal(long crc32Value) {
204+
return String.valueOf(crc32Value & 0xFFFFFFFFL);
205+
}
206+
201207
private void copyFilesWithBlacklist(String current, File from, File to, JSONObject blackList) throws IOException {
202208
File[] files = from.listFiles();
203209
for (File file : files) {
@@ -247,14 +253,19 @@ private void doFullPatch(DownloadTaskParams param) throws IOException {
247253
}
248254
}
249255

250-
private void copyFromResource(HashMap<String, ArrayList<File> > resToCopy) throws IOException {
256+
private void copyFromResource(HashMap<String, ArrayList<File> > resToCopy, HashMap<String, ArrayList<File>> resToCopy2) throws IOException {
251257
SafeZipFile zipFile = new SafeZipFile(new File(context.getPackageResourcePath()));
252258
Enumeration<? extends ZipEntry> entries = zipFile.entries();
253259
while (entries.hasMoreElements()) {
254260
ZipEntry ze = entries.nextElement();
255261

256262
String fn = ze.getName();
263+
long zipCrc32 = ze.getCrc();
264+
String crc32Decimal = getCRC32AsDecimal(zipCrc32);
257265
ArrayList<File> targets = resToCopy.get(fn);
266+
if(targets==null || targets.isEmpty()){
267+
targets = resToCopy2.get(crc32Decimal);
268+
}
258269
if (targets != null) {
259270
File lastTarget = null;
260271
for (File target: targets) {
@@ -279,6 +290,7 @@ private void doPatchFromApk(DownloadTaskParams param) throws IOException, JSONEx
279290
removeDirectory(param.unzipDirectory);
280291
param.unzipDirectory.mkdirs();
281292
HashMap<String, ArrayList<File>> copyList = new HashMap<String, ArrayList<File>>();
293+
HashMap<String, ArrayList<File>> copiesv2List = new HashMap<String, ArrayList<File>>();
282294

283295
boolean foundDiff = false;
284296
boolean foundBundlePatch = false;
@@ -297,7 +309,9 @@ private void doPatchFromApk(DownloadTaskParams param) throws IOException, JSONEx
297309
JSONObject obj = (JSONObject)new JSONTokener(json).nextValue();
298310

299311
JSONObject copies = obj.getJSONObject("copies");
312+
JSONObject copiesv2 = obj.getJSONObject("copiesv2");
300313
Iterator<?> keys = copies.keys();
314+
Iterator<?> keys2 = copiesv2.keys();
301315
while( keys.hasNext() ) {
302316
String to = (String)keys.next();
303317
String from = copies.getString(to);
@@ -321,6 +335,30 @@ private void doPatchFromApk(DownloadTaskParams param) throws IOException, JSONEx
321335
}
322336
target.add(toFile);
323337
}
338+
339+
while( keys2.hasNext() ) {
340+
String from = (String)keys2.next();
341+
String to = copiesv2.getString(from);
342+
if (from.isEmpty()) {
343+
from = to;
344+
}
345+
ArrayList<File> target = null;
346+
if (!copiesv2List.containsKey(from)) {
347+
target = new ArrayList<File>();
348+
copiesv2List.put(from, target);
349+
} else {
350+
target = copiesv2List.get((from));
351+
}
352+
File toFile = new File(param.unzipDirectory, to);
353+
354+
// Fixing a Zip Path Traversal Vulnerability
355+
// https://support.google.com/faqs/answer/9294009
356+
String canonicalPath = toFile.getCanonicalPath();
357+
if (!canonicalPath.startsWith(param.unzipDirectory.getCanonicalPath() + File.separator)) {
358+
throw new SecurityException("Illegal name: " + to);
359+
}
360+
target.add(toFile);
361+
}
324362
continue;
325363
}
326364
if (fn.equals("index.bundlejs.patch")) {
@@ -348,7 +386,7 @@ private void doPatchFromApk(DownloadTaskParams param) throws IOException, JSONEx
348386
throw new Error("bundle patch not found");
349387
}
350388

351-
copyFromResource(copyList);
389+
copyFromResource(copyList, copiesv2List);
352390

353391
if (UpdateContext.DEBUG) {
354392
Log.d("react-native-update", "Unzip finished");

0 commit comments

Comments
 (0)