Mercurial > hg > octave-kai > gnulib-hg
changeset 12017:acc38673eec3
canonicalize-lgpl: reject non-directory with trailing slash
This synchronizes glibc to gnulib. For gnulib to glibc, see:
http://sources.redhat.com/bugzilla/show_bug.cgi?id=10635
* lib/canonicalize-lgpl.c (__realpath): Synchronize with glibc.
* tests/test-canonicalize-lgpl.c (main): Enhance test. This
catches failures in glibc 2.3.5.
* tests/test-canonicalize.c (main): Likewise.
Signed-off-by: Eric Blake <ebb9@byu.net>
author | Eric Blake <ebb9@byu.net> |
---|---|
date | Fri, 11 Sep 2009 13:31:06 -0600 |
parents | 4fac822214af |
children | 586fda772b8f |
files | ChangeLog lib/canonicalize-lgpl.c tests/test-canonicalize-lgpl.c tests/test-canonicalize.c |
diffstat | 4 files changed, 121 insertions(+), 24 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2009-09-17 Eric Blake <ebb9@byu.net> + canonicalize-lgpl: reject non-directory with trailing slash + * lib/canonicalize-lgpl.c (__realpath): Synchronize with glibc. + * tests/test-canonicalize-lgpl.c (main): Enhance test. This + catches failures in glibc 2.3.5. + * tests/test-canonicalize.c (main): Likewise. + canonicalize-lgpl: use native realpath if it works * lib/canonicalize-lgpl.c (realpath): Guard with FUNC_REALPATH_WORKS.
--- a/lib/canonicalize-lgpl.c +++ b/lib/canonicalize-lgpl.c @@ -1,5 +1,5 @@ /* Return the canonical absolute name of a given file. - Copyright (C) 1996-2003, 2005-2009 Free Software Foundation, Inc. + Copyright (C) 1996-2009 Free Software Foundation, Inc. This file is part of the GNU C Library. This program is free software: you can redistribute it and/or modify @@ -15,38 +15,25 @@ You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include <config.h> +#ifndef _LIBC +# include <config.h> +#endif #if !HAVE_CANONICALIZE_FILE_NAME || defined _LIBC -#include <alloca.h> - /* Specification. */ #include <stdlib.h> -#include <stddef.h> +#include <alloca.h> #include <string.h> #include <unistd.h> - #include <limits.h> - #if HAVE_SYS_PARAM_H || defined _LIBC # include <sys/param.h> #endif -#ifndef MAXSYMLINKS -# ifdef SYMLOOP_MAX -# define MAXSYMLINKS SYMLOOP_MAX -# else -# define MAXSYMLINKS 20 -# endif -#endif - #include <sys/stat.h> - #include <errno.h> -#ifndef _LIBC -# define __set_errno(e) errno = (e) -#endif +#include <stddef.h> #ifdef _LIBC # include <shlib-compat.h> @@ -70,6 +57,14 @@ # define __getcwd(buf, max) getwd (buf) # endif # define __readlink readlink +# define __set_errno(e) errno = (e) +# ifndef MAXSYMLINKS +# ifdef SYMLOOP_MAX +# define MAXSYMLINKS SYMLOOP_MAX +# else +# define MAXSYMLINKS 20 +# endif +# endif #endif #if !FUNC_REALPATH_WORKS || defined _LIBC @@ -155,6 +150,7 @@ #else struct stat st; #endif + int n; /* Skip sequence of multiple path-separators. */ while (*start == '/') @@ -232,7 +228,6 @@ { char *buf; size_t len; - int n; if (++num_links > MAXSYMLINKS) { @@ -287,6 +282,11 @@ if (dest > rpath + 1) while ((--dest)[-1] != '/'); } + else if (!S_ISDIR (st.st_mode) && *end != '\0') + { + __set_errno (ENOTDIR); + goto error; + } } } if (dest > rpath + 1 && dest[-1] == '/') @@ -296,16 +296,14 @@ if (extra_buf) freea (extra_buf); - return resolved ? memcpy (resolved, rpath, dest - rpath + 1) : rpath; + return rpath; error: { int saved_errno = errno; if (extra_buf) freea (extra_buf); - if (resolved) - strcpy (resolved, rpath); - else + if (resolved == NULL) free (rpath); errno = saved_errno; } @@ -317,6 +315,7 @@ #if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_3) char * +attribute_compat_text_section __old_realpath (const char *name, char *resolved) { if (resolved == NULL)
--- a/tests/test-canonicalize-lgpl.c +++ b/tests/test-canonicalize-lgpl.c @@ -82,6 +82,24 @@ ASSERT (errno == EINVAL); } + /* Check that a non-directory with trailing slash yields NULL. */ + { + char *result; + errno = 0; + result = canonicalize_file_name (BASE "/tra/"); + ASSERT (result == NULL); + ASSERT (errno == ENOTDIR); + } + + /* Check that a missing directory yields NULL. */ + { + char *result; + errno = 0; + result = canonicalize_file_name (BASE "/zzz/.."); + ASSERT (result == NULL); + ASSERT (errno == ENOENT); + } + /* From here on out, tests involve symlinks. */ if (symlink (BASE "/ket", "ise") != 0) { @@ -137,6 +155,24 @@ ASSERT (errno == ENOENT); } + /* Check that a non-directory symlink with trailing slash yields NULL. */ + { + char *result; + errno = 0; + result = canonicalize_file_name (BASE "/huk/"); + ASSERT (result == NULL); + ASSERT (errno == ENOTDIR); + } + + /* Check that a missing directory via symlink yields NULL. */ + { + char *result; + errno = 0; + result = canonicalize_file_name (BASE "/ouk/.."); + ASSERT (result == NULL); + ASSERT (errno == ENOENT); + } + /* Check that a loop of symbolic links is detected. */ { char *result;
--- a/tests/test-canonicalize.c +++ b/tests/test-canonicalize.c @@ -90,6 +90,34 @@ ASSERT (errno == EINVAL); } + /* Check that a non-directory with trailing slash yields NULL. */ + { + char *result1; + char *result2; + errno = 0; + result1 = canonicalize_file_name (BASE "/tra/"); + ASSERT (result1 == NULL); + ASSERT (errno == ENOTDIR); + errno = 0; + result2 = canonicalize_filename_mode (BASE "/tra/", CAN_EXISTING); + ASSERT (result2 == NULL); + ASSERT (errno == ENOTDIR); + } + + /* Check that a missing directory yields NULL. */ + { + char *result1; + char *result2; + errno = 0; + result1 = canonicalize_file_name (BASE "/zzz/.."); + ASSERT (result1 == NULL); + ASSERT (errno == ENOENT); + errno = 0; + result2 = canonicalize_filename_mode (BASE "/zzz/..", CAN_EXISTING); + ASSERT (result2 == NULL); + ASSERT (errno == ENOENT); + } + /* From here on out, tests involve symlinks. */ if (symlink (BASE "/ket", "ise") != 0) { @@ -163,6 +191,34 @@ ASSERT (errno == ENOENT); } + /* Check that a non-directory symlink with trailing slash yields NULL. */ + { + char *result1; + char *result2; + errno = 0; + result1 = canonicalize_file_name (BASE "/huk/"); + ASSERT (result1 == NULL); + ASSERT (errno == ENOTDIR); + errno = 0; + result2 = canonicalize_filename_mode (BASE "/huk/", CAN_EXISTING); + ASSERT (result2 == NULL); + ASSERT (errno == ENOTDIR); + } + + /* Check that a missing directory via symlink yields NULL. */ + { + char *result1; + char *result2; + errno = 0; + result1 = canonicalize_file_name (BASE "/ouk/.."); + ASSERT (result1 == NULL); + ASSERT (errno == ENOENT); + errno = 0; + result2 = canonicalize_filename_mode (BASE "/ouk/..", CAN_EXISTING); + ASSERT (result2 == NULL); + ASSERT (errno == ENOENT); + } + /* Check that a loop of symbolic links is detected. */ { char *result1;