]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
ln: with -sr, don't segfault for a TARGET of ''
authorJim Meyering <meyering@fb.com>
Fri, 14 Mar 2014 00:05:04 +0000 (17:05 -0700)
committerJim Meyering <meyering@fb.com>
Fri, 14 Mar 2014 03:05:10 +0000 (20:05 -0700)
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.

NEWS
THANKS.in
src/ln.c
tests/ln/relative.sh

diff --git a/NEWS b/NEWS
index 62966b2fa200af1321cfcc96e4fd874f1e1552ce..35d48e52b26d1d2963c853924c4c595f557445d9 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -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]
 
index 561d18ce214c31dd7a3947147adb683149850df5..2670265975409dde89754e000ac4833361dedefa 100644 (file)
--- a/THANKS.in
+++ b/THANKS.in
@@ -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
index aab9cf2fa65fc9da967f52d0e9d92cf252d713c7..67266997e4dc7cd9f52275f8b8b612111a0ad468 100644 (file)
--- a/src/ln.c
+++ b/src/ln.c
@@ -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);
index 7636695ceb8c9f2744a4ddc9c220c9eb40051309..5cf280a5806060dbb6d64e4438b9c9999d2df5f6 100755 (executable)
@@ -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