Mercurial > hg > octave-nkf > gnulib-hg
changeset 11621:c98fca1ff8b8
memchr: detect broken x86_64 and alpha implementations
* modules/memchr-tests (Depends-on): Move mmap detection...
* modules/memchr (Depends-on): ...here.
(configure.ac): Set indicator.
* lib/string.in.h (memchr): Declare replacement.
* modules/string (Makefile.am): Trigger replacement.
* m4/string_h.m4 (gl_HEADER_STRING_H_DEFAULTS): Likewise.
* m4/memchr.m4 (gl_FUNC_MEMCHR): Use mmap to detect platform
bugs.
* doc/posix-functions/memchr.texi (memchr): Document the bug.
* modules/getpagesize (License): Relax license.
Signed-off-by: Eric Blake <ebb9@byu.net>
author | Eric Blake <ebb9@byu.net> |
---|---|
date | Mon, 08 Jun 2009 06:29:17 -0600 |
parents | fa0fe50fe700 |
children | 3576940946dd |
files | ChangeLog doc/posix-functions/memchr.texi lib/string.in.h m4/memchr.m4 m4/string_h.m4 modules/getpagesize modules/memchr modules/memchr-tests modules/string |
diffstat | 9 files changed, 116 insertions(+), 11 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2009-06-12 Eric Blake <ebb9@byu.net> + + memchr: detect broken x86_64 and alpha implementations + * modules/memchr-tests (Depends-on): Move mmap detection... + * modules/memchr (Depends-on): ...here. + (configure.ac): Set indicator. + * lib/string.in.h (memchr): Declare replacement. + * modules/string (Makefile.am): Trigger replacement. + * m4/string_h.m4 (gl_HEADER_STRING_H_DEFAULTS): Likewise. + * m4/memchr.m4 (gl_FUNC_MEMCHR): Use mmap to detect platform + bugs. + * doc/posix-functions/memchr.texi (memchr): Document the bug. + * modules/getpagesize (License): Relax license. + 2009-06-11 Bruno Haible <bruno@clisp.org> * lib/idpriv.h: Add more references.
--- a/doc/posix-functions/memchr.texi +++ b/doc/posix-functions/memchr.texi @@ -10,6 +10,10 @@ @itemize @item This function is missing on some older platforms. + +@item +This function dereferences too much memory on some platforms: +glibc 2.10 on x86_64 or Alpha @end itemize Portability problems not fixed by Gnulib:
--- a/lib/string.in.h +++ b/lib/string.in.h @@ -1,6 +1,6 @@ /* A GNU-like <string.h>. - Copyright (C) 1995-1996, 2001-2008 Free Software Foundation, Inc. + Copyright (C) 1995-1996, 2001-2009 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -49,6 +49,23 @@ #endif +/* Return the first instance of C within N bytes of S, or NULL. */ +#if @GNULIB_MEMCHR@ +# if @REPLACE_MEMCHR@ +# define memchr rpl_memchr +# endif +# if @REPLACE_MEMCHR@ +extern void *memchr (void const *__s, int __c, size_t __n) + __attribute__ ((__pure__)); +# endif +#elif defined GNULIB_POSIXCHECK +# undef memchr +# define memchr(s,c,n) \ + (GL_LINK_WARNING ("memchr has platform-specific bugs - " \ + "use gnulib module memchr for portability" ), \ + memchr (s, c, n)) +#endif + /* Return the first occurrence of NEEDLE in HAYSTACK. */ #if @GNULIB_MEMMEM@ # if @REPLACE_MEMMEM@
--- a/m4/memchr.m4 +++ b/m4/memchr.m4 @@ -1,4 +1,4 @@ -# memchr.m4 serial 5 +# memchr.m4 serial 6 dnl Copyright (C) 2002, 2003, 2004, 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, @@ -6,9 +6,76 @@ AC_DEFUN([gl_FUNC_MEMCHR], [ + dnl Check for prerequisites for memory fence checks. + gl_FUNC_MMAP_ANON + AC_CHECK_HEADERS_ONCE([sys/mman.h]) + AC_CHECK_FUNCS_ONCE([mprotect]) + + dnl These days, we assume memchr is present. But just in case... + AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS]) AC_REPLACE_FUNCS([memchr]) if test $ac_cv_func_memchr = no; then gl_PREREQ_MEMCHR + REPLACE_MEMCHR=1 + fi + + if test $ac_cv_func_memchr = yes; then + # Detect platform-specific bugs in some versions of glibc: + # memchr should not dereference anything with length 0 + # http://bugzilla.redhat.com/499689 + # memchr should not dereference overestimated length after a match + # http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=521737 + # Assume that memchr works on platforms that lack mprotect. + AC_CACHE_CHECK([whether memchr works], [gl_cv_func_memchr_works], + [AC_RUN_IFELSE([AC_LANG_PROGRAM([[ +#include <string.h> +#if HAVE_SYS_MMAN_H +# include <fcntl.h> +# include <unistd.h> +# include <sys/types.h> +# include <sys/mman.h> +# ifndef MAP_FILE +# define MAP_FILE 0 +# endif +#endif +]], [[ + char *fence = NULL; +#if HAVE_SYS_MMAN_H && HAVE_MPROTECT +# if HAVE_MAP_ANONYMOUS + const int flags = MAP_ANONYMOUS | MAP_PRIVATE; + const int fd = -1; +# else /* !HAVE_MAP_ANONYMOUS */ + const int flags = MAP_FILE | MAP_PRIVATE; + int fd = open ("/dev/zero", O_RDONLY, 0666); + if (fd >= 0) +# endif + { + int pagesize = getpagesize (); + char *two_pages = + (char *) mmap (NULL, 2 * pagesize, PROT_READ | PROT_WRITE, + flags, fd, 0); + if (two_pages != (char *)(-1) + && mprotect (two_pages + pagesize, pagesize, PROT_NONE) == 0) + fence = two_pages + pagesize; + } +#endif + if (fence) + { + if (memchr (fence, 0, 0)) + return 1; + strcpy (fence - 9, "12345678"); + if (memchr (fence - 9, 0, 79) != fence - 1) + return 2; + } + return 0; +]])], [gl_cv_func_memchr_works=yes], [gl_cv_func_memchr_works=no], + [dnl Be pessimistic for now. + gl_cv_func_memchr_works="guessing no"])]) + if test "$gl_cv_func_memchr_works" != yes; then + gl_PREREQ_MEMCHR + REPLACE_MEMCHR=1 + AC_LIBOBJ([memchr]) + fi fi ])
--- a/m4/string_h.m4 +++ b/m4/string_h.m4 @@ -1,11 +1,11 @@ # Configure a GNU-like replacement for <string.h>. -# Copyright (C) 2007, 2008 Free Software Foundation, Inc. +# Copyright (C) 2007, 2008, 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. -# serial 6 +# serial 7 # Written by Paul Eggert. @@ -32,6 +32,7 @@ AC_DEFUN([gl_HEADER_STRING_H_DEFAULTS], [ + GNULIB_MEMCHR=0; AC_SUBST([GNULIB_MEMCHR]) GNULIB_MEMMEM=0; AC_SUBST([GNULIB_MEMMEM]) GNULIB_MEMPCPY=0; AC_SUBST([GNULIB_MEMPCPY]) GNULIB_MEMRCHR=0; AC_SUBST([GNULIB_MEMRCHR]) @@ -83,6 +84,7 @@ HAVE_DECL_STRERROR=1; AC_SUBST([HAVE_DECL_STRERROR]) HAVE_DECL_STRSIGNAL=1; AC_SUBST([HAVE_DECL_STRSIGNAL]) HAVE_STRVERSCMP=1; AC_SUBST([HAVE_STRVERSCMP]) + REPLACE_MEMCHR=0; AC_SUBST([REPLACE_MEMCHR]) REPLACE_MEMMEM=0; AC_SUBST([REPLACE_MEMMEM]) REPLACE_STRDUP=0; AC_SUBST([REPLACE_STRDUP]) REPLACE_STRSTR=0; AC_SUBST([REPLACE_STRSTR])
--- a/modules/getpagesize +++ b/modules/getpagesize @@ -18,7 +18,7 @@ <unistd.h> License: -LGPL +LGPLv2+ Maintainer: Jim Meyering
--- a/modules/memchr +++ b/modules/memchr @@ -4,11 +4,16 @@ Files: lib/memchr.c m4/memchr.m4 +m4/mmap-anon.m4 Depends-on: +extensions +getpagesize +string configure.ac: gl_FUNC_MEMCHR +gl_STRING_MODULE_INDICATOR([memchr]) Makefile.am:
--- a/modules/memchr-tests +++ b/modules/memchr-tests @@ -1,16 +1,10 @@ Files: tests/test-memchr.c tests/zerosize-ptr.h -m4/mmap-anon.m4 Depends-on: -extensions -getpagesize configure.ac: -gl_FUNC_MMAP_ANON -AC_CHECK_HEADERS_ONCE([sys/mman.h]) -AC_CHECK_FUNCS_ONCE([mprotect]) Makefile.am: TESTS += test-memchr
--- a/modules/string +++ b/modules/string @@ -38,6 +38,7 @@ -e 's|@''GNULIB_MBSSPN''@|$(GNULIB_MBSSPN)|g' \ -e 's|@''GNULIB_MBSSEP''@|$(GNULIB_MBSSEP)|g' \ -e 's|@''GNULIB_MBSTOK_R''@|$(GNULIB_MBSTOK_R)|g' \ + -e 's|@''GNULIB_MEMCHR''@|$(GNULIB_MEMCHR)|g' \ -e 's|@''GNULIB_MEMMEM''@|$(GNULIB_MEMMEM)|g' \ -e 's|@''GNULIB_MEMPCPY''@|$(GNULIB_MEMPCPY)|g' \ -e 's|@''GNULIB_MEMRCHR''@|$(GNULIB_MEMRCHR)|g' \ @@ -74,6 +75,7 @@ -e 's|@''HAVE_DECL_STRERROR''@|$(HAVE_DECL_STRERROR)|g' \ -e 's|@''HAVE_DECL_STRSIGNAL''@|$(HAVE_DECL_STRSIGNAL)|g' \ -e 's|@''HAVE_STRVERSCMP''@|$(HAVE_STRVERSCMP)|g' \ + -e 's|@''REPLACE_MEMCHR''@|$(REPLACE_MEMCHR)|g' \ -e 's|@''REPLACE_MEMMEM''@|$(REPLACE_MEMMEM)|g' \ -e 's|@''REPLACE_STRCASESTR''@|$(REPLACE_STRCASESTR)|g' \ -e 's|@''REPLACE_STRDUP''@|$(REPLACE_STRDUP)|g' \