X-Authentication-Warning: delorie.com: mail set sender to djgpp-workers-bounces using -f Message-ID: <41238053.6000205@ujf-grenoble.fr> Date: Wed, 18 Aug 2004 18:14:11 +0200 From: Maurice Lombardi User-Agent: Mozilla/5.0 (Windows; U; Win98; fr-FR; rv:1.4) Gecko/20030624 Netscape/7.1 (ax) X-Accept-Language: fr-fr, it, en MIME-Version: 1.0 To: djgpp-workers AT delorie DOT com Subject: bug in __solve_symlink() Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Reply-To: djgpp-workers AT delorie DOT com In a previous post http://www.delorie.com/djgpp/mail-archives/browse.cgi?p=djgpp/2004/05/06/10:32:18 (see also http://www.delorie.com/djgpp/mail-archives/browse.cgi?p=djgpp-workers/2004/05/07/07:03:40 I have described a bug in __solve_symlinks() for version 2.04 and proposed a solution. I found recently that the corresponding test suite is in djtst204.zip As expected the case I described was not covered by the tests. I thus added a new test modelled from the previous one in the suite with the following diff --- tests\libc\compat\unistd\xsymlink.c.orig 2003-02-10 21:41:10.000000000 +0000 +++ tests\libc\compat\unistd\xsymlink.c 2004-08-18 17:40:58.000000000 +0000 @@ -17,8 +17,10 @@ * * There are some tests based on the current-working directory: * 1. An absolute path using '..' to navigate through the directories. - * 2. A relative path using a drive letter and '..'. - * 3. A relative path using a drive letter and one too many '..' over 2. + * 2. An absolute path without drive letter using '..' to navigate and + * not ending in current-working directory. + * 3. A relative path using a drive letter and '..'. + * 4. A relative path using a drive letter and one too many '..' over 3. * * And following are failure tests: * 1. Simple symlink loop. @@ -151,6 +153,29 @@ if (!ret) ok = 0; + + /* Try tests_success[2] with an absolute path without drive letter + * and with '..'. */ + j++; + + strcpy(path, cwd_without_drive); + for (i = 0; i < n_slashes; i++) + { + strcat(path, "/.."); + } + strcat(path, cwd_without_drive); + strcat(path, "/"); + strcat(path, tests_success[2].src); + + test.src = path; + test.target = tests_success[2].target; + + printf("Test %d: Solving %s\n", j, test.src); + ret = test_success(j, test.src, test.target); + if (!ret) + ok = 0; + + /* Try tests_success[0] with a drive-letter and relative path * with '..'. */ j++; --------------------------------------------------------------------------------- running the test with the current beta 1 gives DJ204 C:\dj204\tests\libc\compat\unistd>xsymlink Running __solve_symlinks() and readlink() testsuite: Tests that check __solve_symlinks() works: Test 1 passed Test 2 passed Test 3 passed Test 4 passed Test 5 passed Test 6 passed Test 7 passed Test 8 passed Test 9 passed Test 10 passed Test 11 passed Test 12 passed Test 13 passed Tests that check __solve_symlinks() based on current directory: Test 1: Solving c:/dj204/tests/libc/compat/unistd/../../../../../dj204/tests/lib c/compat/unistd/test1 Test 1 passed Test 2: Solving /dj204/tests/libc/compat/unistd/../../../../../dj204/tests/libc/ compat/unistd/dir1/test1 Test 2 failed - __solve_symlinks returns wrong resolved path Returned path: c:/dj204/tests/libc/compat/unistd/file1 Expected path: c:/dj204/tests/libc/compat/unistd/dir1/file1 Test 3: Solving c:../../../../../dj204/tests/libc/compat/unistd/test1 Test 3 passed Test 4: Solving c:../../../../../../dj204/tests/libc/compat/unistd/test1 Test 4 failed - __solve_symlinks returns wrong resolved path Returned path: c:/dj204/tests/libc/compat/unistd/test1 Expected path: c:/dj204/tests/libc/compat/unistd/file1 Tests that check __solve_symlinks() failure cases: Test 1 passed Test 2 passed FAIL Test 2 in the second series is the new one and it fails as expected --------------------------------------------------------------------------------- appling the proposed diff --- src\libc\compat\unistd\xsymlink.c.orig 2003-02-06 20:42:38.000000000 +0000 +++ src\libc\compat\unistd\xsymlink.c 2004-08-02 15:57:42.000000000 +0000 @@ -74,7 +74,9 @@ */ start = __real_path; end = strpbrk(__real_path, "/\\"); - if (!end || (start == end)) + if (start == end) + end = strpbrk(__real_path + 1, "/\\"); + if (!end) end = __real_path + strlen(__real_path); while (start && *start) { --------------------------------------------------------------------------------------- recompiling src and running the same test gives DJ204 C:\dj204\tests\libc\compat\unistd>xsymlink Running __solve_symlinks() and readlink() testsuite: Tests that check __solve_symlinks() works: Test 1 passed Test 2 passed Test 3 passed Test 4 passed Test 5 passed Test 6 passed Test 7 passed Test 8 passed Test 9 passed Test 10 passed Test 11 passed Test 12 passed Test 13 passed Tests that check __solve_symlinks() based on current directory: Test 1: Solving c:/dj204/tests/libc/compat/unistd/../../../../../dj204/tests/lib c/compat/unistd/test1 Test 1 passed Test 2: Solving /dj204/tests/libc/compat/unistd/../../../../../dj204/tests/libc/ compat/unistd/dir1/test1 Test 2 passed Test 3: Solving c:../../../../../dj204/tests/libc/compat/unistd/test1 Test 3 passed Test 4: Solving c:../../../../../../dj204/tests/libc/compat/unistd/test1 Test 4 failed - __solve_symlinks returns wrong resolved path Returned path: c:/dj204/tests/libc/compat/unistd/test1 Expected path: c:/dj204/tests/libc/compat/unistd/file1 Tests that check __solve_symlinks() failure cases: Test 1 passed Test 2 passed FAIL Test 2 of the second series now succeeds as expected. Test 4 which fails in both cases was described in a thread on djgpp-workers in 2003/02: it occurs with Win98se (I use), not with Win2k, and apparently it remained as is since then. Hope this helps Maurice -- Maurice Lombardi Laboratoire de Spectrometrie Physique, Universite Joseph Fourier de Grenoble, BP87 38402 Saint Martin d'Heres Cedex FRANCE Tel: 33 (0)4 76 51 47 51 Fax: 33 (0)4 76 63 54 95 mailto:Maurice DOT Lombardi AT ujf-grenoble DOT fr