delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2003/01/17/14:47:45

Message-ID: <3E286C07.7040200@mif.vu.lt>
Date: Fri, 17 Jan 2003 21:48:07 +0100
From: Laurynas Biveinis <laurynas DOT biveinis AT mif DOT vu DOT lt>
Organization: VU MIF
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.2.1) Gecko/20021130
X-Accept-Language: lt, en, en-us
MIME-Version: 1.0
To: DJGPP Workers <djgpp-workers AT delorie DOT com>,
Richard Dawe <rich AT phekda DOT freeserve DOT co DOT uk>
Subject: Take on __solve_symlinks()
X-OriginalArrivalTime: 17 Jan 2003 19:46:13.0709 (UTC) FILETIME=[179D5FD0:01C2BE61]
Reply-To: djgpp-workers AT delorie DOT com

Well, maybe I'm on drugs, but I was unable to find good testcases for 
debugging it. It passes with flying colours every single test I made,
except for this case:

    symlink("c:/autoexec.bat", "/link");
    test_success("/link", "c:/autoexec.bat");

I.e. it didn't resolve /link properly. But I failed to create any more 
failing tests, including situations described by you. Maybe you could 
give me the testcase a patch to tests/libc/compat/unistd/xsymlink.c or 
precisely describe particular directory and file layout for uncovering 
the bugs?

Below are the new testcases from testsuite I've used, and the patch I'm 
commiting in a second to fix /link case. The fix is trivial.

    symlink("c:/autoexec.bat", "/link");
    test_success("c:/link", "c:/autoexec.bat");
    test_success("/link", "c:/autoexec.bat");
    test_success("c://link", "c:/autoexec.bat");
    test_success("//link", "c:/autoexec.bat");
    test_success("c:/./link", "c:/autoexec.bat");
    test_success("/../link", "c:/autoexec.bat");
    test_success("c:/../link", "c:/autoexec.bat");
    test_success("/../../link", "c:/autoexec.bat");
    test_success("c:/../../link", "c:/autoexec.bat");
       /* FIXME below, but note that you're insane to run this test 
really that deep :) */
    test_success("c:../../../../../../../../../../../../../../../link", 
"c:/autoexec.bat");
    mkdir("c:/tdir", S_IWUSR);
    symlink("c:/config.sys", "c:/tdir/link");
    test_success("c:/tdir/link", "c:/config.sys");
    test_success("/tdir/link", "c:/config.sys");
    test_success("c:/tdir/../.././tdir/link", "c:/config.sys");
    test_success("/tdir/..//../.././../../tdir/link", "c:/config.sys");
       /* FIXME below, but note that you're insane to run this test 
really that deep :) */
 
test_success("c:../../../../../../../../../../../../../../../tdir/link", 
"c:/config.sys");
    unlink("c:/tdir/link");
    rmdir("c:/tdir");
    unlink("/link");
    symlink("/dev/env/DJDIR/djgpp.env", "/dev/env/DJDIR/link");
    test_success("/dev/env/DJDIR/link", "/dev/env/DJDIR/djgpp.env");
    test_success("/dev/env/DJDIR/../djgpp/link", 
"/dev/env/DJDIR/djgpp.env"); /* FIXME */
    unlink("/dev/env/DJDIR/link");

Index: xsymlink.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/compat/unistd/xsymlink.c,v
retrieving revision 1.6
diff -c -3 -p -r1.6 xsymlink.c
*** xsymlink.c	23 Dec 2002 11:44:49 -0000	1.6
--- xsymlink.c	17 Jan 2003 19:22:25 -0000
*************** int __solve_symlinks(const char * __syml
*** 50,58 ****
      }

      strcpy(__real_path, __symlink_path);
      start = __real_path;
      end = strpbrk(__real_path, "/\\");
!    if (!end)
         end = __real_path + strlen(__real_path);
      while (start && *start)
      {
--- 50,63 ----
      }

      strcpy(__real_path, __symlink_path);
+    /* Begin by start pointing at the first character and end pointing
+       at the first path separator.  In the cases like "/foo" end will
+       point to the next path separator.  In all cases, if there are no
+       path separators left, end will point to the end of string.
+     */
      start = __real_path;
      end = strpbrk(__real_path, "/\\");
!    if (!end || (start == end))
         end = __real_path + strlen(__real_path);
      while (start && *start)
      {
*************** int __solve_symlinks(const char * __syml
*** 164,170 ****
      return 1;
   }

! /* Advance to the next portion of the path. Cope with multiple slashes. */
   static void advance(char ** s, char ** e)
   {
      *s = strpbrk(*s + 1, "/\\");
--- 169,176 ----
      return 1;
   }

! /* Advance to the next portion of the path in the case we won't need
!    previously resolved part anymore.  Cope with multiple slashes. */
   static void advance(char ** s, char ** e)
   {
      *s = strpbrk(*s + 1, "/\\");

--
Laurynas


- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019