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:
@@ -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;
|
||||||
|
@@ -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
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user