https://github.com/facebook/zstd/issues/3523 https://github.com/facebook/zstd/pull/3541 From 50e8f55e7d5928af9c3411afdb4fbedb4d8f770d Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Thu, 9 Mar 2023 12:46:37 -0500 Subject: [PATCH 1/3] Fix Python 3.6 Incompatibility in CLI Tests --- a/tests/cli-tests/run.py +++ b/tests/cli-tests/run.py @@ -535,7 +535,8 @@ def _run_script(self, script: str, cwd: str) -> None: subprocess.run( args=[script], stdin=subprocess.DEVNULL, - capture_output=True, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, cwd=cwd, env=env, check=True, From c4c3e11958aed4dc99ec22e3d31c405217575a8c Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Thu, 9 Mar 2023 12:47:40 -0500 Subject: [PATCH 2/3] Avoid Calling `setvbuf()` on Null File Pointer --- a/programs/fileio.c +++ b/programs/fileio.c @@ -644,18 +644,24 @@ FIO_openDstFile(FIO_ctx_t* fCtx, FIO_prefs_t* const prefs, #endif if (f == NULL) { DISPLAYLEVEL(1, "zstd: %s: %s\n", dstFileName, strerror(errno)); + } else { + /* An increased buffer size can provide a significant performance + * boost on some platforms. Note that providing a NULL buf with a + * size that's not 0 is not defined in ANSI C, but is defined in an + * extension. There are three possibilities here: + * 1. Libc supports the extended version and everything is good. + * 2. Libc ignores the size when buf is NULL, in which case + * everything will continue as if we didn't call `setvbuf()`. + * 3. We fail the call and execution continues but a warning + * message might be shown. + * In all cases due execution continues. For now, I believe that + * this is a more cost-effective solution than managing the buffers + * allocations ourselves (will require an API change). + */ + if (setvbuf(f, NULL, _IOFBF, 1 MB)) { + DISPLAYLEVEL(2, "Warning: setvbuf failed for %s\n", dstFileName); + } } - /* An increased buffer size can provide a significant performance boost on some platforms. - * Note that providing a NULL buf with a size that's not 0 is not defined in ANSI C, but is defined - * in an extension. There are three possibilities here - - * 1. Libc supports the extended version and everything is good. - * 2. Libc ignores the size when buf is NULL, in which case everything will continue as if we didn't - * call `setvbuf`. - * 3. We fail the call and execution continues but a warning message might be shown. - * In all cases due execution continues. For now, I believe that this is a more cost-effective - * solution than managing the buffers allocations ourselves (will require an API change). */ - if(setvbuf(f, NULL, _IOFBF, 1 MB)) - DISPLAYLEVEL(2, "Warning: setvbuf failed for %s\n", dstFileName); return f; } } From 957a0ae52d0f49eccd260a22ceb5f5dfed064e9f Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Thu, 9 Mar 2023 12:48:11 -0500 Subject: [PATCH 3/3] Add CLI Test --- /dev/null +++ b/tests/cli-tests/file-stat/compress-file-to-dir-without-write-perm.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +# motivated by issue #3523 + +datagen > file +mkdir out +chmod 000 out + +zstd file -q --trace-file-stat -o out/file.zst +zstd -tq out/file.zst + +chmod 777 out --- /dev/null +++ b/tests/cli-tests/file-stat/compress-file-to-dir-without-write-perm.sh.stderr.exact @@ -0,0 +1,26 @@ +Trace:FileStat: > UTIL_isLink(file) +Trace:FileStat: < 0 +Trace:FileStat: > UTIL_isConsole(2) +Trace:FileStat: < 0 +Trace:FileStat: > UTIL_getFileSize(file) +Trace:FileStat: > UTIL_stat(-1, file) +Trace:FileStat: < 1 +Trace:FileStat: < 65537 +Trace:FileStat: > UTIL_stat(-1, file) +Trace:FileStat: < 1 +Trace:FileStat: > UTIL_isDirectoryStat() +Trace:FileStat: < 0 +Trace:FileStat: > UTIL_stat(-1, file) +Trace:FileStat: < 1 +Trace:FileStat: > UTIL_isSameFile(file, out/file.zst) +Trace:FileStat: > UTIL_stat(-1, file) +Trace:FileStat: < 1 +Trace:FileStat: > UTIL_stat(-1, out/file.zst) +Trace:FileStat: < 0 +Trace:FileStat: < 0 +Trace:FileStat: > UTIL_isRegularFile(out/file.zst) +Trace:FileStat: > UTIL_stat(-1, out/file.zst) +Trace:FileStat: < 0 +Trace:FileStat: < 0 +zstd: out/file.zst: Permission denied +zstd: can't stat out/file.zst : Permission denied -- ignored