react-native-zip-archive 7.0.1 → 7.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -37,5 +37,5 @@ repositories {
37
37
 
38
38
  dependencies {
39
39
  implementation "com.facebook.react:react-native:+"
40
- implementation group: 'net.lingala.zip4j', name: 'zip4j', version: '2.+'
40
+ implementation group: 'net.lingala.zip4j', name: 'zip4j', version: '2.11.5'
41
41
  }
@@ -1,6 +1,7 @@
1
1
  package com.rnziparchive;
2
2
 
3
3
  import android.content.res.AssetFileDescriptor;
4
+ import android.net.Uri;
4
5
  import android.os.Build;
5
6
  import android.util.Log;
6
7
 
@@ -23,6 +24,7 @@ import java.io.PrintWriter;
23
24
  import java.io.StringWriter;
24
25
  import java.util.ArrayList;
25
26
  import java.util.Arrays;
27
+ import java.util.Collections;
26
28
  import java.util.Enumeration;
27
29
  import java.util.List;
28
30
  import java.util.zip.ZipEntry;
@@ -36,6 +38,7 @@ import net.lingala.zip4j.model.enums.CompressionMethod;
36
38
  import net.lingala.zip4j.model.enums.CompressionLevel;
37
39
  import net.lingala.zip4j.model.enums.EncryptionMethod;
38
40
  import net.lingala.zip4j.model.enums.AesKeyStrength;
41
+ import net.lingala.zip4j.progress.ProgressMonitor;
39
42
 
40
43
  import java.nio.charset.Charset;
41
44
 
@@ -67,7 +70,7 @@ public class RNZipArchiveModule extends ReactContextBaseJavaModule {
67
70
 
68
71
  @ReactMethod
69
72
  public void unzipWithPassword(final String zipFilePath, final String destDirectory,
70
- final String password, final Promise promise) {
73
+ final String password, final Promise promise) {
71
74
  new Thread(new Runnable() {
72
75
  @Override
73
76
  public void run() {
@@ -92,11 +95,11 @@ public class RNZipArchiveModule extends ReactContextBaseJavaModule {
92
95
  String destDirCanonicalPath = (new File(destDirectory).getCanonicalPath()) + File.separator;
93
96
 
94
97
  if (!canonicalPath.startsWith(destDirCanonicalPath)) {
95
- throw new SecurityException(String.format("Found Zip Path Traversal Vulnerability with %s", canonicalPath));
98
+ throw new SecurityException(String.format("Found Zip Path Traversal Vulnerability with %s", canonicalPath));
96
99
  }
97
100
 
98
101
  if (!fileHeader.isDirectory()) {
99
- zipFile.extractFile(fileHeader, destDirectory);
102
+ zipFile.extractFile(fileHeader, destDirectory);
100
103
  extractedFileNames.add(fileHeader.getFileName());
101
104
  }
102
105
  updateProgress(i + 1, totalFiles, zipFilePath);
@@ -149,11 +152,26 @@ public class RNZipArchiveModule extends ReactContextBaseJavaModule {
149
152
  zipFile = new net.lingala.zip4j.ZipFile(zipFilePath);
150
153
  }
151
154
 
155
+ ProgressMonitor progressMonitor = zipFile.getProgressMonitor();
156
+
157
+ zipFile.setRunInThread(true);
152
158
  zipFile.extractAll(destDirectory);
153
159
 
154
- zipFile.close();
155
- updateProgress(1, 1, zipFilePath); // force 100%
156
- promise.resolve(destDirectory);
160
+ while (!progressMonitor.getState().equals(ProgressMonitor.State.READY)) {
161
+ updateProgress(progressMonitor.getWorkCompleted(), progressMonitor.getTotalWork(), zipFilePath);
162
+
163
+ Thread.sleep(100);
164
+ }
165
+
166
+ if (progressMonitor.getResult().equals(ProgressMonitor.Result.SUCCESS)) {
167
+ zipFile.close();
168
+ updateProgress(1, 1, zipFilePath); // force 100%
169
+ promise.resolve(destDirectory);
170
+ } else if (progressMonitor.getResult().equals(ProgressMonitor.Result.ERROR)) {
171
+ throw new Exception("Error occurred. Error message: " + progressMonitor.getException().getMessage());
172
+ } else if (progressMonitor.getResult().equals(ProgressMonitor.Result.CANCELLED)) {
173
+ throw new Exception("Task cancelled");
174
+ }
157
175
  } catch (Exception ex) {
158
176
  updateProgress(0, 1, zipFilePath); // force 0%
159
177
  promise.reject(null, "Failed to extract file " + ex.getLocalizedMessage());
@@ -178,12 +196,21 @@ public class RNZipArchiveModule extends ReactContextBaseJavaModule {
178
196
  @Override
179
197
  public void run() {
180
198
  InputStream assetsInputStream;
181
- final long size;
199
+ final long compressedSize;
182
200
 
183
201
  try {
184
- assetsInputStream = getReactApplicationContext().getAssets().open(assetsPath);
185
- AssetFileDescriptor fileDescriptor = getReactApplicationContext().getAssets().openFd(assetsPath);
186
- size = fileDescriptor.getLength();
202
+ if(assetsPath.startsWith("content://")) {
203
+ var assetUri = Uri.parse(assetsPath);
204
+ var contentResolver = getReactApplicationContext().getContentResolver();
205
+
206
+ assetsInputStream = contentResolver.openInputStream(assetUri);
207
+ var fileDescriptor = contentResolver.openFileDescriptor(assetUri, "r");
208
+ compressedSize = fileDescriptor.getStatSize();
209
+ } else {
210
+ assetsInputStream = getReactApplicationContext().getAssets().open(assetsPath);
211
+ AssetFileDescriptor fileDescriptor = getReactApplicationContext().getAssets().openFd(assetsPath);
212
+ compressedSize = fileDescriptor.getLength();
213
+ }
187
214
  } catch (IOException e) {
188
215
  promise.reject(null, String.format("Asset file `%s` could not be opened", assetsPath));
189
216
  return;
@@ -201,19 +228,21 @@ public class RNZipArchiveModule extends ReactContextBaseJavaModule {
201
228
 
202
229
  ZipEntry entry;
203
230
 
204
- final long[] extractedBytes = {0};
205
- final int[] lastPercentage = {0};
231
+ long extractedBytes = 0;
232
+ updateProgress(extractedBytes, compressedSize, assetsPath); // force 0%
206
233
 
207
- updateProgress(0, 1, assetsPath); // force 0%
208
234
  File fout;
209
235
  while ((entry = zipIn.getNextEntry()) != null) {
210
236
  if (entry.isDirectory()) continue;
237
+
238
+ Log.i("rnziparchive", "Extracting: " + entry.getName());
239
+
211
240
  fout = new File(destDirectory, entry.getName());
212
241
  String canonicalPath = fout.getCanonicalPath();
213
242
  String destDirCanonicalPath = (new File(destDirectory).getCanonicalPath()) + File.separator;
214
243
 
215
244
  if (!canonicalPath.startsWith(destDirCanonicalPath)) {
216
- throw new SecurityException(String.format("Found Zip Path Traversal Vulnerability with %s", canonicalPath));
245
+ throw new SecurityException(String.format("Found Zip Path Traversal Vulnerability with %s", canonicalPath));
217
246
  }
218
247
 
219
248
  if (!fout.exists()) {
@@ -221,31 +250,22 @@ public class RNZipArchiveModule extends ReactContextBaseJavaModule {
221
250
  (new File(fout.getParent())).mkdirs();
222
251
  }
223
252
 
224
- final ZipEntry finalEntry = entry;
225
- StreamUtil.ProgressCallback cb = new StreamUtil.ProgressCallback() {
226
- @Override
227
- public void onCopyProgress(long bytesRead) {
228
- extractedBytes[0] += bytesRead;
229
-
230
- int lastTime = lastPercentage[0];
231
- int percentDone = (int) ((double) extractedBytes[0] * 100 / (double) size);
232
-
233
- // update at most once per percent.
234
- if (percentDone > lastTime) {
235
- lastPercentage[0] = percentDone;
236
- updateProgress(extractedBytes[0], size, finalEntry.getName());
237
- }
238
- }
239
- };
240
-
241
253
  FileOutputStream out = new FileOutputStream(fout);
242
254
  BufferedOutputStream Bout = new BufferedOutputStream(out);
243
- StreamUtil.copy(bin, Bout, cb);
255
+ StreamUtil.copy(bin, Bout, null);
244
256
  Bout.close();
245
257
  out.close();
258
+
259
+ extractedBytes += entry.getCompressedSize();
260
+
261
+ // do not let the percentage go over 99% because we want it to hit 100% only when we are sure it's finished
262
+ if(extractedBytes > compressedSize*0.99) extractedBytes = (long) (compressedSize*0.99);
263
+
264
+ updateProgress(extractedBytes, compressedSize, entry.getName());
246
265
  }
247
266
 
248
- updateProgress(1, 1, assetsPath); // force 100%
267
+ updateProgress(compressedSize, compressedSize, assetsPath); // force 100%
268
+
249
269
  bin.close();
250
270
  zipIn.close();
251
271
  } catch (Exception ex) {
@@ -276,21 +296,21 @@ public class RNZipArchiveModule extends ReactContextBaseJavaModule {
276
296
 
277
297
  @ReactMethod
278
298
  public void zipFilesWithPassword(final ReadableArray files, final String destFile, final String password,
279
- String encryptionMethod, Promise promise) {
299
+ String encryptionMethod, Promise promise) {
280
300
  zipWithPassword(files.toArrayList(), destFile, password, encryptionMethod, promise);
281
301
  }
282
302
 
283
303
 
284
304
  @ReactMethod
285
305
  public void zipFolderWithPassword(final String folder, final String destFile, final String password,
286
- String encryptionMethod, Promise promise) {
306
+ String encryptionMethod, Promise promise) {
287
307
  ArrayList<Object> folderAsArrayList = new ArrayList<>();
288
308
  folderAsArrayList.add(folder);
289
309
  zipWithPassword(folderAsArrayList, destFile, password, encryptionMethod, promise);
290
310
  }
291
311
 
292
312
  private void zipWithPassword(final ArrayList<Object> filesOrDirectory, final String destFile, final String password,
293
- String encryptionMethod, Promise promise) {
313
+ String encryptionMethod, Promise promise) {
294
314
  try{
295
315
 
296
316
  ZipParameters parameters = new ZipParameters();
package/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  declare module 'react-native-zip-archive' {
2
- enum encryptionMethods {
3
- 'STANDARD',
4
- 'AES-128',
5
- 'AES-256'
2
+ enum EncryptionMethods {
3
+ STANDARD = "STANDARD",
4
+ AES_128 = "AES-128",
5
+ AES_256 = "AES-256"
6
6
  }
7
7
  import { NativeEventSubscription } from 'react-native';
8
8
  export function isPasswordProtected(source: string): Promise<boolean>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-zip-archive",
3
- "version": "7.0.1",
3
+ "version": "7.0.2",
4
4
  "description": "A little wrapper on ZipArchive for react-native",
5
5
  "main": "index.js",
6
6
  "scripts": {