Merge pull request #1917 from facebook/recurse_fix

fix recent issue combining -r with empty list of input files
This commit is contained in:
Yann Collet 2019-12-02 15:38:14 -08:00 committed by GitHub
commit cc3252acce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 41 additions and 23 deletions

View File

@ -362,18 +362,24 @@ UTIL_createFileNamesTable_fromFileName(const char* inputFileName)
} }
} }
FileNamesTable* static FileNamesTable*
UTIL_assembleFileNamesTable(const char** filenames, size_t tableSize, char* buf) UTIL_assembleFileNamesTable2(const char** filenames, size_t tableSize, size_t tableCapacity, char* buf)
{ {
FileNamesTable* const table = (FileNamesTable*) malloc(sizeof(*table)); FileNamesTable* const table = (FileNamesTable*) malloc(sizeof(*table));
CONTROL(table != NULL); CONTROL(table != NULL);
table->fileNames = filenames; table->fileNames = filenames;
table->buf = buf; table->buf = buf;
table->tableSize = tableSize; table->tableSize = tableSize;
table->tableCapacity = tableSize; table->tableCapacity = tableCapacity;
return table; return table;
} }
FileNamesTable*
UTIL_assembleFileNamesTable(const char** filenames, size_t tableSize, char* buf)
{
return UTIL_assembleFileNamesTable2(filenames, tableSize, tableSize, buf);
}
void UTIL_freeFileNamesTable(FileNamesTable* table) void UTIL_freeFileNamesTable(FileNamesTable* table)
{ {
if (table==NULL) return; if (table==NULL) return;
@ -652,10 +658,11 @@ UTIL_createExpandedFNT(const char** inputNames, size_t nbIfns, int followLinks)
if (buf == NULL) return NULL; if (buf == NULL) return NULL;
} } } } } }
if (nbFiles == 0) { free(buf); return NULL; } /* note : even if nbFiles==0, function returns a valid, though empty, FileNamesTable* object */
{ size_t ifnNb, pos; { size_t ifnNb, pos;
const char** const fileNamesTable = (const char**)malloc((nbFiles + 1) * sizeof(*fileNamesTable)); size_t const fntCapacity = nbFiles + 1; /* minimum 1, allows adding one reference, typically stdin */
const char** const fileNamesTable = (const char**)malloc(fntCapacity * sizeof(*fileNamesTable));
if (!fileNamesTable) { free(buf); return NULL; } if (!fileNamesTable) { free(buf); return NULL; }
for (ifnNb = 0, pos = 0; ifnNb < nbFiles; ifnNb++) { for (ifnNb = 0, pos = 0; ifnNb < nbFiles; ifnNb++) {
@ -663,7 +670,7 @@ UTIL_createExpandedFNT(const char** inputNames, size_t nbIfns, int followLinks)
if (buf + pos > bufend) { free(buf); free((void*)fileNamesTable); return NULL; } if (buf + pos > bufend) { free(buf); free((void*)fileNamesTable); return NULL; }
pos += strlen(fileNamesTable[ifnNb]) + 1; pos += strlen(fileNamesTable[ifnNb]) + 1;
} }
return UTIL_assembleFileNamesTable(fileNamesTable, nbFiles, buf); return UTIL_assembleFileNamesTable2(fileNamesTable, nbFiles, fntCapacity, buf);
} }
} }
@ -671,6 +678,7 @@ UTIL_createExpandedFNT(const char** inputNames, size_t nbIfns, int followLinks)
void UTIL_expandFNT(FileNamesTable** fnt, int followLinks) void UTIL_expandFNT(FileNamesTable** fnt, int followLinks)
{ {
FileNamesTable* const newFNT = UTIL_createExpandedFNT((*fnt)->fileNames, (*fnt)->tableSize, followLinks); FileNamesTable* const newFNT = UTIL_createExpandedFNT((*fnt)->fileNames, (*fnt)->tableSize, followLinks);
CONTROL(newFNT != NULL);
UTIL_freeFileNamesTable(*fnt); UTIL_freeFileNamesTable(*fnt);
*fnt = newFNT; *fnt = newFNT;
} }

View File

