2525import java .util .Enumeration ;
2626import java .util .Iterator ;
2727import java .util .zip .ZipEntry ;
28+ import java .util .zip .CRC32 ;
2829import java .util .HashMap ;
2930
3031import 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