Skip to content

Commit

Permalink
[RTD-540] reduce cognitive complexity
Browse files Browse the repository at this point in the history
  • Loading branch information
and-mora committed Mar 30, 2023
1 parent d8f5bc9 commit b358dd5
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
Expand Down Expand Up @@ -55,16 +54,13 @@ public File extractZipFile() {
}

if (isFilenameValidPredicate.negate().test(zipEntry.getName())) {
throw new IOException("Illegal filename in archive: " + zipEntry.getName());
throw new ZipException("Illegal filename in archive: " + zipEntry.getName());
}

totalEntryArchive++;
long totalSizeEntry = 0;
validateNumberOfEntries(totalEntryArchive);

if (totalEntryArchive > zipThresholdEntries) {
// too many entries in this archive, can lead to inodes exhaustion of the system
throw new IOException("Too many entries in the archive.");
}
long totalSizeEntry = 0;

try (InputStream zipEntryInputStream = new BufferedInputStream(
zipFile.getInputStream(zipEntry));
Expand All @@ -82,17 +78,10 @@ public File extractZipFile() {
totalSizeArchive += nBytes;

double compressionRatio = (double) totalSizeEntry / zipEntry.getCompressedSize();
if (compressionRatio > thresholdRatio) {
// ratio between compressed and uncompressed data is highly suspicious, looks like a Zip Bomb Attack
throw new IOException(
"Compression ratio is highly suspicious, check the hpan zip archive.");
}
}
}
validateCompressionRatio(compressionRatio);

if (totalSizeArchive > thresholdSizeUncompressed) {
// the uncompressed data size is too much for the application resource capacity
throw new IOException("The uncompressed data size is over the maximum size allowed.");
validateArchiveSize(totalSizeArchive);
}
}

if (zipEntry.getName().matches(listFilePattern)) {
Expand All @@ -102,4 +91,26 @@ public File extractZipFile() {
}
return localTempFile;
}

private void validateNumberOfEntries(int totalEntryArchive) throws ZipException {
if (totalEntryArchive > zipThresholdEntries) {
// too many entries in this archive, can lead to inodes exhaustion of the system
throw new ZipException("Too many entries in the archive.");
}
}

private void validateCompressionRatio(double compressionRatio) throws ZipException {
if (compressionRatio > thresholdRatio) {
// ratio between compressed and uncompressed data is highly suspicious, looks like a Zip Bomb Attack
throw new ZipException(
"Compression ratio is highly suspicious, check the hpan zip archive.");
}
}

private void validateArchiveSize(long totalSizeArchive) throws ZipException {
if (totalSizeArchive > thresholdSizeUncompressed) {
// the uncompressed data size is too much for the application resource capacity
throw new ZipException("The uncompressed data size is over the maximum size allowed.");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,15 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.SecureRandom;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipOutputStream;
import lombok.SneakyThrows;
import org.apache.commons.codec.digest.DigestUtils;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;

Expand All @@ -22,6 +26,13 @@ class HpanUnzipperTest {
@TempDir
Path tempDir;

Set<String> dataInFile;

@BeforeEach
void setUp() {
dataInFile = new HashSet<>();
}

@Test
void givenThresholdSizeWhenExtractZipFileThenThrowException() {

Expand Down Expand Up @@ -59,13 +70,18 @@ void givenWrongPatternWhenExtractZipFileThenReturnsNoFile() {
}

@Test
@SneakyThrows
void givenHappyCaseWhenExtractZipFileThenReturnsFile() {

File zippedFile = createTempZipFile(1, 10);

HpanUnzipper hpanUnzipper = createDefaultUnzipper(zippedFile);

assertThat(hpanUnzipper.extractZipFile()).isNotNull();
File extractedFile = hpanUnzipper.extractZipFile();

assertThat(extractedFile).isNotNull();
Collection<String> readLines = Files.readAllLines(extractedFile.toPath());
assertThat(readLines).containsAll(dataInFile);
}

@Test
Expand Down Expand Up @@ -133,8 +149,9 @@ private File createTempZipFile(int files, int rowsPerFile, boolean zipSplitAttac
for (int j = 0; j < rowsPerFile; j++) {
String stringHashed = DigestUtils.sha256Hex(
String.valueOf(SecureRandom.getInstanceStrong().nextInt()));
byte[] data = stringHashed.getBytes();
byte[] data = (stringHashed + "\n").getBytes();
out.write(data, 0, data.length);
dataInFile.add(stringHashed);
}
out.closeEntry();
}
Expand Down

0 comments on commit b358dd5

Please sign in to comment.