github-code-scanning[bot] commented on code in PR #757:
URL: 
https://github.com/apache/incubator-baremaps/pull/757#discussion_r1306713155


##########
baremaps-core/src/main/java/org/apache/baremaps/workflow/tasks/DecompressFile.java:
##########
@@ -0,0 +1,149 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not 
use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software 
distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
KIND, either express
+ * or implied. See the License for the specific language governing permissions 
and limitations under
+ * the License.
+ */
+
+package org.apache.baremaps.workflow.tasks;
+
+import java.io.*;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardCopyOption;
+import java.nio.file.StandardOpenOption;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.ZipFile;
+import org.apache.baremaps.workflow.Task;
+import org.apache.baremaps.workflow.WorkflowContext;
+import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
+import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
+import 
org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public record DecompressFile(Path source, Path target, Compression 
compression) implements Task {
+
+  public enum Compression {
+    zip,
+    targz,
+    tarbz2,
+    gzip,
+    bzip2
+  }
+
+  private static final Logger logger = 
LoggerFactory.getLogger(UngzipFile.class);
+
+  @Override
+  public void execute(WorkflowContext context) throws Exception {
+    var sourcePath = source.toAbsolutePath();
+    var targetPath = target.toAbsolutePath();
+    switch (compression) {
+      case zip:
+        decompressZip(sourcePath, targetPath);
+        break;
+      case targz:
+        decompressTarGz(sourcePath, targetPath);
+        break;
+      case tarbz2:
+        decompressTarBz2(sourcePath, targetPath);
+        break;
+      case gzip:
+        decompressGzip(sourcePath, targetPath);
+        break;
+      case bzip2:
+        decompressBzip2(sourcePath, targetPath);
+        break;
+    }
+
+  }
+
+  public static void decompressBzip2(Path sourcePath, Path targetPath) throws 
IOException {
+    try (var zis =
+        new BZip2CompressorInputStream(new 
BufferedInputStream(Files.newInputStream(sourcePath)))) {
+      Files.copy(zis, targetPath, StandardCopyOption.REPLACE_EXISTING);
+    }
+  }
+
+  public static void decompressGzip(Path sourcePath, Path targetPath) throws 
IOException {
+    try (var zis = new GZIPInputStream(new 
BufferedInputStream(Files.newInputStream(sourcePath)))) {
+      Files.copy(zis, targetPath, StandardCopyOption.REPLACE_EXISTING);
+    }
+  }
+
+  public static void decompressTarGz(Path sourcePath, Path targetPath) throws 
IOException {
+    try (
+        GZIPInputStream gzipInputStream =
+            new GZIPInputStream(new 
BufferedInputStream(Files.newInputStream(sourcePath)));
+        TarArchiveInputStream tarInputStream = new 
TarArchiveInputStream(gzipInputStream)) {
+      TarArchiveEntry entry;
+      while ((entry = (TarArchiveEntry) tarInputStream.getNextEntry()) != 
null) {
+        var path = targetPath.resolve(entry.getName());

Review Comment:
   ## Arbitrary file access during archive extraction ("Zip Slip")
   
   Unsanitized archive entry, which may contain '..', is used in a [file system 
operation](1).
   Unsanitized archive entry, which may contain '..', is used in a [file system 
operation](2).
   Unsanitized archive entry, which may contain '..', is used in a [file system 
operation](3).
   
   [Show more 
details](https://github.com/apache/incubator-baremaps/security/code-scanning/791)



##########
baremaps-core/src/main/java/org/apache/baremaps/workflow/tasks/DecompressFile.java:
##########
@@ -0,0 +1,149 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not 
use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software 
distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
KIND, either express
+ * or implied. See the License for the specific language governing permissions 
and limitations under
+ * the License.
+ */
+
+package org.apache.baremaps.workflow.tasks;
+
+import java.io.*;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardCopyOption;
+import java.nio.file.StandardOpenOption;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.ZipFile;
+import org.apache.baremaps.workflow.Task;
+import org.apache.baremaps.workflow.WorkflowContext;
+import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
+import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
+import 
org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public record DecompressFile(Path source, Path target, Compression 
compression) implements Task {
+
+  public enum Compression {
+    zip,
+    targz,
+    tarbz2,
+    gzip,
+    bzip2
+  }
+
+  private static final Logger logger = 
LoggerFactory.getLogger(UngzipFile.class);
+
+  @Override
+  public void execute(WorkflowContext context) throws Exception {
+    var sourcePath = source.toAbsolutePath();
+    var targetPath = target.toAbsolutePath();
+    switch (compression) {
+      case zip:
+        decompressZip(sourcePath, targetPath);
+        break;
+      case targz:
+        decompressTarGz(sourcePath, targetPath);
+        break;
+      case tarbz2:
+        decompressTarBz2(sourcePath, targetPath);
+        break;
+      case gzip:
+        decompressGzip(sourcePath, targetPath);
+        break;
+      case bzip2:
+        decompressBzip2(sourcePath, targetPath);
+        break;
+    }
+
+  }
+
+  public static void decompressBzip2(Path sourcePath, Path targetPath) throws 
IOException {
+    try (var zis =
+        new BZip2CompressorInputStream(new 
BufferedInputStream(Files.newInputStream(sourcePath)))) {
+      Files.copy(zis, targetPath, StandardCopyOption.REPLACE_EXISTING);
+    }
+  }
+
+  public static void decompressGzip(Path sourcePath, Path targetPath) throws 
IOException {
+    try (var zis = new GZIPInputStream(new 
BufferedInputStream(Files.newInputStream(sourcePath)))) {
+      Files.copy(zis, targetPath, StandardCopyOption.REPLACE_EXISTING);
+    }
+  }
+
+  public static void decompressTarGz(Path sourcePath, Path targetPath) throws 
IOException {
+    try (
+        GZIPInputStream gzipInputStream =
+            new GZIPInputStream(new 
BufferedInputStream(Files.newInputStream(sourcePath)));
+        TarArchiveInputStream tarInputStream = new 
TarArchiveInputStream(gzipInputStream)) {
+      TarArchiveEntry entry;
+      while ((entry = (TarArchiveEntry) tarInputStream.getNextEntry()) != 
null) {
+        var path = targetPath.resolve(entry.getName());
+        if (entry.isDirectory()) {
+          Files.createDirectories(path);
+        } else {
+          Files.createDirectories(path.getParent());
+          try (BufferedOutputStream outputStream =
+              new BufferedOutputStream(Files.newOutputStream(path))) {
+            int bytesRead;
+            byte[] buffer = new byte[4096];
+            while ((bytesRead = tarInputStream.read(buffer)) != -1) {
+              outputStream.write(buffer, 0, bytesRead);
+            }
+          }
+        }
+      }
+    }
+  }
+
+  public static void decompressTarBz2(Path sourcePath, Path targetPath) throws 
IOException {
+    try (
+        BZip2CompressorInputStream gzipInputStream = new 
BZip2CompressorInputStream(
+            new BufferedInputStream(Files.newInputStream(sourcePath)));
+        TarArchiveInputStream tarInputStream = new 
TarArchiveInputStream(gzipInputStream)) {
+      TarArchiveEntry entry;
+      while ((entry = (TarArchiveEntry) tarInputStream.getNextEntry()) != 
null) {
+        var path = targetPath.resolve(entry.getName());

Review Comment:
   ## Arbitrary file access during archive extraction ("Zip Slip")
   
   Unsanitized archive entry, which may contain '..', is used in a [file system 
operation](1).
   Unsanitized archive entry, which may contain '..', is used in a [file system 
operation](2).
   Unsanitized archive entry, which may contain '..', is used in a [file system 
operation](3).
   
   [Show more 
details](https://github.com/apache/incubator-baremaps/security/code-scanning/792)



##########
baremaps-core/src/main/java/org/apache/baremaps/workflow/tasks/DecompressFile.java:
##########
@@ -0,0 +1,149 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not 
use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software 
distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
KIND, either express
+ * or implied. See the License for the specific language governing permissions 
and limitations under
+ * the License.
+ */
+
+package org.apache.baremaps.workflow.tasks;
+
+import java.io.*;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardCopyOption;
+import java.nio.file.StandardOpenOption;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.ZipFile;
+import org.apache.baremaps.workflow.Task;
+import org.apache.baremaps.workflow.WorkflowContext;
+import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
+import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
+import 
org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public record DecompressFile(Path source, Path target, Compression 
compression) implements Task {
+
+  public enum Compression {
+    zip,
+    targz,
+    tarbz2,
+    gzip,
+    bzip2
+  }
+
+  private static final Logger logger = 
LoggerFactory.getLogger(UngzipFile.class);
+
+  @Override
+  public void execute(WorkflowContext context) throws Exception {
+    var sourcePath = source.toAbsolutePath();
+    var targetPath = target.toAbsolutePath();
+    switch (compression) {
+      case zip:
+        decompressZip(sourcePath, targetPath);
+        break;
+      case targz:
+        decompressTarGz(sourcePath, targetPath);
+        break;
+      case tarbz2:
+        decompressTarBz2(sourcePath, targetPath);
+        break;
+      case gzip:
+        decompressGzip(sourcePath, targetPath);
+        break;
+      case bzip2:
+        decompressBzip2(sourcePath, targetPath);
+        break;
+    }
+
+  }
+
+  public static void decompressBzip2(Path sourcePath, Path targetPath) throws 
IOException {
+    try (var zis =
+        new BZip2CompressorInputStream(new 
BufferedInputStream(Files.newInputStream(sourcePath)))) {
+      Files.copy(zis, targetPath, StandardCopyOption.REPLACE_EXISTING);
+    }
+  }
+
+  public static void decompressGzip(Path sourcePath, Path targetPath) throws 
IOException {
+    try (var zis = new GZIPInputStream(new 
BufferedInputStream(Files.newInputStream(sourcePath)))) {
+      Files.copy(zis, targetPath, StandardCopyOption.REPLACE_EXISTING);
+    }
+  }
+
+  public static void decompressTarGz(Path sourcePath, Path targetPath) throws 
IOException {
+    try (
+        GZIPInputStream gzipInputStream =
+            new GZIPInputStream(new 
BufferedInputStream(Files.newInputStream(sourcePath)));

Review Comment:
   ## Potential input resource leak
   
   This BufferedInputStream is not always closed on method exit.
   
   [Show more 
details](https://github.com/apache/incubator-baremaps/security/code-scanning/796)



##########
baremaps-core/src/main/java/org/apache/baremaps/workflow/tasks/DecompressFile.java:
##########
@@ -0,0 +1,149 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not 
use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software 
distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
KIND, either express
+ * or implied. See the License for the specific language governing permissions 
and limitations under
+ * the License.
+ */
+
+package org.apache.baremaps.workflow.tasks;
+
+import java.io.*;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardCopyOption;
+import java.nio.file.StandardOpenOption;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.ZipFile;
+import org.apache.baremaps.workflow.Task;
+import org.apache.baremaps.workflow.WorkflowContext;
+import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
+import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
+import 
org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public record DecompressFile(Path source, Path target, Compression 
compression) implements Task {
+
+  public enum Compression {
+    zip,
+    targz,
+    tarbz2,
+    gzip,
+    bzip2
+  }
+
+  private static final Logger logger = 
LoggerFactory.getLogger(UngzipFile.class);
+
+  @Override
+  public void execute(WorkflowContext context) throws Exception {
+    var sourcePath = source.toAbsolutePath();
+    var targetPath = target.toAbsolutePath();
+    switch (compression) {
+      case zip:
+        decompressZip(sourcePath, targetPath);
+        break;
+      case targz:
+        decompressTarGz(sourcePath, targetPath);
+        break;
+      case tarbz2:
+        decompressTarBz2(sourcePath, targetPath);
+        break;
+      case gzip:
+        decompressGzip(sourcePath, targetPath);
+        break;
+      case bzip2:
+        decompressBzip2(sourcePath, targetPath);
+        break;
+    }
+
+  }
+
+  public static void decompressBzip2(Path sourcePath, Path targetPath) throws 
IOException {
+    try (var zis =
+        new BZip2CompressorInputStream(new 
BufferedInputStream(Files.newInputStream(sourcePath)))) {
+      Files.copy(zis, targetPath, StandardCopyOption.REPLACE_EXISTING);
+    }
+  }
+
+  public static void decompressGzip(Path sourcePath, Path targetPath) throws 
IOException {
+    try (var zis = new GZIPInputStream(new 
BufferedInputStream(Files.newInputStream(sourcePath)))) {
+      Files.copy(zis, targetPath, StandardCopyOption.REPLACE_EXISTING);
+    }
+  }
+
+  public static void decompressTarGz(Path sourcePath, Path targetPath) throws 
IOException {
+    try (
+        GZIPInputStream gzipInputStream =
+            new GZIPInputStream(new 
BufferedInputStream(Files.newInputStream(sourcePath)));
+        TarArchiveInputStream tarInputStream = new 
TarArchiveInputStream(gzipInputStream)) {
+      TarArchiveEntry entry;
+      while ((entry = (TarArchiveEntry) tarInputStream.getNextEntry()) != 
null) {
+        var path = targetPath.resolve(entry.getName());
+        if (entry.isDirectory()) {
+          Files.createDirectories(path);
+        } else {
+          Files.createDirectories(path.getParent());
+          try (BufferedOutputStream outputStream =
+              new BufferedOutputStream(Files.newOutputStream(path))) {
+            int bytesRead;
+            byte[] buffer = new byte[4096];
+            while ((bytesRead = tarInputStream.read(buffer)) != -1) {
+              outputStream.write(buffer, 0, bytesRead);
+            }
+          }
+        }
+      }
+    }
+  }
+
+  public static void decompressTarBz2(Path sourcePath, Path targetPath) throws 
IOException {
+    try (
+        BZip2CompressorInputStream gzipInputStream = new 
BZip2CompressorInputStream(
+            new BufferedInputStream(Files.newInputStream(sourcePath)));

Review Comment:
   ## Potential input resource leak
   
   This BufferedInputStream is not always closed on method exit.
   
   [Show more 
details](https://github.com/apache/incubator-baremaps/security/code-scanning/797)



##########
baremaps-core/src/main/java/org/apache/baremaps/workflow/tasks/DecompressFile.java:
##########
@@ -0,0 +1,149 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not 
use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software 
distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
KIND, either express
+ * or implied. See the License for the specific language governing permissions 
and limitations under
+ * the License.
+ */
+
+package org.apache.baremaps.workflow.tasks;
+
+import java.io.*;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardCopyOption;
+import java.nio.file.StandardOpenOption;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.ZipFile;
+import org.apache.baremaps.workflow.Task;
+import org.apache.baremaps.workflow.WorkflowContext;
+import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
+import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
+import 
org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public record DecompressFile(Path source, Path target, Compression 
compression) implements Task {
+
+  public enum Compression {
+    zip,
+    targz,
+    tarbz2,
+    gzip,
+    bzip2
+  }
+
+  private static final Logger logger = 
LoggerFactory.getLogger(UngzipFile.class);
+
+  @Override
+  public void execute(WorkflowContext context) throws Exception {
+    var sourcePath = source.toAbsolutePath();
+    var targetPath = target.toAbsolutePath();
+    switch (compression) {
+      case zip:
+        decompressZip(sourcePath, targetPath);
+        break;
+      case targz:
+        decompressTarGz(sourcePath, targetPath);
+        break;
+      case tarbz2:
+        decompressTarBz2(sourcePath, targetPath);
+        break;
+      case gzip:
+        decompressGzip(sourcePath, targetPath);
+        break;
+      case bzip2:
+        decompressBzip2(sourcePath, targetPath);
+        break;
+    }
+
+  }
+
+  public static void decompressBzip2(Path sourcePath, Path targetPath) throws 
IOException {
+    try (var zis =
+        new BZip2CompressorInputStream(new 
BufferedInputStream(Files.newInputStream(sourcePath)))) {

Review Comment:
   ## Potential input resource leak
   
   This BufferedInputStream is not always closed on method exit.
   
   [Show more 
details](https://github.com/apache/incubator-baremaps/security/code-scanning/794)



##########
baremaps-core/src/main/java/org/apache/baremaps/workflow/tasks/DecompressFile.java:
##########
@@ -0,0 +1,149 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not 
use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software 
distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
KIND, either express
+ * or implied. See the License for the specific language governing permissions 
and limitations under
+ * the License.
+ */
+
+package org.apache.baremaps.workflow.tasks;
+
+import java.io.*;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardCopyOption;
+import java.nio.file.StandardOpenOption;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.ZipFile;
+import org.apache.baremaps.workflow.Task;
+import org.apache.baremaps.workflow.WorkflowContext;
+import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
+import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
+import 
org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public record DecompressFile(Path source, Path target, Compression 
compression) implements Task {
+
+  public enum Compression {
+    zip,
+    targz,
+    tarbz2,
+    gzip,
+    bzip2
+  }
+
+  private static final Logger logger = 
LoggerFactory.getLogger(UngzipFile.class);
+
+  @Override
+  public void execute(WorkflowContext context) throws Exception {
+    var sourcePath = source.toAbsolutePath();
+    var targetPath = target.toAbsolutePath();
+    switch (compression) {
+      case zip:
+        decompressZip(sourcePath, targetPath);
+        break;
+      case targz:
+        decompressTarGz(sourcePath, targetPath);
+        break;
+      case tarbz2:
+        decompressTarBz2(sourcePath, targetPath);
+        break;
+      case gzip:
+        decompressGzip(sourcePath, targetPath);
+        break;
+      case bzip2:
+        decompressBzip2(sourcePath, targetPath);
+        break;
+    }
+
+  }
+
+  public static void decompressBzip2(Path sourcePath, Path targetPath) throws 
IOException {
+    try (var zis =
+        new BZip2CompressorInputStream(new 
BufferedInputStream(Files.newInputStream(sourcePath)))) {
+      Files.copy(zis, targetPath, StandardCopyOption.REPLACE_EXISTING);
+    }
+  }
+
+  public static void decompressGzip(Path sourcePath, Path targetPath) throws 
IOException {
+    try (var zis = new GZIPInputStream(new 
BufferedInputStream(Files.newInputStream(sourcePath)))) {

Review Comment:
   ## Potential input resource leak
   
   This BufferedInputStream is not always closed on method exit.
   
   [Show more 
details](https://github.com/apache/incubator-baremaps/security/code-scanning/795)



##########
baremaps-core/src/test/java/org/apache/baremaps/workflow/tasks/DecompressFileTest.java:
##########
@@ -0,0 +1,63 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not 
use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software 
distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
KIND, either express
+ * or implied. See the License for the specific language governing permissions 
and limitations under
+ * the License.
+ */
+
+package org.apache.baremaps.workflow.tasks;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import org.apache.baremaps.testing.TestFiles;
+import org.junit.jupiter.api.Test;
+
+class DecompressFileTest {

Review Comment:
   ## Unused classes and interfaces
   
   Unused class: DecompressFileTest is not referenced within this codebase. If 
not used as an external API it should be removed.
   
   [Show more 
details](https://github.com/apache/incubator-baremaps/security/code-scanning/798)



##########
baremaps-core/src/main/java/org/apache/baremaps/workflow/tasks/DecompressFile.java:
##########
@@ -0,0 +1,149 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not 
use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software 
distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
KIND, either express
+ * or implied. See the License for the specific language governing permissions 
and limitations under
+ * the License.
+ */
+
+package org.apache.baremaps.workflow.tasks;
+
+import java.io.*;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardCopyOption;
+import java.nio.file.StandardOpenOption;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.ZipFile;
+import org.apache.baremaps.workflow.Task;
+import org.apache.baremaps.workflow.WorkflowContext;
+import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
+import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
+import 
org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public record DecompressFile(Path source, Path target, Compression 
compression) implements Task {
+
+  public enum Compression {
+    zip,
+    targz,
+    tarbz2,
+    gzip,
+    bzip2
+  }
+
+  private static final Logger logger = 
LoggerFactory.getLogger(UngzipFile.class);
+
+  @Override
+  public void execute(WorkflowContext context) throws Exception {
+    var sourcePath = source.toAbsolutePath();
+    var targetPath = target.toAbsolutePath();
+    switch (compression) {
+      case zip:
+        decompressZip(sourcePath, targetPath);
+        break;
+      case targz:
+        decompressTarGz(sourcePath, targetPath);
+        break;
+      case tarbz2:
+        decompressTarBz2(sourcePath, targetPath);
+        break;
+      case gzip:
+        decompressGzip(sourcePath, targetPath);
+        break;
+      case bzip2:
+        decompressBzip2(sourcePath, targetPath);
+        break;
+    }
+
+  }
+
+  public static void decompressBzip2(Path sourcePath, Path targetPath) throws 
IOException {
+    try (var zis =
+        new BZip2CompressorInputStream(new 
BufferedInputStream(Files.newInputStream(sourcePath)))) {
+      Files.copy(zis, targetPath, StandardCopyOption.REPLACE_EXISTING);
+    }
+  }
+
+  public static void decompressGzip(Path sourcePath, Path targetPath) throws 
IOException {
+    try (var zis = new GZIPInputStream(new 
BufferedInputStream(Files.newInputStream(sourcePath)))) {
+      Files.copy(zis, targetPath, StandardCopyOption.REPLACE_EXISTING);
+    }
+  }
+
+  public static void decompressTarGz(Path sourcePath, Path targetPath) throws 
IOException {
+    try (
+        GZIPInputStream gzipInputStream =
+            new GZIPInputStream(new 
BufferedInputStream(Files.newInputStream(sourcePath)));
+        TarArchiveInputStream tarInputStream = new 
TarArchiveInputStream(gzipInputStream)) {
+      TarArchiveEntry entry;
+      while ((entry = (TarArchiveEntry) tarInputStream.getNextEntry()) != 
null) {
+        var path = targetPath.resolve(entry.getName());
+        if (entry.isDirectory()) {
+          Files.createDirectories(path);
+        } else {
+          Files.createDirectories(path.getParent());
+          try (BufferedOutputStream outputStream =
+              new BufferedOutputStream(Files.newOutputStream(path))) {
+            int bytesRead;
+            byte[] buffer = new byte[4096];
+            while ((bytesRead = tarInputStream.read(buffer)) != -1) {
+              outputStream.write(buffer, 0, bytesRead);
+            }
+          }
+        }
+      }
+    }
+  }
+
+  public static void decompressTarBz2(Path sourcePath, Path targetPath) throws 
IOException {
+    try (
+        BZip2CompressorInputStream gzipInputStream = new 
BZip2CompressorInputStream(
+            new BufferedInputStream(Files.newInputStream(sourcePath)));
+        TarArchiveInputStream tarInputStream = new 
TarArchiveInputStream(gzipInputStream)) {
+      TarArchiveEntry entry;
+      while ((entry = (TarArchiveEntry) tarInputStream.getNextEntry()) != 
null) {
+        var path = targetPath.resolve(entry.getName());
+        if (entry.isDirectory()) {
+          Files.createDirectories(path);
+        } else {
+          Files.createDirectories(path.getParent());
+          try (BufferedOutputStream outputStream =
+              new BufferedOutputStream(Files.newOutputStream(path))) {
+            int bytesRead;
+            byte[] buffer = new byte[4096];
+            while ((bytesRead = tarInputStream.read(buffer)) != -1) {
+              outputStream.write(buffer, 0, bytesRead);
+            }
+          }
+        }
+      }
+    }
+  }
+
+  public static void decompressZip(Path sourcePath, Path targetPath) throws 
IOException {
+    try (var zipFile = new ZipFile(sourcePath.toFile())) {
+      var entries = zipFile.entries();
+      while (entries.hasMoreElements()) {
+        var entry = entries.nextElement();
+        var path = targetPath.resolve(entry.getName());

Review Comment:
   ## Arbitrary file access during archive extraction ("Zip Slip")
   
   Unsanitized archive entry, which may contain '..', is used in a [file system 
operation](1).
   Unsanitized archive entry, which may contain '..', is used in a [file system 
operation](2).
   Unsanitized archive entry, which may contain '..', is used in a [file system 
operation](3).
   
   [Show more 
details](https://github.com/apache/incubator-baremaps/security/code-scanning/793)



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to