Mercurial > hg > octave-nkf > gnulib-hg
changeset 12019:4e6951cd4f33
canonicalize, canonicalize-lgpl: honor // if distinct from /
* modules/canonicalize (Files): Add double-slash-root.m4.
* modules/canonicalize-lgpl (Files): Likewise.
* m4/canonicalize.m4 (gl_FUNC_CANONICALIZE_FILENAME_MODE)
(gl_CANONICALIZE_LGPL_SEPARATE): Add dependency.
* lib/canonicalize.c (DOUBLE_SLASH_IS_DISTINCT_ROOT): Provide
fallback definition.
(canonicalize_filename_mode): Use it to protect //.
* lib/canonicalize-lgpl.c (DOUBLE_SLASH_IS_DISTINCT_ROOT)
(__realpath): Likewise.
* tests/test-canonicalize.c (main): Test this.
* tests/test-canonicalize-lgpl.c (main): Likewise.
* modules/canonicalize-tests (Depends-on): Add same-inode.
* modules/canonicalize-lgpl-tests (Depends-on): Likewise.
Signed-off-by: Eric Blake <ebb9@byu.net>
author | Eric Blake <ebb9@byu.net> |
---|---|
date | Thu, 10 Sep 2009 17:21:09 -0600 |
parents | 586fda772b8f |
children | 29f9f80b67c1 |
files | ChangeLog lib/canonicalize-lgpl.c lib/canonicalize.c m4/canonicalize.m4 modules/canonicalize modules/canonicalize-lgpl modules/canonicalize-lgpl-tests modules/canonicalize-tests tests/test-canonicalize-lgpl.c tests/test-canonicalize.c |
diffstat | 10 files changed, 139 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,20 @@ 2009-09-17 Eric Blake <ebb9@byu.net> + canonicalize, canonicalize-lgpl: honor // if distinct from / + * modules/canonicalize (Files): Add double-slash-root.m4. + * modules/canonicalize-lgpl (Files): Likewise. + * m4/canonicalize.m4 (gl_FUNC_CANONICALIZE_FILENAME_MODE) + (gl_CANONICALIZE_LGPL_SEPARATE): Add dependency. + * lib/canonicalize.c (DOUBLE_SLASH_IS_DISTINCT_ROOT): Provide + fallback definition. + (canonicalize_filename_mode): Use it to protect //. + * lib/canonicalize-lgpl.c (DOUBLE_SLASH_IS_DISTINCT_ROOT) + (__realpath): Likewise. + * tests/test-canonicalize.c (main): Test this. + * tests/test-canonicalize-lgpl.c (main): Likewise. + * modules/canonicalize-tests (Depends-on): Add same-inode. + * modules/canonicalize-lgpl-tests (Depends-on): Likewise. + canonicalize-lgpl: fix glibc bug with trailing slash * m4/canonicalize-lgpl.m4: Move contents... * m4/canonicalize.m4: ...here.
--- a/lib/canonicalize-lgpl.c +++ b/lib/canonicalize-lgpl.c @@ -67,6 +67,10 @@ # endif #endif +#ifndef DOUBLE_SLASH_IS_DISTINCT_ROOT +# define DOUBLE_SLASH_IS_DISTINCT_ROOT 0 +#endif + #if !FUNC_REALPATH_WORKS || defined _LIBC /* Return the canonical absolute name of file NAME. A canonical name does not contain any `.', `..' components nor any repeated path @@ -141,6 +145,8 @@ { rpath[0] = '/'; dest = rpath + 1; + if (DOUBLE_SLASH_IS_DISTINCT_ROOT && name[1] == '/') + *dest++ = '/'; } for (start = end = name; *start; start = end) @@ -169,6 +175,9 @@ /* Back up to previous component, ignore if at root already. */ if (dest > rpath + 1) while ((--dest)[-1] != '/'); + if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rpath + 1 + && *dest == '/') + dest++; } else { @@ -276,11 +285,21 @@ name = end = memcpy (extra_buf, buf, n); if (buf[0] == '/') - dest = rpath + 1; /* It's an absolute symlink */ + { + dest = rpath + 1; /* It's an absolute symlink */ + if (DOUBLE_SLASH_IS_DISTINCT_ROOT && buf[1] == '/') + *dest++ = '/'; + } else - /* Back up to previous component, ignore if at root already: */ - if (dest > rpath + 1) - while ((--dest)[-1] != '/'); + { + /* Back up to previous component, ignore if at root + already: */ + if (dest > rpath + 1) + while ((--dest)[-1] != '/'); + if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rpath + 1 + && *dest == '/') + dest++; + } } else if (!S_ISDIR (st.st_mode) && *end != '\0') { @@ -291,6 +310,8 @@ } if (dest > rpath + 1 && dest[-1] == '/') --dest; + if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rpath + 1 && *dest == '/') + dest++; *dest = '\0'; if (extra_buf)
--- a/lib/canonicalize.c +++ b/lib/canonicalize.c @@ -31,6 +31,10 @@ #include "xalloc.h" #include "xgetcwd.h" +#ifndef DOUBLE_SLASH_IS_DISTINCT_ROOT +# define DOUBLE_SLASH_IS_DISTINCT_ROOT 0 +#endif + #if !((HAVE_CANONICALIZE_FILE_NAME && FUNC_REALPATH_WORKS) \ || GNULIB_CANONICALIZE_LGPL) /* Return the canonical absolute name of file NAME. A canonical name @@ -122,6 +126,8 @@ rname_limit = rname + PATH_MAX; rname[0] = '/'; dest = rname + 1; + if (DOUBLE_SLASH_IS_DISTINCT_ROOT && name[1] == '/') + *dest++ = '/'; } for (start = name; *start; start = end) @@ -143,6 +149,9 @@ /* Back up to previous component, ignore if at root already. */ if (dest > rname + 1) while ((--dest)[-1] != '/'); + if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rname + 1 + && *dest == '/') + dest++; } else { @@ -226,11 +235,21 @@ name = end = memcpy (extra_buf, buf, n); if (buf[0] == '/') - dest = rname + 1; /* It's an absolute symlink */ + { + dest = rname + 1; /* It's an absolute symlink */ + if (DOUBLE_SLASH_IS_DISTINCT_ROOT && buf[1] == '/') + *dest++ = '/'; + } else - /* Back up to previous component, ignore if at root already: */ - if (dest > rname + 1) - while ((--dest)[-1] != '/'); + { + /* Back up to previous component, ignore if at root + already: */ + if (dest > rname + 1) + while ((--dest)[-1] != '/'); + if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rname + 1 + && *dest == '/') + dest++; + } free (buf); } @@ -246,6 +265,8 @@ } if (dest > rname + 1 && dest[-1] == '/') --dest; + if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rname + 1 && *dest == '/') + dest++; *dest = '\0'; free (extra_buf);
--- a/m4/canonicalize.m4 +++ b/m4/canonicalize.m4 @@ -1,4 +1,4 @@ -# canonicalize.m4 serial 15 +# canonicalize.m4 serial 16 dnl Copyright (C) 2003-2007, 2009 Free Software Foundation, Inc. @@ -14,6 +14,7 @@ AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) AC_CHECK_FUNCS_ONCE([canonicalize_file_name]) + AC_REQUIRE([gl_DOUBLE_SLASH_ROOT]) AC_REQUIRE([gl_FUNC_REALPATH_WORKS]) if test $ac_cv_func_canonicalize_file_name = no; then HAVE_CANONICALIZE_FILE_NAME=0 @@ -47,6 +48,7 @@ [ AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) AC_CHECK_FUNCS_ONCE([canonicalize_file_name getcwd readlink]) + AC_REQUIRE([gl_DOUBLE_SLASH_ROOT]) AC_REQUIRE([gl_FUNC_REALPATH_WORKS]) AC_CHECK_HEADERS_ONCE([sys/param.h]) ])
--- a/modules/canonicalize +++ b/modules/canonicalize @@ -5,6 +5,7 @@ lib/canonicalize.h lib/canonicalize.c m4/canonicalize.m4 +m4/double-slash-root.m4 Depends-on: areadlink-with-size
--- a/modules/canonicalize-lgpl +++ b/modules/canonicalize-lgpl @@ -4,6 +4,7 @@ Files: lib/canonicalize-lgpl.c m4/canonicalize.m4 +m4/double-slash-root.m4 Depends-on: alloca-opt
--- a/modules/canonicalize-lgpl-tests +++ b/modules/canonicalize-lgpl-tests @@ -2,6 +2,7 @@ tests/test-canonicalize-lgpl.c Depends-on: +same-inode configure.ac: AC_CHECK_FUNCS_ONCE([symlink])
--- a/modules/canonicalize-tests +++ b/modules/canonicalize-tests @@ -3,6 +3,7 @@ Depends-on: progname +same-inode configure.ac: AC_CHECK_FUNCS_ONCE([symlink])
--- a/tests/test-canonicalize-lgpl.c +++ b/tests/test-canonicalize-lgpl.c @@ -27,6 +27,8 @@ #include <sys/stat.h> #include <unistd.h> +#include "same-inode.h" + #if !HAVE_SYMLINK # define symlink(a,b) (-1) #endif /* !HAVE_SYMLINK */ @@ -115,6 +117,7 @@ ASSERT (symlink ("wum", BASE "/ouk") == 0); ASSERT (symlink ("../ise", BASE "/ket") == 0); ASSERT (mkdir (BASE "/lum", 0700) == 0); + ASSERT (symlink ("//.//../..", BASE "/droot") == 0); /* Check that the symbolic link to a file can be resolved. */ { @@ -182,7 +185,33 @@ ASSERT (errno == ELOOP); } + /* Check that leading // is honored correctly. */ + { + struct stat st1; + struct stat st2; + char *result1 = canonicalize_file_name ("//."); + char *result2 = canonicalize_file_name (BASE "/droot"); + ASSERT (result1); + ASSERT (result2); + ASSERT (stat ("/", &st1) == 0); + ASSERT (stat ("//", &st2) == 0); + if (SAME_INODE (st1, st2)) + { + ASSERT (strcmp (result1, "/") == 0); + ASSERT (strcmp (result2, "/") == 0); + } + else + { + ASSERT (strcmp (result1, "//") == 0); + ASSERT (strcmp (result2, "//") == 0); + } + free (result1); + free (result2); + } + + /* Cleanup. */ + ASSERT (remove (BASE "/droot") == 0); ASSERT (remove (BASE "/plo") == 0); ASSERT (remove (BASE "/huk") == 0); ASSERT (remove (BASE "/bef") == 0);
--- a/tests/test-canonicalize.c +++ b/tests/test-canonicalize.c @@ -28,6 +28,8 @@ #include <sys/stat.h> #include <unistd.h> +#include "same-inode.h" + #if !HAVE_SYMLINK # define symlink(a,b) (-1) #endif @@ -138,6 +140,7 @@ ASSERT (mkdir (BASE "/d", 0700) == 0); ASSERT (close (creat (BASE "/d/2", 0600)) == 0); ASSERT (symlink ("../s/2", BASE "/d/1") == 0); + ASSERT (symlink ("//.//../..", BASE "/droot") == 0); /* Check that the symbolic link to a file can be resolved. */ { @@ -281,7 +284,42 @@ free (result2); } + /* Check that leading // is honored correctly. */ + { + struct stat st1; + struct stat st2; + char *result1 = canonicalize_file_name ("//."); + char *result2 = canonicalize_filename_mode ("//.", CAN_EXISTING); + char *result3 = canonicalize_file_name (BASE "/droot"); + char *result4 = canonicalize_filename_mode (BASE "/droot", CAN_EXISTING); + ASSERT (result1); + ASSERT (result2); + ASSERT (result3); + ASSERT (result4); + ASSERT (stat ("/", &st1) == 0); + ASSERT (stat ("//", &st2) == 0); + if (SAME_INODE (st1, st2)) + { + ASSERT (strcmp (result1, "/") == 0); + ASSERT (strcmp (result2, "/") == 0); + ASSERT (strcmp (result3, "/") == 0); + ASSERT (strcmp (result4, "/") == 0); + } + else + { + ASSERT (strcmp (result1, "//") == 0); + ASSERT (strcmp (result2, "//") == 0); + ASSERT (strcmp (result3, "//") == 0); + ASSERT (strcmp (result4, "//") == 0); + } + free (result1); + free (result2); + free (result3); + free (result4); + } + /* Cleanup. */ + ASSERT (remove (BASE "/droot") == 0); ASSERT (remove (BASE "/d/1") == 0); ASSERT (remove (BASE "/d/2") == 0); ASSERT (remove (BASE "/d") == 0);