|
3 | 3 | import java.io.FileInputStream; |
4 | 4 | import java.io.IOException; |
5 | 5 | import java.io.InputStream; |
| 6 | +import java.nio.file.FileAlreadyExistsException; |
6 | 7 | import java.nio.file.Files; |
7 | 8 | import java.nio.file.Path; |
8 | 9 | import java.nio.file.Paths; |
@@ -86,26 +87,40 @@ public static void unzip(Path zip, Path outputDir, boolean stripRootFolder, Path |
86 | 87 | if (!entry.startsWith(outputDir)) { |
87 | 88 | throw new IOException("Entry is outside of the target dir: " + zipEntry.getName()); |
88 | 89 | } |
89 | | - if (zipEntry.isDirectory()) { |
90 | | - Files.createDirectories(entry); |
91 | | - } else if (zipEntry.isUnixSymlink()) { |
92 | | - Scanner s = new Scanner(zipFile.getInputStream(zipEntry)).useDelimiter("\\A"); |
93 | | - String result = s.hasNext() ? s.next() : ""; |
94 | | - Files.createSymbolicLink(entry, Paths.get(result)); |
95 | | - } else { |
96 | | - if (!Files.isDirectory(entry.getParent())) { |
97 | | - Files.createDirectories(entry.getParent()); |
98 | | - } |
99 | | - if (Files.isRegularFile(entry)) { |
100 | | - onExisting.handle(zipFile, zipEntry, entry); |
| 90 | + try { |
| 91 | + if (zipEntry.isDirectory() && checkValidParent(entry)) { |
| 92 | + Files.createDirectories(entry); |
| 93 | + } else if (zipEntry.isUnixSymlink()) { |
| 94 | + Scanner s = new Scanner(zipFile.getInputStream(zipEntry)).useDelimiter("\\A"); |
| 95 | + String result = s.hasNext() ? s.next() : ""; |
| 96 | + Files.createSymbolicLink(entry, Paths.get(result)); |
101 | 97 | } else { |
102 | | - defaultZipEntryCopy(zipFile, zipEntry, entry); |
| 98 | + if (checkValidParent(entry.getParent())) { |
| 99 | + Files.createDirectories(entry.getParent()); |
| 100 | + } |
| 101 | + if (Files.exists(entry)) { |
| 102 | + onExisting.handle(zipFile, zipEntry, entry); |
| 103 | + } else { |
| 104 | + defaultZipEntryCopy(zipFile, zipEntry, entry); |
| 105 | + } |
103 | 106 | } |
| 107 | + } catch (FileAlreadyExistsException e) { |
| 108 | + onExisting.handle(zipFile, zipEntry, entry); |
104 | 109 | } |
105 | 110 | } |
106 | 111 | } |
107 | 112 | } |
108 | 113 |
|
| 114 | + private static boolean checkValidParent(Path path) throws FileAlreadyExistsException { |
| 115 | + while (path != null && !Files.exists(path)) { |
| 116 | + path = path.getParent(); |
| 117 | + } |
| 118 | + if (path != null && !Files.isDirectory(path)) { |
| 119 | + throw new FileAlreadyExistsException("Parent path is not a directory: " + path); |
| 120 | + } |
| 121 | + return true; |
| 122 | + } |
| 123 | + |
109 | 124 | public interface ExistingZipFileHandler { |
110 | 125 | void handle(ZipFile zipFile, ZipArchiveEntry zipEntry, Path outFile) throws IOException; |
111 | 126 | } |
|
0 commit comments