diff options
author | Jim Meyering <meyering@fb.com> | 2014-03-13 17:05:04 -0700 |
---|---|---|
committer | Jim Meyering <meyering@fb.com> | 2014-03-13 20:05:10 -0700 |
commit | 0093ac8d57a0f1a16fd09d98f6a524dddb6053e7 (patch) | |
tree | be5995a36e912c3881b1651c1e1a420142129560 | |
parent | 4f211822dddd1777dc915f2df4e2ed3b65c68301 (diff) | |
download | coreutils-0093ac8d57a0f1a16fd09d98f6a524dddb6053e7.tar.xz |
ln: with -sr, don't segfault for a TARGET of ''
Prior to this change, "ln -sr '' F" would segfault, attempting
to read path2[1] in relpath.c's path_common_prefix function.
This problem arises whenever canonicalize_filename_mode returns
NULL.
* src/ln.c (convert_abs_rel): Call relpath only when
both canonicalize_filename_mode calls return non-NULL.
* tests/ln/relative.sh: Add a test to trigger this failure.
* THANKS.in: List reporter's name/address.
* NEWS (Bug fixes): Mention it.
Reported by Erik Bernstein in 739752@bugs.debian.org.
Fixes http://bugs.gnu.org/17010.
-rw-r--r-- | NEWS | 3 | ||||
-rw-r--r-- | THANKS.in | 1 | ||||
-rw-r--r-- | src/ln.c | 16 | ||||
-rwxr-xr-x | tests/ln/relative.sh | 5 |
4 files changed, 19 insertions, 6 deletions
@@ -25,6 +25,9 @@ GNU coreutils NEWS -*- outline -*- it would display an error, requiring --no-dereference to avoid the issue. [bug introduced in coreutils-5.3.0] + ln -sr '' F no longer segfaults. Now works as expected. + [bug introduced with the --relative feature in coreutils-8.16] + shuf --repeat no longer dumps core if the input is empty. [bug introduced with the --repeat feature in coreutils-8.22] @@ -193,6 +193,7 @@ Eric G. Miller egm2@jps.net Eric Pemente pemente@northpark.edu Eric S. Raymond esr@snark.thyrsus.com Erik Bennett bennett@cvo.oneworld.com +Erik Bernstein erik@fscking.org Erik Corry erik@kroete2.freinet.de Felix Lee flee@teleport.com Felix Rauch Valenti frauch@cse.unsw.edu.au @@ -149,13 +149,17 @@ convert_abs_rel (const char *from, const char *target) char *realdest = canonicalize_filename_mode (targetdir, CAN_MISSING); char *realfrom = canonicalize_filename_mode (from, CAN_MISSING); - /* Write to a PATH_MAX buffer. */ - char *relative_from = xmalloc (PATH_MAX); - - if (!relpath (realfrom, realdest, relative_from, PATH_MAX)) + char *relative_from = NULL; + if (realdest && realfrom) { - free (relative_from); - relative_from = NULL; + /* Write to a PATH_MAX buffer. */ + relative_from = xmalloc (PATH_MAX); + + if (!relpath (realfrom, realdest, relative_from, PATH_MAX)) + { + free (relative_from); + relative_from = NULL; + } } free (targetdir); diff --git a/tests/ln/relative.sh b/tests/ln/relative.sh index 7636695ce..5cf280a58 100755 --- a/tests/ln/relative.sh +++ b/tests/ln/relative.sh @@ -45,4 +45,9 @@ mkdir web ln -sr latest web/latest test $(readlink web/latest) = '../release2' || fail=1 +# Expect this to fail with exit status 1, or to succeed quietly (freebsd). +# Prior to coreutils-8.23, it would segfault. +ln -sr '' F +case $? in [01]) ;; *) fail=1;; esac + Exit $fail |