diff options
author | Anjali Nijhara <a.nijhara@samsung.com> | 2023-03-23 15:41:24 +0530 |
---|---|---|
committer | Anjali Nijhara <a.nijhara@samsung.com> | 2023-03-23 16:35:36 +0530 |
commit | 6ebfbbcdb4310742e8ea50fb526adb33ab52bf72 (patch) | |
tree | a3f63ae728260210a6e717523b107b419c0cb270 | |
parent | 886ec0232e4adb5b6f343f4e250cb09993e51213 (diff) | |
download | libidn-6ebfbbcdb4310742e8ea50fb526adb33ab52bf72.tar.gz libidn-6ebfbbcdb4310742e8ea50fb526adb33ab52bf72.tar.bz2 libidn-6ebfbbcdb4310742e8ea50fb526adb33ab52bf72.zip |
[CVE-2015-8948] Use getline instead of fgets with fixed-size buffer
http://git.savannah.gnu.org/cgit/libidn.git/commit/?id=570e68886c41c2e765e6218cb317d9a9a447a041
Change-Id: Ie16fe3755569f3d653246cf0560df71abdc12fd9
-rw-r--r-- | gl/Makefile.am | 195 | ||||
-rw-r--r-- | gl/getdelim.c | 135 | ||||
-rw-r--r-- | gl/getline.c | 27 | ||||
-rw-r--r-- | gl/m4/getdelim.m4 | 88 | ||||
-rw-r--r-- | gl/m4/getline.m4 | 96 | ||||
-rw-r--r-- | gl/m4/gnulib-cache.m4 | 3 | ||||
-rw-r--r-- | gl/m4/gnulib-comp.m4 | 41 | ||||
-rw-r--r-- | gl/m4/realloc.m4 | 76 | ||||
-rw-r--r-- | gl/realloc.m4 | 79 | ||||
-rw-r--r-- | gltests/Makefile.am | 165 | ||||
-rw-r--r-- | gltests/test-getdelim.c | 94 | ||||
-rw-r--r-- | gltests/test-getline.c | 94 | ||||
-rw-r--r-- | src/idn.c | 35 |
13 files changed, 956 insertions, 172 deletions
diff --git a/gl/Makefile.am b/gl/Makefile.am index 86af82b..a53bbc3 100644 --- a/gl/Makefile.am +++ b/gl/Makefile.am @@ -21,7 +21,7 @@ # the same distribution terms as the rest of that program. # # Generated by gnulib-tool. -# Reproduce by: gnulib-tool --import --dir=. --local-dir=gl/override --lib=libgnu --source-base=gl --m4-base=gl/m4 --doc-base=doc --tests-base=gltests --aux-dir=build-aux --with-tests --avoid=binary-io-tests --avoid=fcntl-h-tests --avoid=stdlib-tests --avoid=string-tests --avoid=sys_stat-tests --avoid=time-tests --avoid=unistd-tests --avoid=update-copyright-tests --avoid=wchar-tests --no-conditional-dependencies --libtool --macro-prefix=gl --no-vc-files autobuild csharpcomp-script csharpexec-script error fdl-1.3 gendocs getopt-gnu gnupload gpl-3.0 lgpl-2.1 maintainer-makefile manywarnings pmccabe2html progname update-copyright useless-if-before-free valgrind-tests vc-list-files version-etc warnings +# Reproduce by: gnulib-tool --import --dir=. --local-dir=gl/override --lib=libgnu --source-base=gl --m4-base=gl/m4 --doc-base=doc --tests-base=gltests --aux-dir=build-aux --with-tests --avoid=fcntl-h-tests --avoid=stdlib-tests --avoid=string-tests --avoid=sys_stat-tests --avoid=time-tests --avoid=unistd-tests --avoid=update-copyright-tests --avoid=wchar-tests --no-conditional-dependencies --libtool --macro-prefix=gl --no-vc-files autobuild csharpcomp-script csharpexec-script error fdl-1.3 gendocs getline getopt-gnu gnupload maintainer-makefile manywarnings pmccabe2html progname update-copyright useless-if-before-free valgrind-tests vc-list-files version-etc warnings AUTOMAKE_OPTIONS = 1.5 gnits @@ -116,6 +116,24 @@ EXTRA_DIST += $(top_srcdir)/build-aux/gendocs.sh ## end gnulib module gendocs +## begin gnulib module getdelim + + +EXTRA_DIST += getdelim.c + +EXTRA_libgnu_la_SOURCES += getdelim.c + +## end gnulib module getdelim + +## begin gnulib module getline + + +EXTRA_DIST += getline.c + +EXTRA_libgnu_la_SOURCES += getline.c + +## end gnulib module getline + ## begin gnulib module getopt-posix BUILT_SOURCES += $(GETOPT_H) @@ -210,6 +228,26 @@ libgnu_la_SOURCES += progname.h progname.c ## end gnulib module progname +## begin gnulib module realloc-posix + +EXTRA_DIST += realloc.c + +EXTRA_libgnu_la_SOURCES += realloc.c + +## end gnulib module realloc-posix + +## begin gnulib module snippet/_Noreturn + +# Because this Makefile snippet defines a variable used by other +# gnulib Makefile snippets, it must be present in all Makefile.am that +# need it. This is ensured by the applicability 'all' defined above. + +_NORETURN_H=$(top_srcdir)/build-aux/snippet/_Noreturn.h + +EXTRA_DIST += $(top_srcdir)/build-aux/snippet/_Noreturn.h + +## end gnulib module snippet/_Noreturn + ## begin gnulib module snippet/arg-nonnull # The BUILT_SOURCES created by this Makefile snippet are not used via #include @@ -307,6 +345,56 @@ EXTRA_DIST += stdarg.in.h ## end gnulib module stdarg +## begin gnulib module stdint + +BUILT_SOURCES += $(STDINT_H) + +# We need the following in order to create <stdint.h> when the system +# doesn't have one that works with the given compiler. +if GL_GENERATE_STDINT_H +stdint.h: stdint.in.h $(top_builddir)/config.status + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + sed -e 's|@''GUARD_PREFIX''@|GL|g' \ + -e 's/@''HAVE_STDINT_H''@/$(HAVE_STDINT_H)/g' \ + -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ + -e 's|@''NEXT_STDINT_H''@|$(NEXT_STDINT_H)|g' \ + -e 's/@''HAVE_SYS_TYPES_H''@/$(HAVE_SYS_TYPES_H)/g' \ + -e 's/@''HAVE_INTTYPES_H''@/$(HAVE_INTTYPES_H)/g' \ + -e 's/@''HAVE_SYS_INTTYPES_H''@/$(HAVE_SYS_INTTYPES_H)/g' \ + -e 's/@''HAVE_SYS_BITYPES_H''@/$(HAVE_SYS_BITYPES_H)/g' \ + -e 's/@''HAVE_WCHAR_H''@/$(HAVE_WCHAR_H)/g' \ + -e 's/@''HAVE_LONG_LONG_INT''@/$(HAVE_LONG_LONG_INT)/g' \ + -e 's/@''HAVE_UNSIGNED_LONG_LONG_INT''@/$(HAVE_UNSIGNED_LONG_LONG_INT)/g' \ + -e 's/@''APPLE_UNIVERSAL_BUILD''@/$(APPLE_UNIVERSAL_BUILD)/g' \ + -e 's/@''BITSIZEOF_PTRDIFF_T''@/$(BITSIZEOF_PTRDIFF_T)/g' \ + -e 's/@''PTRDIFF_T_SUFFIX''@/$(PTRDIFF_T_SUFFIX)/g' \ + -e 's/@''BITSIZEOF_SIG_ATOMIC_T''@/$(BITSIZEOF_SIG_ATOMIC_T)/g' \ + -e 's/@''HAVE_SIGNED_SIG_ATOMIC_T''@/$(HAVE_SIGNED_SIG_ATOMIC_T)/g' \ + -e 's/@''SIG_ATOMIC_T_SUFFIX''@/$(SIG_ATOMIC_T_SUFFIX)/g' \ + -e 's/@''BITSIZEOF_SIZE_T''@/$(BITSIZEOF_SIZE_T)/g' \ + -e 's/@''SIZE_T_SUFFIX''@/$(SIZE_T_SUFFIX)/g' \ + -e 's/@''BITSIZEOF_WCHAR_T''@/$(BITSIZEOF_WCHAR_T)/g' \ + -e 's/@''HAVE_SIGNED_WCHAR_T''@/$(HAVE_SIGNED_WCHAR_T)/g' \ + -e 's/@''WCHAR_T_SUFFIX''@/$(WCHAR_T_SUFFIX)/g' \ + -e 's/@''BITSIZEOF_WINT_T''@/$(BITSIZEOF_WINT_T)/g' \ + -e 's/@''HAVE_SIGNED_WINT_T''@/$(HAVE_SIGNED_WINT_T)/g' \ + -e 's/@''WINT_T_SUFFIX''@/$(WINT_T_SUFFIX)/g' \ + < $(srcdir)/stdint.in.h; \ + } > $@-t && \ + mv $@-t $@ +else +stdint.h: $(top_builddir)/config.status + rm -f $@ +endif +MOSTLYCLEANFILES += stdint.h stdint.h-t + +EXTRA_DIST += stdint.in.h + +## end gnulib module stdint + ## begin gnulib module stddef BUILT_SOURCES += $(STDDEF_H) @@ -337,6 +425,111 @@ EXTRA_DIST += stddef.in.h ## end gnulib module stddef +## begin gnulib module stdlib + +BUILT_SOURCES += stdlib.h + +# We need the following in order to create <stdlib.h> when the system +# doesn't have one that works with the given compiler. +stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \ + $(_NORETURN_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ + sed -e 's|@''GUARD_PREFIX''@|GL|g' \ + -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ + -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ + -e 's|@''NEXT_STDLIB_H''@|$(NEXT_STDLIB_H)|g' \ + -e 's/@''GNULIB__EXIT''@/$(GNULIB__EXIT)/g' \ + -e 's/@''GNULIB_ATOLL''@/$(GNULIB_ATOLL)/g' \ + -e 's/@''GNULIB_CALLOC_POSIX''@/$(GNULIB_CALLOC_POSIX)/g' \ + -e 's/@''GNULIB_CANONICALIZE_FILE_NAME''@/$(GNULIB_CANONICALIZE_FILE_NAME)/g' \ + -e 's/@''GNULIB_GETLOADAVG''@/$(GNULIB_GETLOADAVG)/g' \ + -e 's/@''GNULIB_GETSUBOPT''@/$(GNULIB_GETSUBOPT)/g' \ + -e 's/@''GNULIB_GRANTPT''@/$(GNULIB_GRANTPT)/g' \ + -e 's/@''GNULIB_MALLOC_POSIX''@/$(GNULIB_MALLOC_POSIX)/g' \ + -e 's/@''GNULIB_MBTOWC''@/$(GNULIB_MBTOWC)/g' \ + -e 's/@''GNULIB_MKDTEMP''@/$(GNULIB_MKDTEMP)/g' \ + -e 's/@''GNULIB_MKOSTEMP''@/$(GNULIB_MKOSTEMP)/g' \ + -e 's/@''GNULIB_MKOSTEMPS''@/$(GNULIB_MKOSTEMPS)/g' \ + -e 's/@''GNULIB_MKSTEMP''@/$(GNULIB_MKSTEMP)/g' \ + -e 's/@''GNULIB_MKSTEMPS''@/$(GNULIB_MKSTEMPS)/g' \ + -e 's/@''GNULIB_POSIX_OPENPT''@/$(GNULIB_POSIX_OPENPT)/g' \ + -e 's/@''GNULIB_PTSNAME''@/$(GNULIB_PTSNAME)/g' \ + -e 's/@''GNULIB_PTSNAME_R''@/$(GNULIB_PTSNAME_R)/g' \ + -e 's/@''GNULIB_PUTENV''@/$(GNULIB_PUTENV)/g' \ + -e 's/@''GNULIB_QSORT_R''@/$(GNULIB_QSORT_R)/g' \ + -e 's/@''GNULIB_RANDOM''@/$(GNULIB_RANDOM)/g' \ + -e 's/@''GNULIB_RANDOM_R''@/$(GNULIB_RANDOM_R)/g' \ + -e 's/@''GNULIB_REALLOC_POSIX''@/$(GNULIB_REALLOC_POSIX)/g' \ + -e 's/@''GNULIB_REALPATH''@/$(GNULIB_REALPATH)/g' \ + -e 's/@''GNULIB_RPMATCH''@/$(GNULIB_RPMATCH)/g' \ + -e 's/@''GNULIB_SECURE_GETENV''@/$(GNULIB_SECURE_GETENV)/g' \ + -e 's/@''GNULIB_SETENV''@/$(GNULIB_SETENV)/g' \ + -e 's/@''GNULIB_STRTOD''@/$(GNULIB_STRTOD)/g' \ + -e 's/@''GNULIB_STRTOLL''@/$(GNULIB_STRTOLL)/g' \ + -e 's/@''GNULIB_STRTOULL''@/$(GNULIB_STRTOULL)/g' \ + -e 's/@''GNULIB_SYSTEM_POSIX''@/$(GNULIB_SYSTEM_POSIX)/g' \ + -e 's/@''GNULIB_UNLOCKPT''@/$(GNULIB_UNLOCKPT)/g' \ + -e 's/@''GNULIB_UNSETENV''@/$(GNULIB_UNSETENV)/g' \ + -e 's/@''GNULIB_WCTOMB''@/$(GNULIB_WCTOMB)/g' \ + < $(srcdir)/stdlib.in.h | \ + sed -e 's|@''HAVE__EXIT''@|$(HAVE__EXIT)|g' \ + -e 's|@''HAVE_ATOLL''@|$(HAVE_ATOLL)|g' \ + -e 's|@''HAVE_CANONICALIZE_FILE_NAME''@|$(HAVE_CANONICALIZE_FILE_NAME)|g' \ + -e 's|@''HAVE_DECL_GETLOADAVG''@|$(HAVE_DECL_GETLOADAVG)|g' \ + -e 's|@''HAVE_GETSUBOPT''@|$(HAVE_GETSUBOPT)|g' \ + -e 's|@''HAVE_GRANTPT''@|$(HAVE_GRANTPT)|g' \ + -e 's|@''HAVE_MKDTEMP''@|$(HAVE_MKDTEMP)|g' \ + -e 's|@''HAVE_MKOSTEMP''@|$(HAVE_MKOSTEMP)|g' \ + -e 's|@''HAVE_MKOSTEMPS''@|$(HAVE_MKOSTEMPS)|g' \ + -e 's|@''HAVE_MKSTEMP''@|$(HAVE_MKSTEMP)|g' \ + -e 's|@''HAVE_MKSTEMPS''@|$(HAVE_MKSTEMPS)|g' \ + -e 's|@''HAVE_POSIX_OPENPT''@|$(HAVE_POSIX_OPENPT)|g' \ + -e 's|@''HAVE_PTSNAME''@|$(HAVE_PTSNAME)|g' \ + -e 's|@''HAVE_PTSNAME_R''@|$(HAVE_PTSNAME_R)|g' \ + -e 's|@''HAVE_RANDOM''@|$(HAVE_RANDOM)|g' \ + -e 's|@''HAVE_RANDOM_H''@|$(HAVE_RANDOM_H)|g' \ + -e 's|@''HAVE_RANDOM_R''@|$(HAVE_RANDOM_R)|g' \ + -e 's|@''HAVE_REALPATH''@|$(HAVE_REALPATH)|g' \ + -e 's|@''HAVE_RPMATCH''@|$(HAVE_RPMATCH)|g' \ + -e 's|@''HAVE_SECURE_GETENV''@|$(HAVE_SECURE_GETENV)|g' \ + -e 's|@''HAVE_DECL_SETENV''@|$(HAVE_DECL_SETENV)|g' \ + -e 's|@''HAVE_STRTOD''@|$(HAVE_STRTOD)|g' \ + -e 's|@''HAVE_STRTOLL''@|$(HAVE_STRTOLL)|g' \ + -e 's|@''HAVE_STRTOULL''@|$(HAVE_STRTOULL)|g' \ + -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_UNLOCKPT''@|$(HAVE_UNLOCKPT)|g' \ + -e 's|@''HAVE_DECL_UNSETENV''@|$(HAVE_DECL_UNSETENV)|g' \ + -e 's|@''REPLACE_CALLOC''@|$(REPLACE_CALLOC)|g' \ + -e 's|@''REPLACE_CANONICALIZE_FILE_NAME''@|$(REPLACE_CANONICALIZE_FILE_NAME)|g' \ + -e 's|@''REPLACE_MALLOC''@|$(REPLACE_MALLOC)|g' \ + -e 's|@''REPLACE_MBTOWC''@|$(REPLACE_MBTOWC)|g' \ + -e 's|@''REPLACE_MKSTEMP''@|$(REPLACE_MKSTEMP)|g' \ + -e 's|@''REPLACE_PTSNAME''@|$(REPLACE_PTSNAME)|g' \ + -e 's|@''REPLACE_PTSNAME_R''@|$(REPLACE_PTSNAME_R)|g' \ + -e 's|@''REPLACE_PUTENV''@|$(REPLACE_PUTENV)|g' \ + -e 's|@''REPLACE_QSORT_R''@|$(REPLACE_QSORT_R)|g' \ + -e 's|@''REPLACE_RANDOM_R''@|$(REPLACE_RANDOM_R)|g' \ + -e 's|@''REPLACE_REALLOC''@|$(REPLACE_REALLOC)|g' \ + -e 's|@''REPLACE_REALPATH''@|$(REPLACE_REALPATH)|g' \ + -e 's|@''REPLACE_SETENV''@|$(REPLACE_SETENV)|g' \ + -e 's|@''REPLACE_STRTOD''@|$(REPLACE_STRTOD)|g' \ + -e 's|@''REPLACE_UNSETENV''@|$(REPLACE_UNSETENV)|g' \ + -e 's|@''REPLACE_WCTOMB''@|$(REPLACE_WCTOMB)|g' \ + -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ + -e '/definition of _Noreturn/r $(_NORETURN_H)' \ + -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)'; \ + } > $@-t && \ + mv $@-t $@ +MOSTLYCLEANFILES += stdlib.h stdlib.h-t + +EXTRA_DIST += stdlib.in.h + +## end gnulib module stdlib + ## begin gnulib module strerror diff --git a/gl/getdelim.c b/gl/getdelim.c new file mode 100644 index 0000000..88258e5 --- /dev/null +++ b/gl/getdelim.c @@ -0,0 +1,135 @@ +/* getdelim.c --- Implementation of replacement getdelim function. + Copyright (C) 1994, 1996-1998, 2001, 2003, 2005-2015 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 the Free Software Foundation; either version 3, or (at + your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. */ + +/* Ported from glibc by Simon Josefsson. */ + +/* Don't use __attribute__ __nonnull__ in this compilation unit. Otherwise gcc + optimizes away the lineptr == NULL || n == NULL || fp == NULL tests below. */ +#define _GL_ARG_NONNULL(params) + +#include <config.h> + +#include <stdio.h> + +#include <limits.h> +#include <stdint.h> +#include <stdlib.h> +#include <errno.h> + +#ifndef SSIZE_MAX +# define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2)) +#endif + +#if USE_UNLOCKED_IO +# include "unlocked-io.h" +# define getc_maybe_unlocked(fp) getc(fp) +#elif !HAVE_FLOCKFILE || !HAVE_FUNLOCKFILE || !HAVE_DECL_GETC_UNLOCKED +# undef flockfile +# undef funlockfile +# define flockfile(x) ((void) 0) +# define funlockfile(x) ((void) 0) +# define getc_maybe_unlocked(fp) getc(fp) +#else +# define getc_maybe_unlocked(fp) getc_unlocked(fp) +#endif + +/* Read up to (and including) a DELIMITER from FP into *LINEPTR (and + NUL-terminate it). *LINEPTR is a pointer returned from malloc (or + NULL), pointing to *N characters of space. It is realloc'ed as + necessary. Returns the number of characters read (not including + the null terminator), or -1 on error or EOF. */ + +ssize_t +getdelim (char **lineptr, size_t *n, int delimiter, FILE *fp) +{ + ssize_t result; + size_t cur_len = 0; + + if (lineptr == NULL || n == NULL || fp == NULL) + { + errno = EINVAL; + return -1; + } + + flockfile (fp); + + if (*lineptr == NULL || *n == 0) + { + char *new_lineptr; + *n = 120; + new_lineptr = (char *) realloc (*lineptr, *n); + if (new_lineptr == NULL) + { + result = -1; + goto unlock_return; + } + *lineptr = new_lineptr; + } + + for (;;) + { + int i; + + i = getc_maybe_unlocked (fp); + if (i == EOF) + { + result = -1; + break; + } + + /* Make enough space for len+1 (for final NUL) bytes. */ + if (cur_len + 1 >= *n) + { + size_t needed_max = + SSIZE_MAX < SIZE_MAX ? (size_t) SSIZE_MAX + 1 : SIZE_MAX; + size_t needed = 2 * *n + 1; /* Be generous. */ + char *new_lineptr; + + if (needed_max < needed) + needed = needed_max; + if (cur_len + 1 >= needed) + { + result = -1; + errno = EOVERFLOW; + goto unlock_return; + } + + new_lineptr = (char *) realloc (*lineptr, needed); + if (new_lineptr == NULL) + { + result = -1; + goto unlock_return; + } + + *lineptr = new_lineptr; + *n = needed; + } + + (*lineptr)[cur_len] = i; + cur_len++; + + if (i == delimiter) + break; + } + (*lineptr)[cur_len] = '\0'; + result = cur_len ? cur_len : result; + + unlock_return: + funlockfile (fp); /* doesn't set errno */ + + return result; +} diff --git a/gl/getline.c b/gl/getline.c new file mode 100644 index 0000000..811c773 --- /dev/null +++ b/gl/getline.c @@ -0,0 +1,27 @@ +/* getline.c --- Implementation of replacement getline function. + Copyright (C) 2005-2007, 2009-2015 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 the Free Software Foundation; either version 3, or (at + your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. */ + +/* Written by Simon Josefsson. */ + +#include <config.h> + +#include <stdio.h> + +ssize_t +getline (char **lineptr, size_t *n, FILE *stream) +{ + return getdelim (lineptr, n, '\n', stream); +} diff --git a/gl/m4/getdelim.m4 b/gl/m4/getdelim.m4 new file mode 100644 index 0000000..af9b1fa --- /dev/null +++ b/gl/m4/getdelim.m4 @@ -0,0 +1,88 @@ +# getdelim.m4 serial 10 + +dnl Copyright (C) 2005-2007, 2009-2015 Free Software Foundation, Inc. +dnl +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_PREREQ([2.59]) + +AC_DEFUN([gl_FUNC_GETDELIM], +[ + AC_REQUIRE([gl_STDIO_H_DEFAULTS]) + + dnl Persuade glibc <stdio.h> to declare getdelim(). + AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) + + AC_CHECK_DECLS_ONCE([getdelim]) + + AC_CHECK_FUNCS_ONCE([getdelim]) + if test $ac_cv_func_getdelim = yes; then + HAVE_GETDELIM=1 + dnl Found it in some library. Verify that it works. + AC_CACHE_CHECK([for working getdelim function], [gl_cv_func_working_getdelim], + [echo fooNbarN | tr -d '\012' | tr N '\012' > conftest.data + AC_RUN_IFELSE([AC_LANG_SOURCE([[ +# include <stdio.h> +# include <stdlib.h> +# include <string.h> + int main () + { + FILE *in = fopen ("./conftest.data", "r"); + if (!in) + return 1; + { + /* Test result for a NULL buffer and a zero size. + Based on a test program from Karl Heuer. */ + char *line = NULL; + size_t siz = 0; + int len = getdelim (&line, &siz, '\n', in); + if (!(len == 4 && line && strcmp (line, "foo\n") == 0)) + return 2; + } + { + /* Test result for a NULL buffer and a non-zero size. + This crashes on FreeBSD 8.0. */ + char *line = NULL; + size_t siz = (size_t)(~0) / 4; + if (getdelim (&line, &siz, '\n', in) == -1) + return 3; + } + return 0; + } + ]])], [gl_cv_func_working_getdelim=yes] dnl The library version works. + , [gl_cv_func_working_getdelim=no] dnl The library version does NOT work. + , dnl We're cross compiling. Assume it works on glibc2 systems. + [AC_EGREP_CPP([Lucky GNU user], + [ +#include <features.h> +#ifdef __GNU_LIBRARY__ + #if (__GLIBC__ >= 2) && !defined __UCLIBC__ + Lucky GNU user + #endif +#endif + ], + [gl_cv_func_working_getdelim="guessing yes"], + [gl_cv_func_working_getdelim="guessing no"])] + )]) + case "$gl_cv_func_working_getdelim" in + *no) + REPLACE_GETDELIM=1 + ;; + esac + else + HAVE_GETDELIM=0 + fi + + if test $ac_cv_have_decl_getdelim = no; then + HAVE_DECL_GETDELIM=0 + fi +]) + +# Prerequisites of lib/getdelim.c. +AC_DEFUN([gl_PREREQ_GETDELIM], +[ + AC_CHECK_FUNCS([flockfile funlockfile]) + AC_CHECK_DECLS([getc_unlocked]) +]) diff --git a/gl/m4/getline.m4 b/gl/m4/getline.m4 new file mode 100644 index 0000000..a35f3a2 --- /dev/null +++ b/gl/m4/getline.m4 @@ -0,0 +1,96 @@ +# getline.m4 serial 26 + +dnl Copyright (C) 1998-2003, 2005-2007, 2009-2015 Free Software Foundation, +dnl Inc. +dnl +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_PREREQ([2.59]) + +dnl See if there's a working, system-supplied version of the getline function. +dnl We can't just do AC_REPLACE_FUNCS([getline]) because some systems +dnl have a function by that name in -linet that doesn't have anything +dnl to do with the function we need. +AC_DEFUN([gl_FUNC_GETLINE], +[ + AC_REQUIRE([gl_STDIO_H_DEFAULTS]) + + dnl Persuade glibc <stdio.h> to declare getline(). + AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) + + AC_CHECK_DECLS_ONCE([getline]) + + gl_getline_needs_run_time_check=no + AC_CHECK_FUNC([getline], + [dnl Found it in some library. Verify that it works. + gl_getline_needs_run_time_check=yes], + [am_cv_func_working_getline=no]) + if test $gl_getline_needs_run_time_check = yes; then + AC_CACHE_CHECK([for working getline function], [am_cv_func_working_getline], + [echo fooNbarN | tr -d '\012' | tr N '\012' > conftest.data + AC_RUN_IFELSE([AC_LANG_SOURCE([[ +# include <stdio.h> +# include <stdlib.h> +# include <string.h> + int main () + { + FILE *in = fopen ("./conftest.data", "r"); + if (!in) + return 1; + { + /* Test result for a NULL buffer and a zero size. + Based on a test program from Karl Heuer. */ + char *line = NULL; + size_t siz = 0; + int len = getline (&line, &siz, in); + if (!(len == 4 && line && strcmp (line, "foo\n") == 0)) + return 2; + } + { + /* Test result for a NULL buffer and a non-zero size. + This crashes on FreeBSD 8.0. */ + char *line = NULL; + size_t siz = (size_t)(~0) / 4; + if (getline (&line, &siz, in) == -1) + return 3; + } + return 0; + } + ]])], [am_cv_func_working_getline=yes] dnl The library version works. + , [am_cv_func_working_getline=no] dnl The library version does NOT work. + , dnl We're cross compiling. Assume it works on glibc2 systems. + [AC_EGREP_CPP([Lucky GNU user], + [ +#include <features.h> +#ifdef __GNU_LIBRARY__ + #if (__GLIBC__ >= 2) && !defined __UCLIBC__ + Lucky GNU user + #endif +#endif + ], + [am_cv_func_working_getline="guessing yes"], + [am_cv_func_working_getline="guessing no"])] + )]) + fi + + if test $ac_cv_have_decl_getline = no; then + HAVE_DECL_GETLINE=0 + fi + + case "$am_cv_func_working_getline" in + *no) + dnl Set REPLACE_GETLINE always: Even if we have not found the broken + dnl getline function among $LIBS, it may exist in libinet and the + dnl executable may be linked with -linet. + REPLACE_GETLINE=1 + ;; + esac +]) + +# Prerequisites of lib/getline.c. +AC_DEFUN([gl_PREREQ_GETLINE], +[ + : +]) diff --git a/gl/m4/gnulib-cache.m4 b/gl/m4/gnulib-cache.m4 index 92865c6..f6fd035 100644 --- a/gl/m4/gnulib-cache.m4 +++ b/gl/m4/gnulib-cache.m4 @@ -27,7 +27,7 @@ # Specification in the form of a command-line invocation: -# gnulib-tool --import --dir=. --local-dir=gl/override --lib=libgnu --source-base=gl --m4-base=gl/m4 --doc-base=doc --tests-base=gltests --aux-dir=build-aux --with-tests --avoid=binary-io-tests --avoid=fcntl-h-tests --avoid=stdlib-tests --avoid=string-tests --avoid=sys_stat-tests --avoid=time-tests --avoid=unistd-tests --avoid=update-copyright-tests --avoid=wchar-tests --no-conditional-dependencies --libtool --macro-prefix=gl --no-vc-files autobuild csharpcomp-script csharpexec-script error fdl-1.3 gendocs getopt-gnu gnupload gpl-3.0 lgpl-2.1 maintainer-makefile manywarnings pmccabe2html progname update-copyright useless-if-before-free valgrind-tests vc-list-files version-etc warnings +# gnulib-tool --import --dir=. --local-dir=gl/override --lib=libgnu --source-base=gl --m4-base=gl/m4 --doc-base=doc --tests-base=gltests --aux-dir=build-aux --with-tests --avoid=fcntl-h-tests --avoid=stdlib-tests --avoid=string-tests --avoid=sys_stat-tests --avoid=time-tests --avoid=unistd-tests --avoid=update-copyright-tests --avoid=wchar-tests --no-conditional-dependencies --libtool --macro-prefix=gl --no-vc-files autobuild csharpcomp-script csharpexec-script error fdl-1.3 gendocs getline getopt-gnu gnupload maintainer-makefile manywarnings pmccabe2html progname update-copyright useless-if-before-free valgrind-tests vc-list-files version-etc warnings # Specification in the form of a few gnulib-tool.m4 macro invocations: gl_LOCAL_DIR([gl/override]) @@ -38,6 +38,7 @@ gl_MODULES([ error fdl-1.3 gendocs + getline getopt-gnu gnupload gpl-3.0 diff --git a/gl/m4/gnulib-comp.m4 b/gl/m4/gnulib-comp.m4 index 1bf4161..1150aba 100644 --- a/gl/m4/gnulib-comp.m4 +++ b/gl/m4/gnulib-comp.m4 @@ -71,6 +71,10 @@ AC_DEFUN([gl_EARLY], # Code from module gendocs: # Code from module getcwd-lgpl: # Code from module getcwd-lgpl-tests: + # Code from module getdelim: + # Code from module getdelim-tests: + # Code from module getline: + # Code from module getline-tests: # Code from module getopt-gnu: # Code from module getopt-posix: # Code from module getopt-posix-tests: @@ -107,6 +111,7 @@ AC_DEFUN([gl_EARLY], # Code from module pmccabe2html: # Code from module progname: # Code from module putenv: + # Code from module realloc-posix: # Code from module same-inode: # Code from module setenv: # Code from module setenv-tests: @@ -184,6 +189,19 @@ fi m4_ifdef([AM_XGETTEXT_OPTION], [AM_][XGETTEXT_OPTION([--flag=error:3:c-format]) AM_][XGETTEXT_OPTION([--flag=error_at_line:5:c-format])]) +AC_REQUIRE([gl_EXTERN_INLINE]) + gl_FUNC_GETDELIM + if test $HAVE_GETDELIM = 0 || test $REPLACE_GETDELIM = 1; then + AC_LIBOBJ([getdelim]) + gl_PREREQ_GETDELIM + fi + gl_STDIO_MODULE_INDICATOR([getdelim]) + gl_FUNC_GETLINE + if test $REPLACE_GETLINE = 1; then + AC_LIBOBJ([getline]) + gl_PREREQ_GETLINE + fi + gl_STDIO_MODULE_INDICATOR([getline]) gl_FUNC_GETOPT_GNU if test $REPLACE_GETOPT = 1; then AC_LIBOBJ([getopt]) @@ -219,12 +237,20 @@ gl_MSVC_NOTHROW if test $HAVE_MSVC_INVALID_PARAMETER_HANDLER = 1; then AC_LIBOBJ([msvc-nothrow]) fi +gl_MULTIARCH AC_PATH_PROG([PMCCABE], [pmccabe], [false]) AC_CHECK_DECLS([program_invocation_name], [], [], [#include <errno.h>]) AC_CHECK_DECLS([program_invocation_short_name], [], [], [#include <errno.h>]) +gl_FUNC_REALLOC_POSIX +if test $REPLACE_REALLOC = 1; then + AC_LIBOBJ([realloc]) +fi +gl_STDLIB_MODULE_INDICATOR([realloc-posix]) gt_TYPE_SSIZE_T gl_STDARG_H gl_STDDEF_H +gl_STDINT_H +gl_STDLIB_H gl_FUNC_STRERROR if test $REPLACE_STRERROR = 1; then AC_LIBOBJ([strerror]) @@ -335,7 +361,6 @@ if test $REPLACE_MALLOC = 1; then fi gl_STDLIB_MODULE_INDICATOR([malloc-posix]) gl_MALLOCA -gl_MULTIARCH gl_FUNC_OPEN if test $REPLACE_OPEN = 1; then AC_LIBOBJ([open]) @@ -360,11 +385,9 @@ if test $REPLACE_STAT = 1; then fi gl_SYS_STAT_MODULE_INDICATOR([stat]) AM_STDBOOL_H -gl_STDINT_H gt_TYPE_WCHAR_T gt_TYPE_WINT_T gl_STDIO_H -gl_STDLIB_H gl_FUNC_SYMLINK if test $HAVE_SYMLINK = 0 || test $REPLACE_SYMLINK = 1; then AC_LIBOBJ([symlink]) @@ -495,6 +518,8 @@ AC_DEFUN([gl_FILE_LIST], [ lib/errno.in.h lib/error.c lib/error.h + lib/getdelim.c + lib/getline.c lib/getopt.c lib/getopt.in.h lib/getopt1.c @@ -507,8 +532,11 @@ AC_DEFUN([gl_FILE_LIST], [ lib/msvc-nothrow.h lib/progname.c lib/progname.h + lib/realloc.c lib/stdarg.in.h lib/stddef.in.h + lib/stdint.in.h + lib/stdlib.in.h lib/strerror-override.c lib/strerror-override.h lib/strerror.c @@ -535,6 +563,8 @@ AC_DEFUN([gl_FILE_LIST], [ m4/fdopen.m4 m4/fstat.m4 m4/getcwd.m4 + m4/getdelim.m4 + m4/getline.m4 m4/getopt.m4 m4/gnulib-common.m4 m4/include_next.m4 @@ -554,6 +584,7 @@ AC_DEFUN([gl_FILE_LIST], [ m4/open.m4 m4/pathmax.m4 m4/putenv.m4 + m4/realloc.m4 m4/setenv.m4 m4/ssize_t.m4 m4/stat.m4 @@ -593,6 +624,8 @@ AC_DEFUN([gl_FILE_LIST], [ tests/test-fwrite.c tests/test-getcwd-lgpl.c tests/test-getopt.c + tests/test-getdelim.c + tests/test-getline.c tests/test-getopt.h tests/test-getopt_long.h tests/test-ignore-value.c @@ -646,9 +679,7 @@ AC_DEFUN([gl_FILE_LIST], [ tests=lib/setenv.c tests=lib/stat.c tests=lib/stdbool.in.h - tests=lib/stdint.in.h tests=lib/stdio.in.h - tests=lib/stdlib.in.h tests=lib/symlink.c tests=lib/sys_stat.in.h tests=lib/time.in.h diff --git a/gl/m4/realloc.m4 b/gl/m4/realloc.m4 new file mode 100644 index 0000000..0e1d338 --- /dev/null +++ b/gl/m4/realloc.m4 @@ -0,0 +1,76 @@ +# realloc.m4 serial 13 +dnl Copyright (C) 2007, 2009-2015 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. + +m4_version_prereq([2.70], [] ,[ + +# This is taken from the following Autoconf patch: +# http://git.savannah.gnu.org/gitweb/?p=autoconf.git;a=commitdiff;h=7fbb553727ed7e0e689a17594b58559ecf3ea6e9 +AC_DEFUN([_AC_FUNC_REALLOC_IF], +[ + AC_REQUIRE([AC_HEADER_STDC])dnl + AC_REQUIRE([AC_CANONICAL_HOST])dnl for cross-compiles + AC_CHECK_HEADERS([stdlib.h]) + AC_CACHE_CHECK([for GNU libc compatible realloc], + [ac_cv_func_realloc_0_nonnull], + [AC_RUN_IFELSE( + [AC_LANG_PROGRAM( + [[#if defined STDC_HEADERS || defined HAVE_STDLIB_H + # include <stdlib.h> + #else + char *realloc (); + #endif + ]], + [[return ! realloc (0, 0);]]) + ], + [ac_cv_func_realloc_0_nonnull=yes], + [ac_cv_func_realloc_0_nonnull=no], + [case "$host_os" in + # Guess yes on platforms where we know the result. + *-gnu* | freebsd* | netbsd* | openbsd* \ + | hpux* | solaris* | cygwin* | mingw*) + ac_cv_func_realloc_0_nonnull=yes ;; + # If we don't know, assume the worst. + *) ac_cv_func_realloc_0_nonnull=no ;; + esac + ]) + ]) + AS_IF([test $ac_cv_func_realloc_0_nonnull = yes], [$1], [$2]) +])# AC_FUNC_REALLOC + +]) + +# gl_FUNC_REALLOC_GNU +# ------------------- +# Test whether 'realloc (0, 0)' is handled like in GNU libc, and replace +# realloc if it is not. +AC_DEFUN([gl_FUNC_REALLOC_GNU], +[ + AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) + dnl _AC_FUNC_REALLOC_IF is defined in Autoconf. + _AC_FUNC_REALLOC_IF( + [AC_DEFINE([HAVE_REALLOC_GNU], [1], + [Define to 1 if your system has a GNU libc compatible 'realloc' + function, and to 0 otherwise.])], + [AC_DEFINE([HAVE_REALLOC_GNU], [0]) + REPLACE_REALLOC=1 + ]) +])# gl_FUNC_REALLOC_GNU + +# gl_FUNC_REALLOC_POSIX +# --------------------- +# Test whether 'realloc' is POSIX compliant (sets errno to ENOMEM when it +# fails), and replace realloc if it is not. +AC_DEFUN([gl_FUNC_REALLOC_POSIX], +[ + AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) + AC_REQUIRE([gl_CHECK_MALLOC_POSIX]) + if test $gl_cv_func_malloc_posix = yes; then + AC_DEFINE([HAVE_REALLOC_POSIX], [1], + [Define if the 'realloc' function is POSIX compliant.]) + else + REPLACE_REALLOC=1 + fi +]) diff --git a/gl/realloc.m4 b/gl/realloc.m4 new file mode 100644 index 0000000..068b081 --- /dev/null +++ b/gl/realloc.m4 @@ -0,0 +1,79 @@ +/* realloc() function that is glibc compatible. + + Copyright (C) 1997, 2003-2004, 2006-2007, 2009-2015 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 + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +/* written by Jim Meyering and Bruno Haible */ + +#define _GL_USE_STDLIB_ALLOC 1 +#include <config.h> + +/* Only the AC_FUNC_REALLOC macro defines 'realloc' already in config.h. */ +#ifdef realloc +# define NEED_REALLOC_GNU 1 +/* Whereas the gnulib module 'realloc-gnu' defines HAVE_REALLOC_GNU. */ +#elif GNULIB_REALLOC_GNU && !HAVE_REALLOC_GNU +# define NEED_REALLOC_GNU 1 +#endif + +/* Infer the properties of the system's malloc function. + The gnulib module 'malloc-gnu' defines HAVE_MALLOC_GNU. */ +#if GNULIB_MALLOC_GNU && HAVE_MALLOC_GNU +# define SYSTEM_MALLOC_GLIBC_COMPATIBLE 1 +#endif + +#include <stdlib.h> + +#include <errno.h> + +/* Change the size of an allocated block of memory P to N bytes, + with error checking. If N is zero, change it to 1. If P is NULL, + use malloc. */ + +void * +rpl_realloc (void *p, size_t n) +{ + void *result; + +#if NEED_REALLOC_GNU + if (n == 0) + { + n = 1; + + /* In theory realloc might fail, so don't rely on it to free. */ + free (p); + p = NULL; + } +#endif + + if (p == NULL) + { +#if GNULIB_REALLOC_GNU && !NEED_REALLOC_GNU && !SYSTEM_MALLOC_GLIBC_COMPATIBLE + if (n == 0) + n = 1; +#endif + result = malloc (n); + } + else + result = realloc (p, n); + +#if !HAVE_REALLOC_POSIX + if (result == NULL) + errno = ENOMEM; +#endif + + return result; +} diff --git a/gltests/Makefile.am b/gltests/Makefile.am index 7c7c59f..6c72c14 100644 --- a/gltests/Makefile.am +++ b/gltests/Makefile.am @@ -282,6 +282,24 @@ EXTRA_DIST += test-getcwd-lgpl.c signature.h macros.h ## end gnulib module getcwd-lgpl-tests +## begin gnulib module getdelim-tests + +TESTS += test-getdelim +check_PROGRAMS += test-getdelim +MOSTLYCLEANFILES += test-getdelim.txt +EXTRA_DIST += test-getdelim.c signature.h macros.h + +## end gnulib module getdelim-tests + +## begin gnulib module getline-tests + +TESTS += test-getline +check_PROGRAMS += test-getline +MOSTLYCLEANFILES += test-getline.txt +EXTRA_DIST += test-getline.c signature.h macros.h + +## end gnulib module getline-tests + ## begin gnulib module getopt-posix-tests TESTS += test-getopt @@ -610,56 +628,6 @@ EXTRA_DIST += test-stddef.c ## end gnulib module stddef-tests -## begin gnulib module stdint - -BUILT_SOURCES += $(STDINT_H) - -# We need the following in order to create <stdint.h> when the system -# doesn't have one that works with the given compiler. -if GL_GENERATE_STDINT_H -stdint.h: stdint.in.h $(top_builddir)/config.status - $(AM_V_GEN)rm -f $@-t $@ && \ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - sed -e 's|@''GUARD_PREFIX''@|GL|g' \ - -e 's/@''HAVE_STDINT_H''@/$(HAVE_STDINT_H)/g' \ - -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ - -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ - -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ - -e 's|@''NEXT_STDINT_H''@|$(NEXT_STDINT_H)|g' \ - -e 's/@''HAVE_SYS_TYPES_H''@/$(HAVE_SYS_TYPES_H)/g' \ - -e 's/@''HAVE_INTTYPES_H''@/$(HAVE_INTTYPES_H)/g' \ - -e 's/@''HAVE_SYS_INTTYPES_H''@/$(HAVE_SYS_INTTYPES_H)/g' \ - -e 's/@''HAVE_SYS_BITYPES_H''@/$(HAVE_SYS_BITYPES_H)/g' \ - -e 's/@''HAVE_WCHAR_H''@/$(HAVE_WCHAR_H)/g' \ - -e 's/@''HAVE_LONG_LONG_INT''@/$(HAVE_LONG_LONG_INT)/g' \ - -e 's/@''HAVE_UNSIGNED_LONG_LONG_INT''@/$(HAVE_UNSIGNED_LONG_LONG_INT)/g' \ - -e 's/@''APPLE_UNIVERSAL_BUILD''@/$(APPLE_UNIVERSAL_BUILD)/g' \ - -e 's/@''BITSIZEOF_PTRDIFF_T''@/$(BITSIZEOF_PTRDIFF_T)/g' \ - -e 's/@''PTRDIFF_T_SUFFIX''@/$(PTRDIFF_T_SUFFIX)/g' \ - -e 's/@''BITSIZEOF_SIG_ATOMIC_T''@/$(BITSIZEOF_SIG_ATOMIC_T)/g' \ - -e 's/@''HAVE_SIGNED_SIG_ATOMIC_T''@/$(HAVE_SIGNED_SIG_ATOMIC_T)/g' \ - -e 's/@''SIG_ATOMIC_T_SUFFIX''@/$(SIG_ATOMIC_T_SUFFIX)/g' \ - -e 's/@''BITSIZEOF_SIZE_T''@/$(BITSIZEOF_SIZE_T)/g' \ - -e 's/@''SIZE_T_SUFFIX''@/$(SIZE_T_SUFFIX)/g' \ - -e 's/@''BITSIZEOF_WCHAR_T''@/$(BITSIZEOF_WCHAR_T)/g' \ - -e 's/@''HAVE_SIGNED_WCHAR_T''@/$(HAVE_SIGNED_WCHAR_T)/g' \ - -e 's/@''WCHAR_T_SUFFIX''@/$(WCHAR_T_SUFFIX)/g' \ - -e 's/@''BITSIZEOF_WINT_T''@/$(BITSIZEOF_WINT_T)/g' \ - -e 's/@''HAVE_SIGNED_WINT_T''@/$(HAVE_SIGNED_WINT_T)/g' \ - -e 's/@''WINT_T_SUFFIX''@/$(WINT_T_SUFFIX)/g' \ - < $(srcdir)/stdint.in.h; \ - } > $@-t && \ - mv $@-t $@ -else -stdint.h: $(top_builddir)/config.status - rm -f $@ -endif -MOSTLYCLEANFILES += stdint.h stdint.h-t - -EXTRA_DIST += stdint.in.h - -## end gnulib module stdint - ## begin gnulib module stdint-tests TESTS += test-stdint @@ -805,103 +773,6 @@ EXTRA_DIST += test-stdio.c ## end gnulib module stdio-tests -## begin gnulib module stdlib - -BUILT_SOURCES += stdlib.h - -# We need the following in order to create <stdlib.h> when the system -# doesn't have one that works with the given compiler. -stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \ - $(_NORETURN_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) - $(AM_V_GEN)rm -f $@-t $@ && \ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ - sed -e 's|@''GUARD_PREFIX''@|GL|g' \ - -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ - -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ - -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ - -e 's|@''NEXT_STDLIB_H''@|$(NEXT_STDLIB_H)|g' \ - -e 's/@''GNULIB__EXIT''@/$(GNULIB__EXIT)/g' \ - -e 's/@''GNULIB_ATOLL''@/$(GNULIB_ATOLL)/g' \ - -e 's/@''GNULIB_CALLOC_POSIX''@/$(GNULIB_CALLOC_POSIX)/g' \ - -e 's/@''GNULIB_CANONICALIZE_FILE_NAME''@/$(GNULIB_CANONICALIZE_FILE_NAME)/g' \ - -e 's/@''GNULIB_GETLOADAVG''@/$(GNULIB_GETLOADAVG)/g' \ - -e 's/@''GNULIB_GETSUBOPT''@/$(GNULIB_GETSUBOPT)/g' \ - -e 's/@''GNULIB_GRANTPT''@/$(GNULIB_GRANTPT)/g' \ - -e 's/@''GNULIB_MALLOC_POSIX''@/$(GNULIB_MALLOC_POSIX)/g' \ - -e 's/@''GNULIB_MBTOWC''@/$(GNULIB_MBTOWC)/g' \ - -e 's/@''GNULIB_MKDTEMP''@/$(GNULIB_MKDTEMP)/g' \ - -e 's/@''GNULIB_MKOSTEMP''@/$(GNULIB_MKOSTEMP)/g' \ - -e 's/@''GNULIB_MKOSTEMPS''@/$(GNULIB_MKOSTEMPS)/g' \ - -e 's/@''GNULIB_MKSTEMP''@/$(GNULIB_MKSTEMP)/g' \ - -e 's/@''GNULIB_MKSTEMPS''@/$(GNULIB_MKSTEMPS)/g' \ - -e 's/@''GNULIB_POSIX_OPENPT''@/$(GNULIB_POSIX_OPENPT)/g' \ - -e 's/@''GNULIB_PTSNAME''@/$(GNULIB_PTSNAME)/g' \ - -e 's/@''GNULIB_PTSNAME_R''@/$(GNULIB_PTSNAME_R)/g' \ - -e 's/@''GNULIB_PUTENV''@/$(GNULIB_PUTENV)/g' \ - -e 's/@''GNULIB_RANDOM_R''@/$(GNULIB_RANDOM_R)/g' \ - -e 's/@''GNULIB_REALLOC_POSIX''@/$(GNULIB_REALLOC_POSIX)/g' \ - -e 's/@''GNULIB_REALPATH''@/$(GNULIB_REALPATH)/g' \ - -e 's/@''GNULIB_RPMATCH''@/$(GNULIB_RPMATCH)/g' \ - -e 's/@''GNULIB_SETENV''@/$(GNULIB_SETENV)/g' \ - -e 's/@''GNULIB_STRTOD''@/$(GNULIB_STRTOD)/g' \ - -e 's/@''GNULIB_STRTOLL''@/$(GNULIB_STRTOLL)/g' \ - -e 's/@''GNULIB_STRTOULL''@/$(GNULIB_STRTOULL)/g' \ - -e 's/@''GNULIB_SYSTEM_POSIX''@/$(GNULIB_SYSTEM_POSIX)/g' \ - -e 's/@''GNULIB_UNLOCKPT''@/$(GNULIB_UNLOCKPT)/g' \ - -e 's/@''GNULIB_UNSETENV''@/$(GNULIB_UNSETENV)/g' \ - -e 's/@''GNULIB_WCTOMB''@/$(GNULIB_WCTOMB)/g' \ - < $(srcdir)/stdlib.in.h | \ - sed -e 's|@''HAVE__EXIT''@|$(HAVE__EXIT)|g' \ - -e 's|@''HAVE_ATOLL''@|$(HAVE_ATOLL)|g' \ - -e 's|@''HAVE_CANONICALIZE_FILE_NAME''@|$(HAVE_CANONICALIZE_FILE_NAME)|g' \ - -e 's|@''HAVE_DECL_GETLOADAVG''@|$(HAVE_DECL_GETLOADAVG)|g' \ - -e 's|@''HAVE_GETSUBOPT''@|$(HAVE_GETSUBOPT)|g' \ - -e 's|@''HAVE_GRANTPT''@|$(HAVE_GRANTPT)|g' \ - -e 's|@''HAVE_MKDTEMP''@|$(HAVE_MKDTEMP)|g' \ - -e 's|@''HAVE_MKOSTEMP''@|$(HAVE_MKOSTEMP)|g' \ - -e 's|@''HAVE_MKOSTEMPS''@|$(HAVE_MKOSTEMPS)|g' \ - -e 's|@''HAVE_MKSTEMP''@|$(HAVE_MKSTEMP)|g' \ - -e 's|@''HAVE_MKSTEMPS''@|$(HAVE_MKSTEMPS)|g' \ - -e 's|@''HAVE_POSIX_OPENPT''@|$(HAVE_POSIX_OPENPT)|g' \ - -e 's|@''HAVE_PTSNAME''@|$(HAVE_PTSNAME)|g' \ - -e 's|@''HAVE_PTSNAME_R''@|$(HAVE_PTSNAME_R)|g' \ - -e 's|@''HAVE_RANDOM_H''@|$(HAVE_RANDOM_H)|g' \ - -e 's|@''HAVE_RANDOM_R''@|$(HAVE_RANDOM_R)|g' \ - -e 's|@''HAVE_REALPATH''@|$(HAVE_REALPATH)|g' \ - -e 's|@''HAVE_RPMATCH''@|$(HAVE_RPMATCH)|g' \ - -e 's|@''HAVE_DECL_SETENV''@|$(HAVE_DECL_SETENV)|g' \ - -e 's|@''HAVE_STRTOD''@|$(HAVE_STRTOD)|g' \ - -e 's|@''HAVE_STRTOLL''@|$(HAVE_STRTOLL)|g' \ - -e 's|@''HAVE_STRTOULL''@|$(HAVE_STRTOULL)|g' \ - -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_UNLOCKPT''@|$(HAVE_UNLOCKPT)|g' \ - -e 's|@''HAVE_DECL_UNSETENV''@|$(HAVE_DECL_UNSETENV)|g' \ - -e 's|@''REPLACE_CALLOC''@|$(REPLACE_CALLOC)|g' \ - -e 's|@''REPLACE_CANONICALIZE_FILE_NAME''@|$(REPLACE_CANONICALIZE_FILE_NAME)|g' \ - -e 's|@''REPLACE_MALLOC''@|$(REPLACE_MALLOC)|g' \ - -e 's|@''REPLACE_MBTOWC''@|$(REPLACE_MBTOWC)|g' \ - -e 's|@''REPLACE_MKSTEMP''@|$(REPLACE_MKSTEMP)|g' \ - -e 's|@''REPLACE_PTSNAME_R''@|$(REPLACE_PTSNAME_R)|g' \ - -e 's|@''REPLACE_PUTENV''@|$(REPLACE_PUTENV)|g' \ - -e 's|@''REPLACE_REALLOC''@|$(REPLACE_REALLOC)|g' \ - -e 's|@''REPLACE_REALPATH''@|$(REPLACE_REALPATH)|g' \ - -e 's|@''REPLACE_SETENV''@|$(REPLACE_SETENV)|g' \ - -e 's|@''REPLACE_STRTOD''@|$(REPLACE_STRTOD)|g' \ - -e 's|@''REPLACE_UNSETENV''@|$(REPLACE_UNSETENV)|g' \ - -e 's|@''REPLACE_WCTOMB''@|$(REPLACE_WCTOMB)|g' \ - -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ - -e '/definition of _Noreturn/r $(_NORETURN_H)' \ - -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ - -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)'; \ - } > $@-t && \ - mv $@-t $@ -MOSTLYCLEANFILES += stdlib.h stdlib.h-t - -EXTRA_DIST += stdlib.in.h - -## end gnulib module stdlib - ## begin gnulib module strerror-tests TESTS += test-strerror diff --git a/gltests/test-getdelim.c b/gltests/test-getdelim.c new file mode 100644 index 0000000..bbcc3cd --- /dev/null +++ b/gltests/test-getdelim.c @@ -0,0 +1,94 @@ +/* Test of getdelim() function. + Copyright (C) 2007-2015 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 + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. */ + +/* Written by Eric Blake <ebb9@byu.net>, 2007. */ + +#include <config.h> + +#include <stdio.h> + +#include "signature.h" +SIGNATURE_CHECK (getdelim, ssize_t, (char **, size_t *, int, FILE *)); + +#include <stdlib.h> +#include <string.h> + +#include "macros.h" + +int +main (void) +{ + FILE *f; + char *line; + size_t len; + ssize_t result; + + /* Create test file. */ + f = fopen ("test-getdelim.txt", "wb"); + if (!f || fwrite ("anAnbcnd\0f", 1, 10, f) != 10 || fclose (f) != 0) + { + fputs ("Failed to create sample file.\n", stderr); + remove ("test-getdelim.txt"); + return 1; + } + f = fopen ("test-getdelim.txt", "rb"); + if (!f) + { + fputs ("Failed to reopen sample file.\n", stderr); + remove ("test-getdelim.txt"); + return 1; + } + + /* Test initial allocation, which must include trailing NUL. */ + line = NULL; + len = 0; + result = getdelim (&line, &len, 'n', f); + ASSERT (result == 2); + ASSERT (strcmp (line, "an") == 0); + ASSERT (2 < len); + free (line); + + /* Test initial allocation again, with line = NULL and len != 0. */ + line = NULL; + len = (size_t)(~0) / 4; + result = getdelim (&line, &len, 'n', f); + ASSERT (result == 2); + ASSERT (strcmp (line, "An") == 0); + ASSERT (2 < len); + free (line); + + /* Test growth of buffer. */ + line = malloc (1); + len = 1; + result = getdelim (&line, &len, 'n', f); + ASSERT (result == 3); + ASSERT (strcmp (line, "bcn") == 0); + ASSERT (3 < len); + + /* Test embedded NULs and EOF behavior. */ + result = getdelim (&line, &len, 'n', f); + ASSERT (result == 3); + ASSERT (memcmp (line, "d\0f", 4) == 0); + ASSERT (3 < len); + + result = getdelim (&line, &len, 'n', f); + ASSERT (result == -1); + + free (line); + fclose (f); + remove ("test-getdelim.txt"); + return 0; +} diff --git a/gltests/test-getline.c b/gltests/test-getline.c new file mode 100644 index 0000000..238742c --- /dev/null +++ b/gltests/test-getline.c @@ -0,0 +1,94 @@ +/* Test of getline() function. + Copyright (C) 2007-2015 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 + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. */ + +/* Written by Eric Blake <ebb9@byu.net>, 2007. */ + +#include <config.h> + +#include <stdio.h> + +#include "signature.h" +SIGNATURE_CHECK (getline, ssize_t, (char **, size_t *, FILE *)); + +#include <stdlib.h> +#include <string.h> + +#include "macros.h" + +int +main (void) +{ + FILE *f; + char *line; + size_t len; + ssize_t result; + + /* Create test file. */ + f = fopen ("test-getline.txt", "wb"); + if (!f || fwrite ("a\nA\nbc\nd\0f", 1, 10, f) != 10 || fclose (f) != 0) + { + fputs ("Failed to create sample file.\n", stderr); + remove ("test-getline.txt"); + return 1; + } + f = fopen ("test-getline.txt", "rb"); + if (!f) + { + fputs ("Failed to reopen sample file.\n", stderr); + remove ("test-getline.txt"); + return 1; + } + + /* Test initial allocation, which must include trailing NUL. */ + line = NULL; + len = 0; + result = getline (&line, &len, f); + ASSERT (result == 2); + ASSERT (strcmp (line, "a\n") == 0); + ASSERT (2 < len); + free (line); + + /* Test initial allocation again, with line = NULL and len != 0. */ + line = NULL; + len = (size_t)(~0) / 4; + result = getline (&line, &len, f); + ASSERT (result == 2); + ASSERT (strcmp (line, "A\n") == 0); + ASSERT (2 < len); + free (line); + + /* Test growth of buffer, must not leak. */ + line = malloc (1); + len = 0; + result = getline (&line, &len, f); + ASSERT (result == 3); + ASSERT (strcmp (line, "bc\n") == 0); + ASSERT (3 < len); + + /* Test embedded NULs and EOF behavior. */ + result = getline (&line, &len, f); + ASSERT (result == 3); + ASSERT (memcmp (line, "d\0f", 4) == 0); + ASSERT (3 < len); + + result = getline (&line, &len, f); + ASSERT (result == -1); + + free (line); + fclose (f); + remove ("test-getline.txt"); + return 0; +} @@ -129,7 +129,8 @@ int main (int argc, char *argv[]) { struct gengetopt_args_info args_info; - char readbuf[BUFSIZ]; + char *line = NULL; + size_t linelen = 0; char *p, *r; uint32_t *q; unsigned cmdn = 0; @@ -193,24 +194,20 @@ main (int argc, char *argv[]) do { if (cmdn < args_info.inputs_num) - { - strncpy (readbuf, args_info.inputs[cmdn++], BUFSIZ - 1); - readbuf[BUFSIZ - 1] = '\0'; - } - else if (fgets (readbuf, BUFSIZ, stdin) == NULL) - { + line = strdup (args_info.inputs[cmdn++]); + else if (getline (&line, &linelen, stdin) == -1) + { if (feof (stdin)) break; error (EXIT_FAILURE, errno, _("input error")); } - - if (readbuf[strlen (readbuf) - 1] == '\n') - readbuf[strlen (readbuf) - 1] = '\0'; + if (line[strlen (line) - 1] == '\n') + line[strlen (line) - 1] = '\0'; if (args_info.stringprep_given) { - p = stringprep_locale_to_utf8 (readbuf); + p = stringprep_locale_to_utf8 (line); if (!p) error (EXIT_FAILURE, 0, _("could not convert from %s to UTF-8"), stringprep_locale_charset ()); @@ -292,15 +289,15 @@ main (int argc, char *argv[]) } len2 = BUFSIZ - 1; - rc = punycode_encode (len, q, NULL, &len2, readbuf); + rc = punycode_encode (len, q, NULL, &len2, encbuf); free (q); if (rc != PUNYCODE_SUCCESS) error (EXIT_FAILURE, 0, _("punycode_encode: %s"), punycode_strerror (rc)); - readbuf[len2] = '\0'; + encbuf[len2] = '\0'; - p = stringprep_utf8_to_locale (readbuf); + p = stringprep_utf8_to_locale (encbuf); if (!p) error (EXIT_FAILURE, 0, _("could not convert from UTF-8 to %s"), stringprep_locale_charset ()); @@ -319,7 +316,7 @@ main (int argc, char *argv[]) if (!q) error (EXIT_FAILURE, ENOMEM, N_("malloc")); - rc = punycode_decode (strlen (readbuf), readbuf, &len, q, NULL); + rc = punycode_decode (strlen (line), readbuf, &len, q, NULL); if (rc != PUNYCODE_SUCCESS) { free (q); @@ -355,7 +352,7 @@ main (int argc, char *argv[]) if (args_info.idna_to_ascii_given) { - p = stringprep_locale_to_utf8 (readbuf); + p = stringprep_locale_to_utf8 (line); if (!p) error (EXIT_FAILURE, 0, _("could not convert from %s to UTF-8"), stringprep_locale_charset ()); @@ -432,7 +429,7 @@ main (int argc, char *argv[]) if (args_info.idna_to_unicode_given) { - p = stringprep_locale_to_utf8 (readbuf); + p = stringprep_locale_to_utf8 (line); if (!p) error (EXIT_FAILURE, 0, _("could not convert from %s to UTF-8"), stringprep_locale_charset ()); @@ -513,7 +510,7 @@ main (int argc, char *argv[]) if (args_info.nfkc_given) { - p = stringprep_locale_to_utf8 (readbuf); + p = stringprep_locale_to_utf8 (line); if (!p) error (EXIT_FAILURE, 0, _("could not convert from %s to UTF-8"), stringprep_locale_charset ()); @@ -575,5 +572,7 @@ main (int argc, char *argv[]) while (!feof (stdin) && !ferror (stdin) && (args_info.inputs_num == 0 || cmdn < args_info.inputs_num)); + free (line); + return EXIT_SUCCESS; } |