Skip to content

Commit

Permalink
Skip file attributes if nio is not supported
Browse files Browse the repository at this point in the history
  • Loading branch information
srikanth-lingala committed Jun 26, 2019
1 parent b6e22b4 commit 494fa72
Show file tree
Hide file tree
Showing 8 changed files with 98 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ void addFilesToZip(List<File> filesToAdd, ProgressMonitor progressMonitor, ZipPa
}

FileHeader fileHeader = zipOutputStream.closeEntry();
fileHeader.setExternalFileAttributes(FileUtils.getFileAttributes(fileToAdd.toPath()));
fileHeader.setExternalFileAttributes(FileUtils.getFileAttributes(fileToAdd));

headerWriter.updateLocalFileHeader(fileHeader, zipModel, splitOutputStream);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
30 changes: 20 additions & 10 deletions src/main/java/net/lingala/zip4j/util/FileUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -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];
}
}
Expand Down
14 changes: 11 additions & 3 deletions src/main/java/net/lingala/zip4j/util/UnzipUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -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 {

Expand All @@ -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());
}
}

}
20 changes: 20 additions & 0 deletions src/test/java/net/lingala/zip4j/util/FileUtilsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<PosixFilePermission> 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);
Expand Down
12 changes: 8 additions & 4 deletions src/test/java/net/lingala/zip4j/util/FileUtilsTestWindows.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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();
Expand Down
33 changes: 32 additions & 1 deletion src/test/java/net/lingala/zip4j/util/UnzipUtilIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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);
Expand All @@ -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(
Expand Down

0 comments on commit 494fa72

Please sign in to comment.