Skip to content

Commit 90e2199

Browse files
authored
Regression when file already exists when exploding archive (#720)
Signed-off-by: Valentin Delaye <jonesbusy@users.noreply.github.com>
1 parent 9e8634d commit 90e2199

2 files changed

Lines changed: 62 additions & 2 deletions

File tree

src/main/java/land/oras/utils/ArchiveUtils.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,8 @@ static void unzip(InputStream fis, Path target) {
405405
Files.createDirectories(outputPath.getParent());
406406
try (OutputStream out = Files.newOutputStream(
407407
outputPath,
408-
StandardOpenOption.CREATE_NEW,
408+
StandardOpenOption.CREATE,
409+
StandardOpenOption.TRUNCATE_EXISTING,
409410
StandardOpenOption.WRITE,
410411
LinkOption.NOFOLLOW_LINKS)) {
411412
zais.transferTo(out);
@@ -458,7 +459,8 @@ public static void untar(InputStream fis, Path target) {
458459
} else {
459460
try (OutputStream out = Files.newOutputStream(
460461
outputPath,
461-
StandardOpenOption.CREATE_NEW,
462+
StandardOpenOption.CREATE,
463+
StandardOpenOption.TRUNCATE_EXISTING,
462464
StandardOpenOption.WRITE,
463465
LinkOption.NOFOLLOW_LINKS)) {
464466
tais.transferTo(out);

src/test/java/land/oras/utils/ArchiveUtilsTest.java

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,4 +369,62 @@ void shouldRejectSymlinkEscapingTargetOnUntar(@TempDir Path tmp) throws IOExcept
369369
assertThrows(OrasException.class, () -> ArchiveUtils.untar(mtar, target));
370370
assertFalse(Files.exists(escapeFile), "Symlink-target escape must not create a file outside target");
371371
}
372+
373+
@Test
374+
void shouldUntarOverwriteExistingFiles(@TempDir Path tmp) throws IOException {
375+
Path target = tmp.resolve("output");
376+
Files.createDirectories(target);
377+
378+
byte[] firstContent = "first".getBytes();
379+
byte[] secondContent = "second-overwritten".getBytes();
380+
381+
Path tar1 = tmp.resolve("first.tar");
382+
try (TarArchiveOutputStream tout = new TarArchiveOutputStream(Files.newOutputStream(tar1))) {
383+
TarArchiveEntry e = new TarArchiveEntry("file.txt");
384+
e.setSize(firstContent.length);
385+
tout.putArchiveEntry(e);
386+
tout.write(firstContent);
387+
tout.closeArchiveEntry();
388+
}
389+
ArchiveUtils.untar(tar1, target);
390+
assertEquals("first", Files.readString(target.resolve("file.txt")));
391+
392+
Path tar2 = tmp.resolve("second.tar");
393+
try (TarArchiveOutputStream tout = new TarArchiveOutputStream(Files.newOutputStream(tar2))) {
394+
TarArchiveEntry e = new TarArchiveEntry("file.txt");
395+
e.setSize(secondContent.length);
396+
tout.putArchiveEntry(e);
397+
tout.write(secondContent);
398+
tout.closeArchiveEntry();
399+
}
400+
ArchiveUtils.untar(tar2, target);
401+
assertEquals("second-overwritten", Files.readString(target.resolve("file.txt")));
402+
}
403+
404+
@Test
405+
void shouldUnzipOverwriteExistingFiles(@TempDir Path tmp) throws IOException {
406+
Path target = tmp.resolve("output");
407+
Files.createDirectories(target);
408+
409+
byte[] firstContent = "first".getBytes();
410+
byte[] secondContent = "second-overwritten".getBytes();
411+
412+
Path zip1 = tmp.resolve("first.zip");
413+
try (java.util.zip.ZipOutputStream zout = new java.util.zip.ZipOutputStream(Files.newOutputStream(zip1))) {
414+
zout.putNextEntry(new java.util.zip.ZipEntry("file.txt"));
415+
zout.write(firstContent);
416+
zout.closeEntry();
417+
}
418+
ArchiveUtils.unzip(zip1, target);
419+
assertEquals("first", Files.readString(target.resolve("file.txt")));
420+
421+
Path zip2 = tmp.resolve("second.zip");
422+
try (java.util.zip.ZipOutputStream zout = new java.util.zip.ZipOutputStream(Files.newOutputStream(zip2))) {
423+
zout.putNextEntry(new java.util.zip.ZipEntry("file.txt"));
424+
zout.write(secondContent);
425+
zout.closeEntry();
426+
}
427+
ArchiveUtils.unzip(zip2, target);
428+
assertEquals("second-overwritten", Files.readString(target.resolve("file.txt")));
429+
}
372430
}

0 commit comments

Comments
 (0)