Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,13 @@ protected void extractFile(
} else if (isDirectory) {
targetFileName.mkdirs();
} else {
// Delete existing file first to handle read-only files
// This matches the behavior of tar and unzip
if (targetFileName.exists()) {
// Make file writable before deleting (required on Windows for read-only files)
targetFileName.setWritable(true);
targetFileName.delete();
}
Files.copy(compressedInputStream, targetFileName.toPath(), REPLACE_EXISTING);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,4 +188,33 @@ void shouldExtractWhenCasingDifferOnlyInEntryNamePath(@TempDir File temporaryFol
assertTrue(abstractUnArchiver.shouldExtractEntry(temporaryFolder, file, entryName, entryDate));
assertEquals(0, abstractUnArchiver.casingMessageEmitted.get());
}

@Test
void shouldExtractReadOnlyFile(@TempDir File temporaryFolder) throws Exception {
// given
File readOnlyFile = new File(temporaryFolder, "readonly.txt");
readOnlyFile.createNewFile();
java.nio.file.Files.write(readOnlyFile.toPath(), "original content".getBytes());

// Make the file read-only (simulate -r-xr-xr-x permissions)
readOnlyFile.setWritable(false);
assertTrue(readOnlyFile.exists());
assertFalse(readOnlyFile.canWrite());

// Create a mock input stream with new content
String newContent = "new content";
java.io.InputStream inputStream = new java.io.ByteArrayInputStream(newContent.getBytes());

// when
abstractUnArchiver.setOverwrite(true);
abstractUnArchiver.extractFile(
null, temporaryFolder, inputStream, "readonly.txt", new Date(), false, null, null, null);

// then
// The file should have been successfully overwritten
assertTrue(readOnlyFile.exists());
byte[] actualBytes = java.nio.file.Files.readAllBytes(readOnlyFile.toPath());
String actualContent = new String(actualBytes);
assertEquals(newContent, actualContent);
}
}
Loading