Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 48 additions & 15 deletions programs/fileio.c
Original file line number Diff line number Diff line change
Expand Up @@ -1195,6 +1195,10 @@ FIO_createFilename_fromOutDir(const char* path, const char* outDirName, const si
const char* filenameStart;
char separator;
char* result;
size_t outDirLen;
size_t filenameLen;
size_t separatorLen;
size_t resultCapacity;

#if defined(_MSC_VER) || defined(__MINGW32__) || defined (__MSVCRT__) /* windows support */
separator = '\\';
Expand All @@ -1207,18 +1211,27 @@ FIO_createFilename_fromOutDir(const char* path, const char* outDirName, const si
filenameStart = extractFilename(filenameStart, '/'); /* sometimes, '/' separator is also used on Windows (mingw+msys2) */
#endif

result = (char*) calloc(1, strlen(outDirName) + 1 + strlen(filenameStart) + suffixLen + 1);
outDirLen = strlen(outDirName);
filenameLen = strlen(filenameStart);
separatorLen = (outDirLen == 0 || outDirName[outDirLen - 1] == separator) ? 0 : 1;

if (outDirLen > (size_t)-1 - separatorLen
|| outDirLen + separatorLen > (size_t)-1 - filenameLen
|| outDirLen + separatorLen + filenameLen > (size_t)-1 - suffixLen - 1) {
EXM_THROW(30, "zstd: FIO_createFilename_fromOutDir: output path too large");
}
resultCapacity = outDirLen + separatorLen + filenameLen + suffixLen + 1;

result = (char*)calloc(1, resultCapacity);
if (!result) {
EXM_THROW(30, "zstd: FIO_createFilename_fromOutDir: %s", strerror(errno));
}

memcpy(result, outDirName, strlen(outDirName));
if (outDirName[strlen(outDirName)-1] == separator) {
memcpy(result + strlen(outDirName), filenameStart, strlen(filenameStart));
} else {
memcpy(result + strlen(outDirName), &separator, 1);
memcpy(result + strlen(outDirName) + 1, filenameStart, strlen(filenameStart));
memcpy(result, outDirName, outDirLen);
if (separatorLen) {
memcpy(result + outDirLen, &separator, 1);
}
memcpy(result + outDirLen + separatorLen, filenameStart, filenameLen);

return result;
}
Expand Down Expand Up @@ -2422,21 +2435,31 @@ FIO_determineCompressedName(const char* srcFileName, const char* outDirName, con
char* outDirFilename = NULL;
size_t sfnSize = strlen(srcFileName);
size_t const srcSuffixLen = strlen(suffix);
size_t requiredCapacity;

if(!strcmp(srcFileName, stdinmark)) {
return stdoutmark;
}

if (outDirName) {
outDirFilename = FIO_createFilename_fromOutDir(srcFileName, outDirName, srcSuffixLen);
sfnSize = strlen(outDirFilename);
assert(outDirFilename != NULL);
sfnSize = strlen(outDirFilename);
}

if (sfnSize > (size_t)-1 - srcSuffixLen - 1) {
EXM_THROW(30, "zstd: destination filename too large");
}
requiredCapacity = sfnSize + srcSuffixLen + 1;

if (dfnbCapacity <= sfnSize+srcSuffixLen+1) {
if (dfnbCapacity <= requiredCapacity) {
/* resize buffer for dstName */
free(dstFileNameBuffer);
dfnbCapacity = sfnSize + srcSuffixLen + 30;
if (requiredCapacity > (size_t)-1 - FNSPACE) {
dfnbCapacity = requiredCapacity;
} else {
dfnbCapacity = requiredCapacity + FNSPACE;
}
dstFileNameBuffer = (char*)malloc(dfnbCapacity);
if (!dstFileNameBuffer) {
EXM_THROW(30, "zstd: %s", strerror(errno));
Expand Down Expand Up @@ -3252,6 +3275,7 @@ FIO_determineDstName(const char* srcFileName, const char* outDirName)
static size_t dfnbCapacity = 0;
static char* dstFileNameBuffer = NULL; /* using static allocation : this function cannot be multi-threaded */
size_t dstFileNameEndPos;
size_t requiredCapacity;
char* outDirFilename = NULL;
const char* dstSuffix = "";
size_t dstSuffixLen = 0;
Expand Down Expand Up @@ -3301,14 +3325,24 @@ FIO_determineDstName(const char* srcFileName, const char* outDirName)

if (outDirName) {
outDirFilename = FIO_createFilename_fromOutDir(srcFileName, outDirName, 0);
sfnSize = strlen(outDirFilename);
assert(outDirFilename != NULL);
sfnSize = strlen(outDirFilename);
}

if (dfnbCapacity+srcSuffixLen <= sfnSize+1+dstSuffixLen) {
dstFileNameEndPos = sfnSize - srcSuffixLen;
if (dstFileNameEndPos > (size_t)-1 - dstSuffixLen - 1) {
EXM_THROW(74, "%s : destination filename too large", strerror(errno));
}
requiredCapacity = dstFileNameEndPos + dstSuffixLen + 1;

if (dfnbCapacity <= requiredCapacity) {
/* allocate enough space to write dstFilename into it */
free(dstFileNameBuffer);
dfnbCapacity = sfnSize + 20;
if (requiredCapacity > (size_t)-1 - FNSPACE) {
dfnbCapacity = requiredCapacity;
} else {
dfnbCapacity = requiredCapacity + FNSPACE;
}
dstFileNameBuffer = (char*)malloc(dfnbCapacity);
if (dstFileNameBuffer==NULL)
EXM_THROW(74, "%s : not enough memory for dstFileName",
Expand All @@ -3317,7 +3351,6 @@ FIO_determineDstName(const char* srcFileName, const char* outDirName)

/* return dst name == src name truncated from suffix */
assert(dstFileNameBuffer != NULL);
dstFileNameEndPos = sfnSize - srcSuffixLen;
if (outDirFilename) {
memcpy(dstFileNameBuffer, outDirFilename, dstFileNameEndPos);
free(outDirFilename);
Expand All @@ -3327,7 +3360,7 @@ FIO_determineDstName(const char* srcFileName, const char* outDirName)

/* The short tar extensions tzst, tgz, txz and tlz4 files should have "tar"
* extension on decompression. Also writes terminating null. */
strcpy(dstFileNameBuffer + dstFileNameEndPos, dstSuffix);
memcpy(dstFileNameBuffer + dstFileNameEndPos, dstSuffix, dstSuffixLen + 1);
return dstFileNameBuffer;

/* note : dstFileNameBuffer memory is not going to be free */
Expand Down