]> git.ipfire.org Git - thirdparty/zstd.git/commitdiff
stdin multiple file fixes (#3222)
authorYonatan Komornik <11005061+yoniko@users.noreply.github.com>
Fri, 29 Jul 2022 23:13:07 +0000 (16:13 -0700)
committerGitHub <noreply@github.com>
Fri, 29 Jul 2022 23:13:07 +0000 (16:13 -0700)
* Fixes for https://github.com/facebook/zstd/issues/3206 - bugs when handling stdin as part of multiple files.

* new line at end of multiple-files.sh

programs/fileio.c
programs/util.c
programs/util.h
programs/zstdcli.c
tests/cli-tests/compression/multiple-files.sh [new file with mode: 0755]
tests/cli-tests/compression/multiple-files.sh.stdout.exact [new file with mode: 0644]

index 7a479069a0729d8d27e50c15f751e049acc89d5a..27daeca9330e01c2c3fa3fe819d1f313d7577ff2 100644 (file)
@@ -1796,6 +1796,11 @@ FIO_determineCompressedName(const char* srcFileName, const char* outDirName, con
     char* outDirFilename = NULL;
     size_t sfnSize = strlen(srcFileName);
     size_t const srcSuffixLen = strlen(suffix);
+
+    if(!strcmp(srcFileName, stdinmark)) {
+        return stdoutmark;
+    }
+
     if (outDirName) {
         outDirFilename = FIO_createFilename_fromOutDir(srcFileName, outDirName, srcSuffixLen);
         sfnSize = strlen(outDirFilename);
@@ -2579,6 +2584,11 @@ FIO_determineDstName(const char* srcFileName, const char* outDirName)
 
     size_t srcSuffixLen;
     const char* const srcSuffix = strrchr(srcFileName, '.');
+
+    if(!strcmp(srcFileName, stdinmark)) {
+        return stdoutmark;
+    }
+
     if (srcSuffix == NULL) {
         DISPLAYLEVEL(1,
             "zstd: %s: unknown suffix (%s expected). "
index 50db70fd447bf9e0f6f8360971169c86a9953f8c..c925adabc9e3e351bf78b38bac0b1f979f119cd9 100644 (file)
@@ -509,6 +509,16 @@ FileNamesTable* UTIL_allocateFileNamesTable(size_t tableSize)
     return fnt;
 }
 
+int UTIL_searchFileNamesTable(FileNamesTable* table, char const* name) {
+    size_t i;
+    for(i=0 ;i < table->tableSize; i++) {
+        if(!strcmp(table->fileNames[i], name)) {
+            return (int)i;
+        }
+    }
+    return -1;
+}
+
 void UTIL_refFilename(FileNamesTable* fnt, const char* filename)
 {
     assert(fnt->tableSize < fnt->tableCapacity);
index add165d57ce934923810e4f97639728a2ad029b1..faf8c9f11cbc8a33c683fcecd9c5db43160fcdba 100644 (file)
@@ -269,6 +269,11 @@ UTIL_createFNT_fromROTable(const char** filenames, size_t nbFilenames);
  */
 FileNamesTable* UTIL_allocateFileNamesTable(size_t tableSize);
 
+/*! UTIL_searchFileNamesTable() :
+ *  Searched through entries in FileNamesTable for a specific name.
+ * @return : index of entry if found or -1 if not found
+ */
+int UTIL_searchFileNamesTable(FileNamesTable* table, char const* name);
 
 /*! UTIL_refFilename() :
  *  Add a reference to read-only name into @fnt table.
index 372b7d7a30633f76849c5352161d84984824fcd3..71b0dbefee0063f00f9fc8304f0cbcc9466e9644 100644 (file)
@@ -1391,19 +1391,19 @@ int main(int argCount, const char* argv[])
        UTIL_refFilename(filenames, stdinmark);
     }
 
-    if (!strcmp(filenames->fileNames[0], stdinmark) && !outFileName)
+    if (filenames->tableSize == 1 && !strcmp(filenames->fileNames[0], stdinmark) && !outFileName)
         outFileName = stdoutmark;  /* when input is stdin, default output is stdout */
 
     /* Check if input/output defined as console; trigger an error in this case */
     if (!forceStdin
-     && !strcmp(filenames->fileNames[0], stdinmark)
+     && (UTIL_searchFileNamesTable(filenames, stdinmark) != -1)
      && IS_CONSOLE(stdin) ) {
         DISPLAYLEVEL(1, "stdin is a console, aborting\n");
         CLEAN_RETURN(1);
     }
-    if ( outFileName && !strcmp(outFileName, stdoutmark)
+    if ( (!outFileName || !strcmp(outFileName, stdoutmark))
       && IS_CONSOLE(stdout)
-      && !strcmp(filenames->fileNames[0], stdinmark)
+      && (UTIL_searchFileNamesTable(filenames, stdinmark) != -1)
       && !forceStdout
       && operation!=zom_decompress ) {
         DISPLAYLEVEL(1, "stdout is a console, aborting\n");
diff --git a/tests/cli-tests/compression/multiple-files.sh b/tests/cli-tests/compression/multiple-files.sh
new file mode 100755 (executable)
index 0000000..aeb74cf
--- /dev/null
@@ -0,0 +1,21 @@
+#!/bin/sh
+set -e
+
+# setup
+echo "file1" > file1
+echo "file2" > file2
+
+echo "Test zstd ./file1 - file2"
+rm -f ./file*.zst
+echo "stdin" | zstd ./file1 - ./file2 | zstd -d
+cat file1.zst | zstd -d
+cat file2.zst | zstd -d
+
+echo "Test zstd -d ./file1.zst - file2.zst"
+rm ./file1 ./file2
+echo "stdin" | zstd - | zstd -d ./file1.zst - file2.zst
+cat file1
+cat file2
+
+echo "zstd -d ./file1.zst - file2.zst -c"
+echo "stdin" | zstd | zstd -d ./file1.zst - file2.zst -c
diff --git a/tests/cli-tests/compression/multiple-files.sh.stdout.exact b/tests/cli-tests/compression/multiple-files.sh.stdout.exact
new file mode 100644 (file)
index 0000000..aad61d6
--- /dev/null
@@ -0,0 +1,12 @@
+Test zstd ./file1 - file2
+stdin
+file1
+file2
+Test zstd -d ./file1.zst - file2.zst
+stdin
+file1
+file2
+zstd -d ./file1.zst - file2.zst -c
+file1
+stdin
+file2