From 494fa72d34f1642143542c2147c97bcb2f4f93c8 Mon Sep 17 00:00:00 2001 From: Srikanth Reddy Lingala Date: Wed, 26 Jun 2019 18:12:12 +0200 Subject: [PATCH] Skip file attributes if nio is not supported --- .../zip4j/tasks/AbstractAddFileToZipTask.java | 2 +- .../zip4j/tasks/AbstractExtractFileTask.java | 2 +- .../net/lingala/zip4j/util/FileUtils.java | 30 +++++++++++------ .../net/lingala/zip4j/util/UnzipUtil.java | 14 ++++++-- .../net/lingala/zip4j/util/FileUtilsTest.java | 20 +++++++++++ .../zip4j/util/FileUtilsTestLinuxAndMac.java | 6 +++- .../zip4j/util/FileUtilsTestWindows.java | 12 ++++--- .../net/lingala/zip4j/util/UnzipUtilIT.java | 33 ++++++++++++++++++- 8 files changed, 98 insertions(+), 21 deletions(-) diff --git a/src/main/java/net/lingala/zip4j/tasks/AbstractAddFileToZipTask.java b/src/main/java/net/lingala/zip4j/tasks/AbstractAddFileToZipTask.java index 3d52d175..4264d4f9 100644 --- a/src/main/java/net/lingala/zip4j/tasks/AbstractAddFileToZipTask.java +++ b/src/main/java/net/lingala/zip4j/tasks/AbstractAddFileToZipTask.java @@ -75,7 +75,7 @@ void addFilesToZip(List filesToAdd, ProgressMonitor progressMonitor, ZipPa } FileHeader fileHeader = zipOutputStream.closeEntry(); - fileHeader.setExternalFileAttributes(FileUtils.getFileAttributes(fileToAdd.toPath())); + fileHeader.setExternalFileAttributes(FileUtils.getFileAttributes(fileToAdd)); headerWriter.updateLocalFileHeader(fileHeader, zipModel, splitOutputStream); } diff --git a/src/main/java/net/lingala/zip4j/tasks/AbstractExtractFileTask.java b/src/main/java/net/lingala/zip4j/tasks/AbstractExtractFileTask.java index c7fc5a14..46ac5969 100644 --- a/src/main/java/net/lingala/zip4j/tasks/AbstractExtractFileTask.java +++ b/src/main/java/net/lingala/zip4j/tasks/AbstractExtractFileTask.java @@ -76,7 +76,7 @@ private void unzipFile(ZipInputStream inputStream, FileHeader fileHeader, String throw new ZipException(e); } - UnzipUtil.applyFileAttributes(fileHeader, outputFile.toPath()); + UnzipUtil.applyFileAttributes(fileHeader, outputFile); } private void verifyNextEntry(ZipInputStream zipInputStream, FileHeader fileHeader) throws ZipException { diff --git a/src/main/java/net/lingala/zip4j/util/FileUtils.java b/src/main/java/net/lingala/zip4j/util/FileUtils.java index c5fa7dc1..9c3dcde2 100644 --- a/src/main/java/net/lingala/zip4j/util/FileUtils.java +++ b/src/main/java/net/lingala/zip4j/util/FileUtils.java @@ -62,17 +62,27 @@ public static void setFileLastModifiedTime(Path file, long lastModifiedTime) { } } - public static byte[] getFileAttributes(Path file) { - if (file == null || !Files.exists(file)) { - return new byte[4]; - } + public static void setFileLastModifiedTimeWithoutNio(File file, long lastModifiedTime) { + file.setLastModified(Zip4jUtil.dosToJavaTme(lastModifiedTime)); + } - String os = System.getProperty("os.name").toLowerCase(); - if (isWindows(os)) { - return getWindowsFileAttributes(file); - } else if (isMac(os) || isUnix(os)) { - return getPosixFileAttributes(file); - } else { + public static byte[] getFileAttributes(File file) { + try { + if (file == null || !file.exists()) { + return new byte[4]; + } + + Path path = file.toPath(); + + String os = System.getProperty("os.name").toLowerCase(); + if (isWindows(os)) { + return getWindowsFileAttributes(path); + } else if (isMac(os) || isUnix(os)) { + return getPosixFileAttributes(path); + } else { + return new byte[4]; + } + } catch (NoSuchMethodError e) { return new byte[4]; } } diff --git a/src/main/java/net/lingala/zip4j/util/UnzipUtil.java b/src/main/java/net/lingala/zip4j/util/UnzipUtil.java index 6f686a1b..0066fa02 100755 --- a/src/main/java/net/lingala/zip4j/util/UnzipUtil.java +++ b/src/main/java/net/lingala/zip4j/util/UnzipUtil.java @@ -6,11 +6,13 @@ import net.lingala.zip4j.model.FileHeader; import net.lingala.zip4j.model.ZipModel; +import java.io.File; import java.io.IOException; import java.nio.file.Path; import static net.lingala.zip4j.util.FileUtils.setFileAttributes; import static net.lingala.zip4j.util.FileUtils.setFileLastModifiedTime; +import static net.lingala.zip4j.util.FileUtils.setFileLastModifiedTimeWithoutNio; public class UnzipUtil { @@ -32,9 +34,15 @@ public static ZipInputStream createZipInputStream(ZipModel zipModel, FileHeader } } - public static void applyFileAttributes(FileHeader fileHeader, Path file) { - setFileAttributes(file, fileHeader.getExternalFileAttributes()); - setFileLastModifiedTime(file, fileHeader.getLastModifiedTime()); + public static void applyFileAttributes(FileHeader fileHeader, File file) { + + try { + Path path = file.toPath(); + setFileAttributes(path, fileHeader.getExternalFileAttributes()); + setFileLastModifiedTime(path, fileHeader.getLastModifiedTime()); + } catch (NoSuchMethodError e) { + setFileLastModifiedTimeWithoutNio(file, fileHeader.getLastModifiedTime()); + } } } diff --git a/src/test/java/net/lingala/zip4j/util/FileUtilsTest.java b/src/test/java/net/lingala/zip4j/util/FileUtilsTest.java index 348128d3..d465c186 100644 --- a/src/test/java/net/lingala/zip4j/util/FileUtilsTest.java +++ b/src/test/java/net/lingala/zip4j/util/FileUtilsTest.java @@ -70,6 +70,26 @@ public void testLastModifiedFileTimeWhenIOExceptionDoesNothing() { FileUtils.setFileLastModifiedTime(path, currentTime); } + @Test + public void testLastModifiedFileTimeWithoutNIOSetsSuccessfully() { + File file = mock(File.class); + long currentTime = System.currentTimeMillis(); + + FileUtils.setFileLastModifiedTimeWithoutNio(file, currentTime); + + verify(file).setLastModified(Zip4jUtil.dosToJavaTme(currentTime)); + } + + @Test + public void testGetFileAttributesReturnsEmptyBytesWhenNIONotSupported() { + File file = mock(File.class); + when(file.toPath()).thenThrow(new NoSuchMethodError("No method")); + + byte[] fileAttributes = FileUtils.getFileAttributes(file); + assertThat(fileAttributes).hasSize(4); + assertThat(fileAttributes).contains(0, 0, 0, 0); + } + @Test public void testGetFilesInDirectoryRecursiveThrowsExceptionWhenFileIsNull() throws ZipException { expectedException.expectMessage("input path is null, cannot read files in the directory"); diff --git a/src/test/java/net/lingala/zip4j/util/FileUtilsTestLinuxAndMac.java b/src/test/java/net/lingala/zip4j/util/FileUtilsTestLinuxAndMac.java index a6330679..7f2970f1 100644 --- a/src/test/java/net/lingala/zip4j/util/FileUtilsTestLinuxAndMac.java +++ b/src/test/java/net/lingala/zip4j/util/FileUtilsTestLinuxAndMac.java @@ -5,6 +5,7 @@ import org.junit.Test; import org.mockito.ArgumentCaptor; +import java.io.File; import java.io.IOException; import java.nio.file.FileSystem; import java.nio.file.Path; @@ -89,14 +90,17 @@ public void testGetFileAttributesAsDefinedForDirectory() throws IOException { } private void testGetFileAttributesGetsAsDefined(boolean isDirectory) throws IOException { + File file = mock(File.class); Path path = mock(Path.class); + when(file.toPath()).thenReturn(path); + when(file.exists()).thenReturn(true); PosixFileAttributeView posixFileAttributeView = mockPosixFileAttributeView(path, isDirectory); PosixFileAttributes posixFileAttributes = mock(PosixFileAttributes.class); Set posixFilePermissions = getAllPermissions(); when(posixFileAttributes.permissions()).thenReturn(posixFilePermissions); when(posixFileAttributeView.readAttributes()).thenReturn(posixFileAttributes); - byte[] fileAttributes = FileUtils.getFileAttributes(path); + byte[] fileAttributes = FileUtils.getFileAttributes(file); assertThat(fileAttributes).hasSize(4); assertThat(fileAttributes[0]).isEqualTo((byte) 0); diff --git a/src/test/java/net/lingala/zip4j/util/FileUtilsTestWindows.java b/src/test/java/net/lingala/zip4j/util/FileUtilsTestWindows.java index 7db74dfb..84eb964b 100644 --- a/src/test/java/net/lingala/zip4j/util/FileUtilsTestWindows.java +++ b/src/test/java/net/lingala/zip4j/util/FileUtilsTestWindows.java @@ -4,6 +4,7 @@ import org.junit.Before; import org.junit.Test; +import java.io.File; import java.io.IOException; import java.nio.file.FileSystem; import java.nio.file.Path; @@ -80,17 +81,20 @@ public void testGetFileAttributesWhenFileIsNullReturnsEmptyBytes() { @Test public void testGetFileAttributesWhenFileDoesNotExistReturnsEmptyBytes() throws IOException { - Path path = mock(Path.class); - mockDosFileAttributeView(path, false); + File file = mock(File.class); + when(file.exists()).thenReturn(false); - byte[] attributes = FileUtils.getFileAttributes(path); + byte[] attributes = FileUtils.getFileAttributes(file); assertThat(attributes).contains(0, 0, 0, 0); } @Test public void testGetFileAttributesReturnsAttributesAsDefined() throws IOException { + File file = mock(File.class); Path path = mock(Path.class); + when(file.toPath()).thenReturn(path); + when(file.exists()).thenReturn(true); DosFileAttributeView dosFileAttributeView = mockDosFileAttributeView(path, true); DosFileAttributes dosFileAttributes = mock(DosFileAttributes.class); when(dosFileAttributeView.readAttributes()).thenReturn(dosFileAttributes); @@ -99,7 +103,7 @@ public void testGetFileAttributesReturnsAttributesAsDefined() throws IOException when(dosFileAttributes.isSystem()).thenReturn(true); when(dosFileAttributes.isArchive()).thenReturn(true); - byte[] attributes = FileUtils.getFileAttributes(path); + byte[] attributes = FileUtils.getFileAttributes(file); assertThat(isBitSet(attributes[0], 0)).isTrue(); assertThat(isBitSet(attributes[0], 1)).isTrue(); diff --git a/src/test/java/net/lingala/zip4j/util/UnzipUtilIT.java b/src/test/java/net/lingala/zip4j/util/UnzipUtilIT.java index 6a51496d..8cd782ff 100644 --- a/src/test/java/net/lingala/zip4j/util/UnzipUtilIT.java +++ b/src/test/java/net/lingala/zip4j/util/UnzipUtilIT.java @@ -22,6 +22,8 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.when; import static org.powermock.api.mockito.PowerMockito.verifyStatic; @RunWith(PowerMockRunner.class) @@ -55,11 +57,14 @@ public void testApplyFileAttributes() { FileHeader fileHeader = new FileHeader(); fileHeader.setExternalFileAttributes(externalFileAttributes); fileHeader.setLastModifiedTime(currentTime); + + File file = mock(File.class); Path path = mock(Path.class); + when(file.toPath()).thenReturn(path); PowerMockito.mockStatic(FileUtils.class); - UnzipUtil.applyFileAttributes(fileHeader, path); + UnzipUtil.applyFileAttributes(fileHeader, file); verifyStatic(); FileUtils.setFileLastModifiedTime(path, currentTime); @@ -68,6 +73,32 @@ public void testApplyFileAttributes() { FileUtils.setFileAttributes(path, externalFileAttributes); } + @Test + public void testApplyFileFileAttributesSetsLastModifiedTimeWithoutNio() { + byte[] externalFileAttributes = new byte[] {12, 34, 0, 0}; + long currentTime = System.currentTimeMillis(); + FileHeader fileHeader = new FileHeader(); + fileHeader.setExternalFileAttributes(externalFileAttributes); + fileHeader.setLastModifiedTime(currentTime); + + File file = mock(File.class); + Path path = mock(Path.class); + when(file.toPath()).thenThrow(new NoSuchMethodError("No method")); + + PowerMockito.mockStatic(FileUtils.class); + + UnzipUtil.applyFileAttributes(fileHeader, file); + + verifyStatic(never()); + FileUtils.setFileLastModifiedTime(path, currentTime); + + verifyStatic(never()); + FileUtils.setFileAttributes(path, externalFileAttributes); + + verifyStatic(); + FileUtils.setFileLastModifiedTimeWithoutNio(file, currentTime); + } + private ZipFile createZipFile() throws ZipException { ZipFile zipFile = new ZipFile(generatedZipFile, "password".toCharArray()); zipFile.addFiles(Arrays.asList(