Date: Sun, 31 Aug 2003 22:04:13 +0100 From: "Richard Dawe" Sender: rich AT phekda DOT freeserve DOT co DOT uk To: djgpp-workers AT delorie DOT com X-Mailer: Emacs 21.3.50 (via feedmail 8.3.emacs20_6 I) and Blat ver 1.8.6 Subject: Don't break UNCs in __canonicalize_path [PATCH] Message-Id: Reply-To: djgpp-workers AT delorie DOT com Hello. Below is a patch to stop __canonicalize_path from breaking UNCs. NB: _fixpath is just a wrapper for __canonicalize_path. There's also a test program. It could probably do with more test cases. Suggestions welcome. Note that the /dev/c fails - see my other mail about what /dev/c should expand to. OK to commit, when the /dev/c issue has been resolved? Thanks, bye, Rich =] Index: src/libc/posix/sys/stat/fixpath.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/posix/sys/stat/fixpath.c,v retrieving revision 1.8 diff -p -u -3 -r1.8 fixpath.c --- src/libc/posix/sys/stat/fixpath.c 25 Sep 2002 21:45:20 -0000 1.8 +++ src/libc/posix/sys/stat/fixpath.c 31 Aug 2003 20:52:46 -0000 @@ -184,9 +184,20 @@ __canonicalize_path(const char *in, char *op++ = ':'; } - /* Convert relative path to absolute */ if (!is_slash(*ip)) + { + /* Convert relative path to absolute */ op = __get_current_directory(op, drive_number); + } + else + { + /* Don't break UNCs. But convert to forward slashes. */ + if (is_slash(ip[0]) && is_slash(ip[1])) + { + *op++ = '/'; + ip += 2; /* NB: while loop adds a slash for us. */ + } + } /* Step through the input path */ while (*ip) Index: tests/libc/posix/sys/stat/makefile =================================================================== RCS file: /cvs/djgpp/djgpp/tests/libc/posix/sys/stat/makefile,v retrieving revision 1.5 diff -p -u -3 -r1.5 makefile --- tests/libc/posix/sys/stat/makefile 8 Mar 2003 00:42:43 -0000 1.5 +++ tests/libc/posix/sys/stat/makefile 31 Aug 2003 20:52:46 -0000 @@ -1,6 +1,7 @@ TOP=../../.. SRC += fixpath.c +SRC += fixpath2.c SRC += fstat.c SRC += leak.c SRC += lstat.c --- /dev/null 2003-08-31 22:02:23.000000000 +0000 +++ tests/libc/posix/sys/stat/fixpath2.c 2003-08-31 21:33:46.000000000 +0000 @@ -0,0 +1,156 @@ +#include +#include +#include +#include +#include +#include +#include + +static int +check (const int testnum, const char *expected, const char *out) +{ + int ok = 1; + + printf("Test %d: ", testnum); + if (stricmp(out, expected) == 0) + { + puts("OK"); + } + else + { + puts("FAIL"); + printf("Expected '%s'; got '%s'\n", expected, out); + ok = 0; + } + + return ok; +} + +int +main (void) +{ + char in[FILENAME_MAX]; + char out[FILENAME_MAX]; + char expected[FILENAME_MAX]; + char *p; + int testnum = 0; + int ok = 1; + + /* Test 1: Check expansion of ".". */ + testnum++; + in[0] = out[0] = expected[0] = '\0'; + + strcpy(in, "."); + assert(getcwd(expected, sizeof(expected)) != NULL); + + _fixpath(in, out); + ok = check(testnum, expected, out) && ok; + + /* Test 2: Check "." ignored in "`pwd`/.". */ + testnum++; + in[0] = out[0] = expected[0] = '\0'; + + assert(getcwd(expected, sizeof(expected)) != NULL); + strcpy(in, expected); + strcat(in, "/."); /* TODO: Possible buffer overrun. */ + + _fixpath(in, out); + ok = check(testnum, expected, out) && ok; + + /* Test 3: Check "." ignored in "`pwd`/./". */ + testnum++; + in[0] = out[0] = expected[0] = '\0'; + + assert(getcwd(expected, sizeof(expected)) != NULL); + strcpy(in, expected); + strcat(in, "/./"); /* TODO: Possible buffer overrun. */ + + _fixpath(in, out); + ok = check(testnum, expected, out) && ok; + + /* + * Test 4: Check drive letter added to "`pwd`" + * with drive letter removed. + */ + testnum++; + in[0] = out[0] = expected[0] = '\0'; + + assert(getcwd(expected, sizeof(expected)) != NULL); + strcpy(in, expected + 2); + + _fixpath(in, out); + ok = check(testnum, expected, out) && ok; + + /* Test 5: Check path expanded OK for ":". */ + testnum++; + in[0] = out[0] = expected[0] = '\0'; + + assert(getcwd(expected, sizeof(expected)) != NULL); + in[0] = expected[0]; + in[1] = expected[1]; + in[2] = '\0'; + + _fixpath(in, out); + ok = check(testnum, expected, out) && ok; + + /* Test 6: Check path expanded OK for ":.". */ + testnum++; + in[0] = out[0] = expected[0] = '\0'; + + assert(getcwd(expected, sizeof(expected)) != NULL); + in[0] = expected[0]; + in[1] = expected[1]; + in[2] = '.'; + in[2] = '\0'; + + _fixpath(in, out); + ok = check(testnum, expected, out) && ok; + + /* Test 7: Check that "/dev/c" expands to "c:/". */ + testnum++; + in[0] = out[0] = expected[0] = '\0'; + + strcpy(in, "/dev/c"); + strcpy(expected, "c:/"); + + _fixpath(in, out); + ok = check(testnum, expected, out) && ok; + + /* Test 8: Check that "/dev/c/" expands to "c:/". */ + testnum++; + in[0] = out[0] = expected[0] = '\0'; + + strcpy(in, "/dev/c/"); + strcpy(expected, "c:/"); + + _fixpath(in, out); + ok = check(testnum, expected, out) && ok; + + /* Test 9: Check that UNC names aren't trampled upon. */ + testnum++; + in[0] = out[0] = expected[0] = '\0'; + + assert(gethostname(in, sizeof(in)) == 0); + memmove(in + 2, in, strlen(in) + 1); /* TODO: Possible buffer overrun. */ + in[0] = in[1] = '\\'; + strcat(in, "\\share"); /* TODO: Possible buffer overrun. */ + + strcpy(expected, in); + /* TODO: Possible buffer overrun. */ + memmove(expected + 2, expected, strlen(expected) + 1); + for (p = expected; *p; p++) + { + if (*p == '\\') + *p = '/'; + } + assert((p = getcwd(NULL, FILENAME_MAX)) != NULL); + expected[0] = p[0]; + expected[1] = ':'; + free(p); + + _fixpath(in, out); + ok = check(testnum, expected, out) && ok; + + puts(ok ? "PASS" : "FAIL"); + return(ok ? EXIT_SUCCESS : EXIT_FAILURE); +}