|
27 | 27 | import java.util.zip.ZipEntry; |
28 | 28 | import java.util.zip.ZipFile; |
29 | 29 | import java.util.zip.ZipInputStream; |
30 | | -import java.util.zip.ZipOutputStream; |
31 | 30 |
|
32 | 31 | import net.lingala.zip4j.exception.ZipException; |
33 | 32 | import net.lingala.zip4j.model.FileHeader; |
34 | | -import net.lingala.zip4j.progress.ProgressMonitor; |
35 | 33 | import net.lingala.zip4j.model.ZipParameters; |
36 | 34 | import net.lingala.zip4j.util.Zip4jConstants; |
37 | 35 |
|
38 | 36 | public class RNZipArchiveModule extends ReactContextBaseJavaModule { |
39 | 37 | private static final String TAG = RNZipArchiveModule.class.getSimpleName(); |
40 | 38 |
|
41 | | - private static final int BUFFER_SIZE = 4096; |
42 | 39 | private static final String PROGRESS_EVENT_NAME = "zipArchiveProgressEvent"; |
43 | 40 | private static final String EVENT_KEY_FILENAME = "filePath"; |
44 | 41 | private static final String EVENT_KEY_PROGRESS = "progress"; |
@@ -83,14 +80,18 @@ public void run() { |
83 | 80 | updateProgress(0, 1, zipFilePath); // force 0% |
84 | 81 | for (int i = 0; i < totalFiles; i++) { |
85 | 82 | FileHeader fileHeader = (FileHeader) fileHeaderList.get(i); |
| 83 | + |
| 84 | + File fout = new File(destDirectory, fileHeader.getFileName()); |
| 85 | + ensureZipPathSafety(fout, destDirectory); |
| 86 | + |
86 | 87 | zipFile.extractFile(fileHeader, destDirectory); |
87 | 88 | if (!fileHeader.isDirectory()) { |
88 | 89 | extractedFileNames.add(fileHeader.getFileName()); |
89 | 90 | } |
90 | 91 | updateProgress(i + 1, totalFiles, zipFilePath); |
91 | 92 | } |
92 | 93 | promise.resolve(Arguments.fromList(extractedFileNames)); |
93 | | - } catch (ZipException ex) { |
| 94 | + } catch (Exception ex) { |
94 | 95 | updateProgress(0, 1, zipFilePath); // force 0% |
95 | 96 | promise.reject(null, String.format("Failed to unzip file, due to: %s", getStackTrace(ex))); |
96 | 97 | } |
@@ -161,11 +162,7 @@ public void onCopyProgress(long bytesRead) { |
161 | 162 | }; |
162 | 163 |
|
163 | 164 | File fout = new File(destDirectory, entry.getName()); |
164 | | - String destDirCanonicalPath = (new File(destDirectory)).getCanonicalPath(); |
165 | | - String canonicalPath = fout.getCanonicalPath(); |
166 | | - if (!canonicalPath.startsWith(destDirCanonicalPath)) { |
167 | | - throw new Exception(String.format("Found Zip Path Traversal Vulnerability with %s", canonicalPath)); |
168 | | - } |
| 165 | + ensureZipPathSafety(fout, destDirectory); |
169 | 166 |
|
170 | 167 | if (!fout.exists()) { |
171 | 168 | //noinspection ResultOfMethodCallIgnored |
@@ -254,11 +251,7 @@ public void run() { |
254 | 251 | if (entry.isDirectory()) continue; |
255 | 252 | fout = new File(destDirectory, entry.getName()); |
256 | 253 |
|
257 | | - String destDirCanonicalPath = (new File(destDirectory)).getCanonicalPath(); |
258 | | - String canonicalPath = fout.getCanonicalPath(); |
259 | | - if (!canonicalPath.startsWith(destDirCanonicalPath)) { |
260 | | - throw new Exception(String.format("Found Zip Path Traversal Vulnerability with %s", canonicalPath)); |
261 | | - } |
| 254 | + ensureZipPathSafety(fout, destDirectory); |
262 | 255 |
|
263 | 256 | if (!fout.exists()) { |
264 | 257 | //noinspection ResultOfMethodCallIgnored |
@@ -493,4 +486,12 @@ private String getStackTrace(Exception e) { |
493 | 486 | return sw.toString(); |
494 | 487 | } |
495 | 488 |
|
| 489 | + private void ensureZipPathSafety(final File fout, final String destDirectory) throws Exception { |
| 490 | + String destDirCanonicalPath = (new File(destDirectory)).getCanonicalPath(); |
| 491 | + String canonicalPath = fout.getCanonicalPath(); |
| 492 | + if (!canonicalPath.startsWith(destDirCanonicalPath)) { |
| 493 | + throw new Exception(String.format("Found Zip Path Traversal Vulnerability with %s", canonicalPath)); |
| 494 | + } |
| 495 | + } |
| 496 | + |
496 | 497 | } |
0 commit comments