Subject: [PATCH] realpath: fix problems with // handling

From: Eric Blake <[email-masked]>
Date: Sat, 4 Feb 2012 12:05:56 -0700

On platforms like Cygwin where / and // are distinct, realpath was
incorrectly collapsing // into /.  http://debbugs.gnu.org/10472.

* src/realpath.c (path_common_prefix): When // is special, treat /
and // as having no common match.
(relpath): Allow for no match even without --relative-base.
---

This is the coreutils side of the patch; for this to work, we also
have to upgrade to the latest gnulib.

I'm not pushing this until we decide what to do about testing; I
guess we've already figured out how to make basename and dirname
tests conditional on whether they are on Linux or Cygwin (that is,
whether // and / are the same or different), so I should do something
similar to that for the realpath test.  But I can at least get a
code review on realpath.c while figuring out the testing situation.

 src/realpath.c |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/src/realpath.c b/src/realpath.c
index 2dc5e11..f06fbcc 100644
--- a/src/realpath.c
+++ b/src/realpath.c
@@ -131,6 +131,10 @@ path_common_prefix (const char *path1, const char *path2)
   int i = 0;
   int ret = 0;

+  if (DOUBLE_SLASH_IS_DISTINCT_ROOT && *path1 == '/' && *path2 == '/'
+      && (path1[1] == '/') != (path2[1] == '/'))
+    return 0;
+
   while (*path1 && *path2)
     {
       if (*path1 != *path2)
@@ -168,6 +172,9 @@ relpath (const char *can_fname)

       /* Skip the prefix common to --relative-to and path.  */
       int common_index = path_common_prefix (can_relative_to, can_fname);
+      if (!common_index)
+        return false;
+
       const char *relto_suffix = can_relative_to + common_index;
       const char *fname_suffix = can_fname + common_index;

-- 
1.7.7.6