This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-compress.git


The following commit(s) were added to refs/heads/master by this push:
     new 632434ccb Throw an IllegalArgumentException when a file name or 
comment in gzip parameters encodes to a byte array with a 0 byte (#618)
632434ccb is described below

commit 632434ccbede8b2bd2e0a5bb3ff04844ced8355b
Author: ddeschenes-1 <54910444+ddeschene...@users.noreply.github.com>
AuthorDate: Sat Nov 30 08:23:06 2024 -0500

    Throw an IllegalArgumentException when a file name or comment in gzip 
parameters encodes to a byte array with a 0 byte (#618)
    
    * (doc) Added safety check to avoid corrupting byte '0' in filename or 
comment of gzip parameters.
    
    * Remove unnecessary commas; normalize formatting
    
    * Collapse double `if` into a single `if` (and reuse isNotEmpty())
    
    ---------
    
    Co-authored-by: Danny Deschenes <ddesche...@towerlogic.com>
    Co-authored-by: Gary Gregory <garydgreg...@users.noreply.github.com>
---
 .../compress/compressors/gzip/GzipParameters.java  | 19 ++++++++--
 .../compressors/gzip/GzipParametersTest.java       | 44 ++++++++++++++++++++++
 2 files changed, 59 insertions(+), 4 deletions(-)

diff --git 
a/src/main/java/org/apache/commons/compress/compressors/gzip/GzipParameters.java
 
b/src/main/java/org/apache/commons/compress/compressors/gzip/GzipParameters.java
index 07ce38f26..4588e8ad9 100644
--- 
a/src/main/java/org/apache/commons/compress/compressors/gzip/GzipParameters.java
+++ 
b/src/main/java/org/apache/commons/compress/compressors/gzip/GzipParameters.java
@@ -25,7 +25,8 @@ import java.time.Instant;
 import java.util.zip.Deflater;
 
 import org.apache.commons.io.Charsets;
-
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.StringUtils;
 
 /**
  * Parameters for the GZIP compressor.
@@ -298,6 +299,13 @@ public class GzipParameters {
     private int bufferSize = 512;
     private int deflateStrategy = Deflater.DEFAULT_STRATEGY;
 
+    private String requireNonNulByte(final String text) {
+        if (StringUtils.isNotEmpty(text) && 
ArrayUtils.contains(text.getBytes(fileNameCharset), (byte) 0)) {
+            throw new IllegalArgumentException("String encoded in Charset '" + 
fileNameCharset + "' contains the nul byte 0 which is not supported in gzip.");
+        }
+        return text;
+    }
+
     /**
      * Gets size of the buffer used to retrieve compressed data.
      *
@@ -448,9 +456,10 @@ public class GzipParameters {
      * Sets an arbitrary user-defined comment.
      *
      * @param comment a user-defined comment.
+     * @throws IllegalArgumentException if the encoded bytes would contain a 
nul byte '\0' reserved for gzip field termination.
      */
     public void setComment(final String comment) {
-        this.comment = comment;
+        this.comment = requireNonNulByte(comment);
     }
 
     /**
@@ -495,20 +504,22 @@ public class GzipParameters {
      * Sets the name of the compressed file.
      *
      * @param fileName the name of the file without the directory path
+     * @throws IllegalArgumentException if the encoded bytes would contain a 
nul byte '\0' reserved for gzip field termination.
      * @deprecated Use {@link #setFileName(String)}.
      */
     @Deprecated
     public void setFilename(final String fileName) {
-        this.fileName = fileName;
+        setFileName(fileName);
     }
 
     /**
      * Sets the name of the compressed file.
      *
      * @param fileName the name of the file without the directory path
+     * @throws IllegalArgumentException if the encoded bytes would contain a 
nul byte '\0' reserved for gzip field termination.
      */
     public void setFileName(final String fileName) {
-        this.fileName = fileName;
+        this.fileName = requireNonNulByte(fileName);
     }
 
     /**
diff --git 
a/src/test/java/org/apache/commons/compress/compressors/gzip/GzipParametersTest.java
 
b/src/test/java/org/apache/commons/compress/compressors/gzip/GzipParametersTest.java
index 30f1b09a9..d2febb1d9 100644
--- 
a/src/test/java/org/apache/commons/compress/compressors/gzip/GzipParametersTest.java
+++ 
b/src/test/java/org/apache/commons/compress/compressors/gzip/GzipParametersTest.java
@@ -20,11 +20,15 @@
 package org.apache.commons.compress.compressors.gzip;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
+import java.nio.charset.Charset;
 import java.util.zip.Deflater;
 
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
 
 /**
  * Tests {@link GzipParameters}.
@@ -46,4 +50,44 @@ public class GzipParametersTest {
         gzipParameters.setOS(GzipParameters.OS.Z_SYSTEM);
         assertTrue(gzipParameters.toString().contains("Z_SYSTEM"));
     }
+
+    @ParameterizedTest
+    //@formatter:off
+    @CsvSource({
+        "          , helloworld",
+        "          , helloéworld",
+        "ISO-8859-1, helloworld",
+        "ISO-8859-1, helloéworld",
+        "UTF-8     , helloworld",
+        "UTF-8     , helloéworld"
+    })
+    //@formatter:on
+    public void testLegalCommentOrFileName(final String charset, final String 
text) {
+        final GzipParameters p = new GzipParameters();
+        if (charset != null) {
+            p.setFileNameCharset(Charset.forName(charset));
+        }
+        p.setComment(text);
+        p.setFilename(text);
+        p.setFileName(text);
+    }
+
+    @ParameterizedTest
+    //@formatter:off
+    @CsvSource({
+        "          , hello\0world, false",
+        "ISO-8859-1, hello\0world, false",
+        "UTF-8     , hello\0world, false",
+        "UTF-16BE  , helloworld, false"
+    })
+    //@formatter:on
+    public void testIllegalCommentOrFileName(final String charset, final 
String text) {
+        final GzipParameters p = new GzipParameters();
+        if (charset != null) {
+            p.setFileNameCharset(Charset.forName(charset));
+        }
+        assertThrows(IllegalArgumentException.class, () -> p.setComment(text));
+        assertThrows(IllegalArgumentException.class, () -> 
p.setFilename(text));
+        assertThrows(IllegalArgumentException.class, () -> 
p.setFileName(text));
+    }
 }

Reply via email to