@ -27,10 +27,12 @@
**************************************/ **************************************/
#include "platform.h" /* IS_CONSOLE, PLATFORM_POSIX_VERSION */ #include "platform.h" /* IS_CONSOLE, PLATFORM_POSIX_VERSION */
#include "util.h" /* UTIL_HAS_CREATEFILELIST, UTIL_createFileList */ #include "util.h" /* UTIL_HAS_CREATEFILELIST, UTIL_createFileList */
#include <stdio.h> /* fprintf(), stdin, stdout, stderr */
#include <stdlib.h> /* getenv */ #include <stdlib.h> /* getenv */
#include <string.h> /* strcmp, strlen */ #include <string.h> /* strcmp, strlen */
#include <stdio.h> /* fprintf(), stdin, stdout, stderr */
#include <errno.h> /* errno */ #include <errno.h> /* errno */
#include <assert.h> /* assert */
#include "fileio.h" /* stdinmark, stdoutmark, ZSTD_EXTENSION */ #include "fileio.h" /* stdinmark, stdoutmark, ZSTD_EXTENSION */
#ifndef ZSTD_NOBENCH #ifndef ZSTD_NOBENCH
# include "benchzstd.h" /* BMK_benchFiles */ # include "benchzstd.h" /* BMK_benchFiles */
@ -508,10 +510,12 @@ static void printVersion(void)
/* Environment variables for parameter setting */ /* Environment variables for parameter setting */
#define ENV_CLEVEL "ZSTD_CLEVEL" #define ENV_CLEVEL "ZSTD_CLEVEL"
/* functions that pick up environment variables */ /* pick up environment variables
* requirement : g_displayOut must be set */
static int init_cLevel(void) { static int init_cLevel(void) {
const char* const env = getenv(ENV_CLEVEL); const char* const env = getenv(ENV_CLEVEL);
if (env) { assert(g_displayOut == stderr); /* to print error messages */
if (env != NULL) {
const char* ptr = env; const char* ptr = env;
int sign = 1; int sign = 1;
if (*ptr == '-') { if (*ptr == '-') {
@ -528,8 +532,7 @@ static int init_cLevel(void) {
return ZSTDCLI_CLEVEL_DEFAULT; return ZSTDCLI_CLEVEL_DEFAULT;
} else if (*ptr == 0) { } else if (*ptr == 0) {
return sign * (int)absLevel; return sign * (int)absLevel;
} } }
}
DISPLAYLEVEL(2, "Ignore environment variable setting %s=%s: not a valid integer value \n", ENV_CLEVEL, env); DISPLAYLEVEL(2, "Ignore environment variable setting %s=%s: not a valid integer value \n", ENV_CLEVEL, env);
} }
@ -543,14 +546,14 @@ typedef enum { zom_compress, zom_decompress, zom_test, zom_bench, zom_train, zom
#ifdef ZSTD_NOCOMPRESS #ifdef ZSTD_NOCOMPRESS
/* symbols from compression library are not defined and should not be invoked */ /* symbols from compression library are not defined and should not be invoked */
# define MINCLEVEL -50 # define MINCLEVEL -99
# define MAXCLEVEL 22 # define MAXCLEVEL 22
#else #else
# define MINCLEVEL ZSTD_minCLevel() # define MINCLEVEL ZSTD_minCLevel()
# define MAXCLEVEL ZSTD_maxCLevel() # define MAXCLEVEL ZSTD_maxCLevel()
#endif #endif
int main(int argCount, const char* argv[]) int main(int const argCount, const char* argv[])
{ {
int argNb, int argNb,
followLinks = 0, followLinks = 0,
@ -582,7 +585,7 @@ int main(int argCount, const char* argv[])
zstd_operation_mode operation = zom_compress; zstd_operation_mode operation = zom_compress;
ZSTD_compressionParameters compressionParams; ZSTD_compressionParameters compressionParams;
int cLevel; int cLevel;
int cLevelLast = -1000000000; int cLevelLast = MINCLEVEL - 1; /* lower than minimum */
unsigned recursive = 0; unsigned recursive = 0;
unsigned memLimit = 0; unsigned memLimit = 0;
FileNamesTable* filenames = UTIL_allocateFileNamesTable((size_t)argCount); /* argCount >= 1 */ FileNamesTable* filenames = UTIL_allocateFileNamesTable((size_t)argCount); /* argCount >= 1 */
@ -613,9 +616,10 @@ int main(int argCount, const char* argv[])
/* init */ /* init */
(void)recursive; (void)cLevelLast; /* not used when ZSTD_NOBENCH set */ (void)recursive; (void)cLevelLast; /* not used when ZSTD_NOBENCH set */
(void)memLimit; /* not used when ZSTD_NODECOMPRESS set */ (void)memLimit; /* not used when ZSTD_NODECOMPRESS set */
assert(argCount >= 1);
if ((filenames==NULL) || (file_of_names==NULL)) { DISPLAY("zstd: allocation error \n"); exit(1); } if ((filenames==NULL) || (file_of_names==NULL)) { DISPLAY("zstd: allocation error \n"); exit(1); }
g_displayOut = stderr; g_displayOut = stderr;
cLevel = init_cLevel(); cLevel = init_cLevel(); /* must be done after setting g_displayOut, since some error message might be printed */
programName = lastNameFromPath(programName); programName = lastNameFromPath(programName);
#ifdef ZSTD_MULTITHREAD #ifdef ZSTD_MULTITHREAD
nbWorkers = 1; nbWorkers = 1;

View File

@ -251,6 +251,12 @@ test -f precompressedFilterTestDir/input.5.zst.zst
test -f precompressedFilterTestDir/input.6.zst.zst test -f precompressedFilterTestDir/input.6.zst.zst
println "Test completed" println "Test completed"
println "\n===> recursive mode test "
# combination of -r with empty list of input file
$ZSTD -c -r < tmp > tmp.zst
println "\n===> file removal" println "\n===> file removal"
$ZSTD -f --rm tmp $ZSTD -f --rm tmp
test ! -f tmp # tmp should no longer be present test ! -f tmp # tmp should no longer be present