Hey Bruno,
It seems we forgot about this behavior when moving to posix_spawn. In
the find_in_given_path function, there are the following lines:
if (path == NULL)
/* If PATH is not set, the default search path is implementation
dependent.
In practice, it is treated like an empty PATH. */
path = "";
That isn't true on GNU/Linux, FreeBSD, and Solaris at least, where an
unset PATH searches the default path specified by
pathconf (_CS_PATH, ...) and an empty PATH searches the current working
directory. Perhaps the default to _CS_PATH I put here is better placed
in the Gnulib function? It has been in POSIX for a long time [1].
[1] https://pubs.opengroup.org/onlinepubs/9799919799/functions/confstr.html
-- 8< --
* src/sort.c (get_resolved_compress_program): When PATH is not defined
in the environment, look up the compress program in "/bin:/usr/bin" or
the default search path specified by confstr (_CS_PATH, ...), if
supported.
* tests/sort/sort-compress.sh: Add a test case.
* NEWS: Mention the bug fix.
Discovered by Anthropic's OSS Scanner, as bug ANT-2026-1R7RAVAG.
---
NEWS | 7 +++++++
src/sort.c | 27 ++++++++++++++++++++++++++-
tests/sort/sort-compress.sh | 16 +++++++++++++++-
3 files changed, 48 insertions(+), 2 deletions(-)
diff --git a/NEWS b/NEWS
index 7071d6878..cf4566029 100644
--- a/NEWS
+++ b/NEWS
@@ -124,6 +124,13 @@ GNU coreutils NEWS -*-
outline -*-
resolves to a path beginning with the symbolic link itself.
[bug introduced in coreutils-9.0]
+ 'sort --compress-program=PROG' no longer treats an unset PATH environment
+ variable as equivalent to a PATH environment variable defined to an empty
+ string. On typical platforms, that would result in PROG being executed from
+ the current working directory, if it existed, when PATH was not defined in
the
+ environment.
+ [bug introduced in coreutils-9.9]
+
'stty' again rejects empty speed arguments.
Previously such arguments were accepted as value 0.
[bug introduced in coreutils-9.8]
diff --git a/src/sort.c b/src/sort.c
index 962588c34..47862e95c 100644
--- a/src/sort.c
+++ b/src/sort.c
@@ -1114,9 +1114,34 @@ get_resolved_compress_program (void)
if (resolved_compress_program_cache == NULL)
{
+ char const *path = getenv ("PATH");
+ char *default_path = NULL;
+
+ /* The find_in_given_path function treats an unset PATH as the same
+ as an empty PATH. On typical platforms, that means executing a
+ program from the current working directory. Instead, we want
+ the behavior of execlp, which will default to
+ confstr (_CS_PATH, ...). */
+ if (! path)
+ {
+ path = "/bin:/usr/bin";
+
+#ifdef _CS_PATH
+ size_t const len = confstr (_CS_PATH, NULL, 0);
+
+ if (len)
+ {
+ default_path = malloc (len);
+ if (default_path && confstr (_CS_PATH, default_path, len) == len)
+ path = default_path;
+ }
+#endif
+ }
+
resolved_compress_program_cache =
- find_in_given_path (compress_program, getenv ("PATH"), NULL, false);
+ find_in_given_path (compress_program, path, NULL, false);
/* If resolved_compress_program_cache == NULL, errno is set here. */
+ free (default_path);
}
return resolved_compress_program_cache;
diff --git a/tests/sort/sort-compress.sh b/tests/sort/sort-compress.sh
index 12802ca02..04a2778be 100755
--- a/tests/sort/sort-compress.sh
+++ b/tests/sort/sort-compress.sh
@@ -49,7 +49,21 @@ chmod +x gzip
PATH=.:$PATH sort -S 1k --compress-program=gzip in > out || fail=1
compare exp out || fail=1
test -f ok || fail=1
-rm -f ok
+rm -f ok out
+
+# Test that an unset PATH is not treated the same as an empty
+# PATH, i.e., PATH=''. On GNU/Linux, an unset PATH searches
+# the default path, but an empty PATH searches the current working
+# directory. Since the behavior may differ on other platforms, we
+# check it using 'env' first. In coreutils-9.9 to coreutils-9.12,
+# an unset PATH was turned into an empty PATH.
+env -u PATH gzip </dev/null >/dev/null 2>&1
+if test $? -eq 0 && ! test -f ok; then
+ sort=$(cmd_exe sort) || framework_failure_
+ env -u PATH $sort -S 1k --compress-program=gzip in >out || fail=1
+ compare exp out || fail=1
+ test -f ok && fail=1
+fi
# This is to make sure it works with no compression.
PATH=.:$PATH sort -S 1k in > out || fail=1
--
2.56.0