From 4e793c35b62f5ea945b7d33ce36c78fc4d645b3a Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Fri, 11 Sep 2009 13:57:55 -0600 Subject: [PATCH] canonicalize-lgpl: fix glibc bug with trailing slash Consolidate the m4 macros into a single file, since both modules now have to worry about replacing canonicalize_file_name on buggy glibc. * m4/canonicalize-lgpl.m4: Move contents... * m4/canonicalize.m4: ...here. (gl_CANONICALIZE_LGPL): Factor realpath check... (gl_FUNC_REALPATH_WORKS): ...into new macro. Enhance to catch glibc 2.3.5 bug, fixed 2005-04-27. (gl_FUNC_CANONICALIZE_FILENAME_MODE): Use it. (gl_PREREQ_CANONICALIZE_LGPL): Inline... (gl_CANONICALIZE_LGPL_SEPARATE): ...into this macro. * modules/canonicalize-lgpl (Files): Manage file rename. * m4/stdlib_h.m4 (gl_STDLIB_H_DEFAULTS): Provide default. * modules/stdlib (Makefile.am): Substitute witness. * lib/stdlib.in.h (canonicalize_file_name): Declare if replacement is needed. * lib/canonicalize-lgpl.c: Also compile if canonicalize_file_name replacement is required. * lib/canonicalize.c (canonicalize_file_name): Likewise. * doc/glibc-functions/canonicalize_file_name.texi (canonicalize_file_name): Document this. * doc/posix-functions/realpath.texi (realpath): Likewise. Signed-off-by: Eric Blake --- ChangeLog | 21 +++++++ doc/glibc-functions/canonicalize_file_name.texi | 4 ++ doc/posix-functions/realpath.texi | 8 +++ lib/canonicalize-lgpl.c | 2 +- lib/canonicalize.c | 3 +- lib/stdlib.in.h | 5 +- m4/canonicalize-lgpl.m4 | 59 ------------------- m4/canonicalize.m4 | 77 ++++++++++++++++++++++--- m4/stdlib_h.m4 | 3 +- modules/canonicalize-lgpl | 2 +- modules/stdlib | 1 + 11 files changed, 113 insertions(+), 72 deletions(-) delete mode 100644 m4/canonicalize-lgpl.m4 diff --git a/ChangeLog b/ChangeLog index 2e406a6e6..6121def98 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,26 @@ 2009-09-17 Eric Blake + canonicalize-lgpl: fix glibc bug with trailing slash + * m4/canonicalize-lgpl.m4: Move contents... + * m4/canonicalize.m4: ...here. + (gl_CANONICALIZE_LGPL): Factor realpath check... + (gl_FUNC_REALPATH_WORKS): ...into new macro. Enhance to catch + glibc 2.3.5 bug, fixed 2005-04-27. + (gl_FUNC_CANONICALIZE_FILENAME_MODE): Use it. + (gl_PREREQ_CANONICALIZE_LGPL): Inline... + (gl_CANONICALIZE_LGPL_SEPARATE): ...into this macro. + * modules/canonicalize-lgpl (Files): Manage file rename. + * m4/stdlib_h.m4 (gl_STDLIB_H_DEFAULTS): Provide default. + * modules/stdlib (Makefile.am): Substitute witness. + * lib/stdlib.in.h (canonicalize_file_name): Declare if replacement + is needed. + * lib/canonicalize-lgpl.c: Also compile if canonicalize_file_name + replacement is required. + * lib/canonicalize.c (canonicalize_file_name): Likewise. + * doc/glibc-functions/canonicalize_file_name.texi + (canonicalize_file_name): Document this. + * doc/posix-functions/realpath.texi (realpath): Likewise. + 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 diff --git a/doc/glibc-functions/canonicalize_file_name.texi b/doc/glibc-functions/canonicalize_file_name.texi index f034f8175..5d17e26c3 100644 --- a/doc/glibc-functions/canonicalize_file_name.texi +++ b/doc/glibc-functions/canonicalize_file_name.texi @@ -9,6 +9,10 @@ Portability problems fixed by Gnulib: @item This function is missing on all non-glibc platforms: MacOS X 10.3, FreeBSD 6.0, NetBSD 3.0, OpenBSD 3.8, AIX 5.1, HP-UX 11, IRIX 6.5, OSF/1 5.1, Solaris 10, Cygwin, mingw, Interix 3.5, BeOS. +@item +This function fails to detect trailing slashes on non-directories on +some platforms: +glibc 2.3.5. @end itemize Portability problems not fixed by Gnulib: diff --git a/doc/posix-functions/realpath.texi b/doc/posix-functions/realpath.texi index 01ce781cf..5f7495be2 100644 --- a/doc/posix-functions/realpath.texi +++ b/doc/posix-functions/realpath.texi @@ -19,6 +19,14 @@ Solaris. This function does not always return an absolute path on some platforms: Solaris. +@item +This function fails to detect trailing slashes on non-directories on +some platforms: +glibc 2.3.5. +@item +This function fails to recognize non-directories followed @samp{..} on +some platforms: +cygwin. @end itemize Portability problems not fixed by Gnulib: diff --git a/lib/canonicalize-lgpl.c b/lib/canonicalize-lgpl.c index 63aecb52b..fbde01bbc 100644 --- a/lib/canonicalize-lgpl.c +++ b/lib/canonicalize-lgpl.c @@ -19,7 +19,7 @@ # include #endif -#if !HAVE_CANONICALIZE_FILE_NAME || defined _LIBC +#if !HAVE_CANONICALIZE_FILE_NAME || !FUNC_REALPATH_WORKS || defined _LIBC /* Specification. */ #include diff --git a/lib/canonicalize.c b/lib/canonicalize.c index 403093055..3a0154bd0 100644 --- a/lib/canonicalize.c +++ b/lib/canonicalize.c @@ -31,7 +31,8 @@ #include "xalloc.h" #include "xgetcwd.h" -#if !(HAVE_CANONICALIZE_FILE_NAME || GNULIB_CANONICALIZE_LGPL) +#if !((HAVE_CANONICALIZE_FILE_NAME && FUNC_REALPATH_WORKS) \ + || GNULIB_CANONICALIZE_LGPL) /* Return the canonical absolute name of file NAME. A canonical name does not contain any `.', `..' components nor any repeated file name separators ('/') or symlinks. All components must exist. diff --git a/lib/stdlib.in.h b/lib/stdlib.in.h index b20f69968..7a9246a57 100644 --- a/lib/stdlib.in.h +++ b/lib/stdlib.in.h @@ -116,7 +116,10 @@ extern void * calloc (size_t nmemb, size_t size); #endif #if @GNULIB_CANONICALIZE_FILE_NAME@ -# if !@HAVE_CANONICALIZE_FILE_NAME@ +# if @REPLACE_CANONICALIZE_FILE_NAME@ +# define canonicalize_file_name rpl_canonicalize_file_name +# endif +# if !@HAVE_CANONICALIZE_FILE_NAME@ || @REPLACE_CANONICALIZE_FILE_NAME@ extern char *canonicalize_file_name (const char *name); # endif #elif defined GNULIB_POSIXCHECK diff --git a/m4/canonicalize-lgpl.m4 b/m4/canonicalize-lgpl.m4 deleted file mode 100644 index 1fdacf857..000000000 --- a/m4/canonicalize-lgpl.m4 +++ /dev/null @@ -1,59 +0,0 @@ -# canonicalize-lgpl.m4 serial 8 -dnl Copyright (C) 2003, 2006-2007, 2009 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -AC_DEFUN([gl_CANONICALIZE_LGPL], -[ - dnl Do this replacement check manually because the file name is shorter - dnl than the function name. - AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) - AC_CHECK_FUNCS_ONCE([canonicalize_file_name realpath]) - dnl Assume that all platforms with canonicalize_file_name also have - dnl a working realpath. - if test $ac_cv_func_canonicalize_file_name = no; then - HAVE_CANONICALIZE_FILE_NAME=0 - AC_LIBOBJ([canonicalize-lgpl]) - if test $ac_cv_func_realpath = no; then - HAVE_REALPATH=0 - else - AC_CACHE_CHECK([whether realpath works], [gl_cv_func_realpath_works], [ - touch conftest.a - AC_RUN_IFELSE([ - AC_LANG_PROGRAM([[ - #include - ]], [[ - char *name1 = realpath ("conftest.a", NULL); - char *name2 = realpath ("conftest.b/../conftest.a", NULL); - return !(name1 && *name1 == '/' && !name2); - ]]) - ], [gl_cv_func_realpath_works=yes], [gl_cv_func_realpath_works=no], - [gl_cv_func_realpath_works="guessing no"]) - ]) - if test $gl_cv_func_realpath_works != yes; then - REPLACE_REALPATH=1 - else - AC_DEFINE([FUNC_REALPATH_WORKS], [1], [Define to 1 if realpath() - can malloc memory and always gives an absolute path.]) - fi - fi - gl_PREREQ_CANONICALIZE_LGPL - fi -]) - -# Like gl_CANONICALIZE_LGPL, except prepare for separate compilation -# (no AC_LIBOBJ). -AC_DEFUN([gl_CANONICALIZE_LGPL_SEPARATE], -[ - AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) - AC_CHECK_FUNCS_ONCE([canonicalize_file_name]) - gl_PREREQ_CANONICALIZE_LGPL -]) - -# Prerequisites of lib/canonicalize-lgpl.c. -AC_DEFUN([gl_PREREQ_CANONICALIZE_LGPL], -[ - AC_CHECK_HEADERS_ONCE([sys/param.h]) - AC_CHECK_FUNCS_ONCE([getcwd readlink]) -]) diff --git a/m4/canonicalize.m4 b/m4/canonicalize.m4 index 1258b3b4a..47c5c01ad 100644 --- a/m4/canonicalize.m4 +++ b/m4/canonicalize.m4 @@ -1,18 +1,79 @@ -# canonicalize.m4 serial 14 +# canonicalize.m4 serial 15 -# Copyright (C) 2003, 2004, 2005, 2006, 2007, 2009 Free Software -# Foundation, Inc. +dnl Copyright (C) 2003-2007, 2009 Free Software Foundation, Inc. -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# Written by Jim Meyering. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. +# Provides canonicalize_file_name and canonicalize_filename_mode, but does +# not provide or fix realpath. AC_DEFUN([gl_FUNC_CANONICALIZE_FILENAME_MODE], [ AC_LIBOBJ([canonicalize]) AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) AC_CHECK_FUNCS_ONCE([canonicalize_file_name]) + AC_REQUIRE([gl_FUNC_REALPATH_WORKS]) + if test $ac_cv_func_canonicalize_file_name = no; then + HAVE_CANONICALIZE_FILE_NAME=0 + elif test $gl_cv_func_realpath_works != yes; then + REPLACE_CANONICALIZE_FILE_NAME=1 + fi +]) + +# Provides canonicalize_file_name and realpath. +AC_DEFUN([gl_CANONICALIZE_LGPL], +[ + AC_REQUIRE([gl_CANONICALIZE_LGPL_SEPARATE]) + if test $ac_cv_func_canonicalize_file_name = no; then + HAVE_CANONICALIZE_FILE_NAME=0 + AC_LIBOBJ([canonicalize-lgpl]) + if test $ac_cv_func_realpath = no; then + HAVE_REALPATH=0 + elif test $gl_cv_func_realpath_works != yes; then + REPLACE_REALPATH=1 + fi + elif test $gl_cv_func_realpath_works != yes; then + AC_LIBOBJ([canonicalize-lgpl]) + REPLACE_REALPATH=1 + REPLACE_CANONICALIZE_FILE_NAME=1 + fi +]) + +# Like gl_CANONICALIZE_LGPL, except prepare for separate compilation +# (no AC_LIBOBJ). +AC_DEFUN([gl_CANONICALIZE_LGPL_SEPARATE], +[ + AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) + AC_CHECK_FUNCS_ONCE([canonicalize_file_name getcwd readlink]) + AC_REQUIRE([gl_FUNC_REALPATH_WORKS]) + AC_CHECK_HEADERS_ONCE([sys/param.h]) +]) + +# Check whether realpath works. Assume that if a platform has both +# realpath and canonicalize_file_name, but the former is broken, then +# so is the latter. +AC_DEFUN([gl_FUNC_REALPATH_WORKS], +[ + AC_CHECK_FUNCS_ONCE([realpath]) + AC_CACHE_CHECK([whether realpath works], [gl_cv_func_realpath_works], [ + touch conftest.a + AC_RUN_IFELSE([ + AC_LANG_PROGRAM([[ + #include + ]], [[ + char *name1 = realpath ("conftest.a", NULL); + char *name2 = realpath ("conftest.b/../conftest.a", NULL); + char *name3 = realpath ("conftest.a/", NULL); + return !(name1 && *name1 == '/' && !name2 && !name3); + ]]) + ], [gl_cv_func_realpath_works=yes], [gl_cv_func_realpath_works=no], + [gl_cv_func_realpath_works="guessing no"]) + ]) + if test $gl_cv_func_realpath_works = yes; then + AC_DEFINE([FUNC_REALPATH_WORKS], [1], [Define to 1 if realpath() + can malloc memory, always gives an absolute path, and handles + trailing slash correctly.]) + fi ]) diff --git a/m4/stdlib_h.m4 b/m4/stdlib_h.m4 index 1bcf06e5a..42d551d3b 100644 --- a/m4/stdlib_h.m4 +++ b/m4/stdlib_h.m4 @@ -1,4 +1,4 @@ -# stdlib_h.m4 serial 19 +# stdlib_h.m4 serial 20 dnl Copyright (C) 2007-2009 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -72,6 +72,7 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS], HAVE_STRUCT_RANDOM_DATA=1; AC_SUBST([HAVE_STRUCT_RANDOM_DATA]) HAVE_SYS_LOADAVG_H=0; AC_SUBST([HAVE_SYS_LOADAVG_H]) HAVE_UNSETENV=1; AC_SUBST([HAVE_UNSETENV]) + REPLACE_CANONICALIZE_FILE_NAME=0; AC_SUBST([REPLACE_CANONICALIZE_FILE_NAME]) REPLACE_MKSTEMP=0; AC_SUBST([REPLACE_MKSTEMP]) REPLACE_PUTENV=0; AC_SUBST([REPLACE_PUTENV]) REPLACE_REALPATH=0; AC_SUBST([REPLACE_REALPATH]) diff --git a/modules/canonicalize-lgpl b/modules/canonicalize-lgpl index c5ecd4fd4..f6b005579 100644 --- a/modules/canonicalize-lgpl +++ b/modules/canonicalize-lgpl @@ -3,7 +3,7 @@ realpath, canonical_file_name: Provide canonical absolute file name Files: lib/canonicalize-lgpl.c -m4/canonicalize-lgpl.m4 +m4/canonicalize.m4 Depends-on: alloca-opt diff --git a/modules/stdlib b/modules/stdlib index bb8a16424..4968ce7cb 100644 --- a/modules/stdlib +++ b/modules/stdlib @@ -65,6 +65,7 @@ stdlib.h: stdlib.in.h -e 's|@''HAVE_STRUCT_RANDOM_DATA''@|$(HAVE_STRUCT_RANDOM_DATA)|g' \ -e 's|@''HAVE_SYS_LOADAVG_H''@|$(HAVE_SYS_LOADAVG_H)|g' \ -e 's|@''HAVE_UNSETENV''@|$(HAVE_UNSETENV)|g' \ + -e 's|@''REPLACE_CANONICALIZE_FILE_NAME''@|$(REPLACE_CANONICALIZE_FILE_NAME)|g' \ -e 's|@''REPLACE_MKSTEMP''@|$(REPLACE_MKSTEMP)|g' \ -e 's|@''REPLACE_PUTENV''@|$(REPLACE_PUTENV)|g' \ -e 's|@''REPLACE_REALPATH''@|$(REPLACE_REALPATH)|g' \ -- 2.11.0