bug-coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

ln.c portability fix for hosts where / != //


From: Paul Eggert
Subject: ln.c portability fix for hosts where / != //
Date: Fri, 28 Oct 2005 15:19:29 -0700
User-agent: Gnus/5.1007 (Gnus v5.10.7) Emacs/21.4 (gnu/linux)

I installed this patch to fix a bug I found by inspecting the strace
output for "ln".  It's hard to write a test case for it, since it
requires write access to "/".

2005-10-28  Paul Eggert  <address@hidden>

        * src/ln.c (FILE_BASENAME_CONCAT): Omit unnecessary slashes in the
        boundary between DEST and SOURCE in the result.

--- src/ln.c    22 Aug 2005 10:31:55 -0000      1.152
+++ src/ln.c    28 Oct 2005 22:17:00 -0000      1.153
@@ -54,7 +54,10 @@
 #endif
 
 /* Construct a string NEW_DEST by concatenating DEST, a slash, and
-   basename(SOURCE) in alloca'd memory.  Don't modify DEST or SOURCE.  */
+   basename (SOURCE) in alloca'd memory.  Don't modify DEST or SOURCE.
+   Omit unnecessary slashes in the boundary between DEST and SOURCE in
+   the result; they can cause harm if "/" and "//" denote different
+   directories.  */
 
 #define FILE_BASENAME_CONCAT(new_dest, dest, source)                   \
     do                                                                 \
@@ -62,15 +65,18 @@
        const char *source_base;                                        \
        char *tmp_source;                                               \
        size_t buf_len = strlen (source) + 1;                           \
+       size_t dest_len = strlen (dest);                                \
                                                                        \
        tmp_source = alloca (buf_len);                                  \
        memcpy (tmp_source, (source), buf_len);                         \
        strip_trailing_slashes (tmp_source);                            \
        source_base = base_name (tmp_source);                           \
-                                                                       \
-       (new_dest) = alloca (strlen ((dest)) + 1                        \
-                                     + strlen (source_base) + 1);      \
-       stpcpy (stpcpy (stpcpy ((new_dest), (dest)), "/"), source_base);\
+       source_base += (source_base[0] == '/');                         \
+       dest_len -= (dest_len != 0 && (dest)[dest_len - 1] == '/');     \
+       (new_dest) = alloca (dest_len + 1 + strlen (source_base) + 1);  \
+       memcpy (new_dest, dest, dest_len);                              \
+       (new_dest)[dest_len] = '/';                                     \
+       strcpy ((new_dest) + dest_len + 1, source_base);                \
       }                                                                        
\
     while (0)
 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]