1
0
mirror of https://github.com/facebook/zstd.git synced 2025-08-05 19:15:58 +03:00

Don't Block Removing File on Being Able to Read It

`open()`'s mode bits are only applied to files that are created by the call.
If the output file already exists, but is not readable, the `fopen()` would
fail, preventing us from removing it, which would mean that the file would
not end up with the correct permission bits.

It's not clear to me why the `fopen()` is there at all. `UTIL_isRegularFile()`
should be sufficient, AFAICT.
This commit is contained in:
W. Felix Handte
2021-03-08 17:49:20 -05:00
parent b87f97b3ea
commit 1fb10ba831
2 changed files with 28 additions and 16 deletions

View File

@@ -669,7 +669,6 @@ FIO_openDstFile(FIO_ctx_t* fCtx, FIO_prefs_t* const prefs,
if (UTIL_isRegularFile(dstFileName)) { if (UTIL_isRegularFile(dstFileName)) {
/* Check if destination file already exists */ /* Check if destination file already exists */
FILE* const fCheck = fopen( dstFileName, "rb" );
#if !defined(_WIN32) #if !defined(_WIN32)
/* this test does not work on Windows : /* this test does not work on Windows :
* `NUL` and `nul` are detected as regular files */ * `NUL` and `nul` are detected as regular files */
@@ -678,22 +677,20 @@ FIO_openDstFile(FIO_ctx_t* fCtx, FIO_prefs_t* const prefs,
dstFileName); dstFileName);
} }
#endif #endif
if (fCheck != NULL) { /* dst file exists, authorization prompt */ if (!prefs->overwrite) {
fclose(fCheck); if (g_display_prefs.displayLevel <= 1) {
if (!prefs->overwrite) { /* No interaction possible */
if (g_display_prefs.displayLevel <= 1) { DISPLAY("zstd: %s already exists; not overwritten \n",
/* No interaction possible */ dstFileName);
DISPLAY("zstd: %s already exists; not overwritten \n", return NULL;
dstFileName);
return NULL;
}
DISPLAY("zstd: %s already exists; ", dstFileName);
if (UTIL_requireUserConfirmation("overwrite (y/n) ? ", "Not overwritten \n", "yY", fCtx->hasStdinInput))
return NULL;
} }
/* need to unlink */ DISPLAY("zstd: %s already exists; ", dstFileName);
FIO_removeFile(dstFileName); if (UTIL_requireUserConfirmation("overwrite (y/n) ? ", "Not overwritten \n", "yY", fCtx->hasStdinInput))
} } return NULL;
}
/* need to unlink */
FIO_removeFile(dstFileName);
}
{ const int fd = open(dstFileName, O_WRONLY|O_CREAT|O_TRUNC, mode); { const int fd = open(dstFileName, O_WRONLY|O_CREAT|O_TRUNC, mode);
FILE* f = NULL; FILE* f = NULL;

View File

@@ -513,6 +513,21 @@ if [ "$isWindows" = false ] ; then
rm -f tmp1.zst tmp2.zst tmp1.out tmp2.out rm -f tmp1.zst tmp2.zst tmp1.out tmp2.out
println "test : check permissions on pre-existing output file in compression "
chmod 0600 tmp1
touch tmp1.zst
chmod 0400 tmp1.zst
zstd -f tmp1 -o tmp1.zst
assertFilePermissions tmp1.zst 600
println "test : check permissions on pre-existing output file in decompression "
chmod 0400 tmp1.zst
touch tmp1.out
chmod 0200 tmp1.out
zstd -f -d tmp1.zst -o tmp1.out
assertFilePermissions tmp1.out 400
rm -f tmp1.zst tmp1.out
umask 0666 umask 0666
chmod 0666 tmp1 tmp2 chmod 0666 tmp1 tmp2