[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Wheezy update of libidn?



Hi,

I prepared an wheezy update for libidn, fixing CVE-2016-6263,
CVE-2016-6261 and CVE-2015-8948. I just applied the upstream's patches
and tested the upgrade of package in a clean wheezy chroot.

If someone could test/review my work I'll appreciate (debdiff is
attached). I am waiting some feedback.

Best regards.

-- 
Lucas Kanashiro
8ED6 C3F8 BAC9 DB7F C130  A870 F823 A272 9883 C97C

diff -Nru libidn-1.25/debian/changelog libidn-1.25/debian/changelog
--- libidn-1.25/debian/changelog	2016-05-15 20:36:27.000000000 -0300
+++ libidn-1.25/debian/changelog	2016-07-28 16:11:30.000000000 -0300
@@ -1,3 +1,17 @@
+libidn (1.25-2+deb7u2) wheezy-security; urgency=medium
+
+  * Non-maintainer upload by the LTS team.
+  * Fix CVE-2016-6263, stringprep_utf8_nfkc_normalize reject invalid UTF-8.
+    It was always documented to only accept UTF-8 data, but now it doesn't
+    crash when presented with such data. Reported by Hanno Böck.
+  * Fix CVE-2016-6261, fix out-of-bounds stack read in idna_to_ascii_4i.
+    See tests/tst_toascii64oob.c for regression check (and the comment in
+    it how to use it). Reported by Hanno Böck.
+  * Fix CVE-2015-8948, solve out-of-bounds-read when reading one zero byte as
+    input. Also replaced fgets with getline. Reported by Hanno Böck.
+
+ -- Lucas Kanashiro <kanashiro@debian.org>  Thu, 28 Jul 2016 16:11:26 -0300
+
 libidn (1.25-2+deb7u1) wheezy-security; urgency=high
 
   [ Alessandro Ghedini ]
diff -Nru libidn-1.25/debian/patches/01_CVE-2015-2059.patch libidn-1.25/debian/patches/01_CVE-2015-2059.patch
--- libidn-1.25/debian/patches/01_CVE-2015-2059.patch	2016-05-06 04:37:02.000000000 -0300
+++ libidn-1.25/debian/patches/01_CVE-2015-2059.patch	2016-07-28 12:07:18.000000000 -0300
@@ -519,8 +519,8 @@
  
  ctests = tst_stringprep tst_punycode tst_idna tst_idna2 tst_idna3	\
  	tst_idna4 tst_nfkc tst_pr29 tst_strerror tst_toutf8		\
--	tst_symbols
-+	tst_symbols tst_badutf8
+-	tst_symbols tst_badutf8nfkc
++	tst_symbols tst_badutf8nfkc tst_badutf8
  if TLD
  ctests += tst_tld
  endif
diff -Nru libidn-1.25/debian/patches/02_CVE-2015-2059-2.patch libidn-1.25/debian/patches/02_CVE-2015-2059-2.patch
--- libidn-1.25/debian/patches/02_CVE-2015-2059-2.patch	2016-05-06 04:37:02.000000000 -0300
+++ libidn-1.25/debian/patches/02_CVE-2015-2059-2.patch	2016-07-28 12:08:10.000000000 -0300
@@ -48,8 +48,8 @@
  
  ctests = tst_stringprep tst_punycode tst_idna tst_idna2 tst_idna3	\
  	tst_idna4 tst_nfkc tst_pr29 tst_strerror tst_toutf8		\
--	tst_symbols tst_badutf8
-+	tst_symbols tst_badutf8 tst_utf8crash
+-	tst_symbols tst_badutf8nfkc tst_badutf8
++	tst_symbols tst_badutf8nfkc tst_badutf8 tst_utf8crash
  if TLD
  ctests += tst_tld
  endif
diff -Nru libidn-1.25/debian/patches/CVE-2015-8948.patch libidn-1.25/debian/patches/CVE-2015-8948.patch
--- libidn-1.25/debian/patches/CVE-2015-8948.patch	1969-12-31 21:00:00.000000000 -0300
+++ libidn-1.25/debian/patches/CVE-2015-8948.patch	2016-07-28 16:08:32.000000000 -0300
@@ -0,0 +1,1415 @@
+Description: fix CVE-2015-8948
+ Use getline instead of fgets with fixed-size buffer. Fixes out-of-bounds read,
+ reported by Hanno Böck.
+Author: Lucas Kanashiro <kanashiro@debian.org>
+Last-Updated: 2016-07-28
+
+From 	570e68886c41c2e765e6218cb317d9a9a447a041 2016-01-14 13:59:19 (GMT)
+From: Simon Josefsson <simon@josefsson.org>
+Date: Thu, 14 Jan 2016 13:59:19 +0000
+Subject: idn: Use getline instead of fgets with fixed-size buffer. CVE-2015-8948
+
+--- 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=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 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/ge
+ 
+ ## 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,27 @@ libgnu_la_SOURCES += progname.h progname
+ 
+ ## 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
+@@ -337,6 +376,161 @@ EXTRA_DIST += stddef.in.h
+ 
+ ## end   gnulib module stddef
+ 
++## 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 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
+ 
+ 
+--- /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;
++}
+--- /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);
++}
+--- /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])
++])
+--- /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],
++[
++  :
++])
+--- 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=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 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
+   maintainer-makefile
+--- a/gl/m4/gnulib-comp.m4
++++ b/gl/m4/gnulib-comp.m4
+@@ -72,6 +72,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:
+@@ -106,6 +110,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:
+@@ -187,6 +192,18 @@ fi
+ m4_ifdef([AM_XGETTEXT_OPTION],
+   [AM_][XGETTEXT_OPTION([--flag=error:3:c-format])
+    AM_][XGETTEXT_OPTION([--flag=error_at_line:5:c-format])])
++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])
+@@ -228,12 +245,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])
+@@ -347,7 +372,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])
+@@ -372,11 +396,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])
+@@ -505,6 +527,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
+@@ -517,8 +541,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
+@@ -546,6 +573,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
+@@ -566,6 +595,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
+@@ -607,6 +637,8 @@ AC_DEFUN([gl_FILE_LIST], [
+   tests/test-fstat.c
+   tests/test-fwrite.c
+   tests/test-getcwd-lgpl.c
++  tests/test-getdelim.c
++  tests/test-getline.c
+   tests/test-getopt.c
+   tests/test-getopt.h
+   tests/test-getopt_long.h
+@@ -663,9 +695,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
+--- /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
++])
+--- /dev/null
++++ b/gl/realloc.c
+@@ -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;
++}
+--- a/gltests/Makefile.am
++++ b/gltests/Makefile.am
+@@ -291,6 +291,24 @@ EXTRA_DIST += test-getcwd-lgpl.c signatu
+ 
+ ## 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
+@@ -621,56 +639,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
+@@ -815,106 +783,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''@/$(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_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_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_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-tests
+ 
+ TESTS += test-strerror
+--- /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;
++}
+--- /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;
++}
+--- a/src/idn.c
++++ b/src/idn.c
+@@ -126,7 +126,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;
+@@ -191,10 +192,9 @@ main (int argc, char *argv[])
+     {
+       if (cmdn < args_info.inputs_num)
+ 	{
+-	  strncpy (readbuf, args_info.inputs[cmdn++], BUFSIZ - 1);
+-	  readbuf[BUFSIZ - 1] = '\0';
++    line = strdup (args_info.inputs[cmdn++]);
+ 	}
+-      else if (fgets (readbuf, BUFSIZ, stdin) == NULL)
++      else if (getline (&line, &linelen, stdin) == -1)
+ 	{
+ 	  if (feof (stdin))
+ 	    break;
+@@ -202,12 +202,13 @@ main (int argc, char *argv[])
+ 	  error (EXIT_FAILURE, errno, _("input error"));
+ 	}
+ 
+-      if (readbuf[strlen (readbuf) - 1] == '\n')
+-	readbuf[strlen (readbuf) - 1] = '\0';
++  if (strlen (line) > 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 ());
+@@ -267,9 +268,10 @@ main (int argc, char *argv[])
+ 
+       if (args_info.punycode_encode_given)
+ 	{
++    char encbuf[BUFSIZ];
+ 	  size_t len, len2;
+ 
+-	  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 ());
+@@ -289,15 +291,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 ());
+@@ -316,7 +318,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), line, &len, q, NULL);
+ 	  if (rc != PUNYCODE_SUCCESS)
+ 	    {
+ 	      free (q);
+@@ -352,7 +354,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 ());
+@@ -429,7 +431,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 ());
+@@ -510,7 +512,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 ());
+@@ -572,5 +574,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;
+ }
diff -Nru libidn-1.25/debian/patches/CVE-2016-6261.patch libidn-1.25/debian/patches/CVE-2016-6261.patch
--- libidn-1.25/debian/patches/CVE-2016-6261.patch	1969-12-31 21:00:00.000000000 -0300
+++ libidn-1.25/debian/patches/CVE-2016-6261.patch	2016-07-28 16:10:13.000000000 -0300
@@ -0,0 +1,108 @@
+Description: fix CVE-2016-6261
+ Fix out-of-bounds stack read in idna_to_ascii_4i. See tests/tst_toascii64oob.c
+ for regression check (and the comment in it how to use it).
+Author: Lucas Kanashiro <kanashiro@debian.org>
+Last-Updated: 2016-07-28
+
+From 	f20ce1128fb7f4d33297eee307dddaf0f92ac72d 2016-01-14 12:46:52 (GMT)
+From: Simon Josefsson <simon@josefsson.org>
+Date: Thu, 14 Jan 2016 12:46:52 +0000
+Subject: Fix out-of-bounds stack read. Add some regression tests. CVE-2016-6261
+
+--- a/lib/idna.c
++++ b/lib/idna.c
+@@ -209,6 +209,11 @@ step3:
+       }
+     if (i < 64)
+       out[i] = '\0';
++    else
++    {
++      free (src);
++      return IDNA_INVALID_LENGTH;
++    }
+     if (inasciirange)
+       goto step8;
+   }
+@@ -263,7 +268,7 @@ step3:
+ 
+ step8:
+   free (src);
+-  if (strlen (out) < 1 || strlen (out) > 63)
++  if (strlen (out) < 1)
+     return IDNA_INVALID_LENGTH;
+ 
+   return IDNA_SUCCESS;
+--- a/tests/Makefile.am
++++ b/tests/Makefile.am
+@@ -27,7 +27,8 @@ libutils_a_SOURCES = utils.h utils.c
+ 
+ ctests = tst_stringprep tst_punycode tst_idna tst_idna2 tst_idna3	\
+ 	tst_idna4 tst_nfkc tst_pr29 tst_strerror tst_toutf8		\
+-	tst_symbols tst_badutf8nfkc tst_badutf8 tst_utf8crash
++	tst_symbols tst_badutf8nfkc tst_badutf8 tst_utf8crash \
++ tst_toascii64oob
+ if TLD
+ ctests += tst_tld
+ endif
+--- /dev/null
++++ b/tests/tst_toascii64oob.c
+@@ -0,0 +1,59 @@
++/* tst_toascii64oob.c --- Regression tests for stack OOB in idna_to_ascii().
++ * Copyright (C) 2002-2016 Simon Josefsson
++ *
++ * This file is part of GNU Libidn.
++ *
++ * 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/>.
++ *
++ */
++
++#ifdef HAVE_CONFIG_H
++# include "config.h"
++#endif
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <stdarg.h>
++#include <string.h>
++
++#include <idna.h>
++#include <idn-free.h>
++
++#include "utils.h"
++
++/* Reported by Hanno Böck in
++   https://lists.gnu.org/archive/html/help-libidn/2015-07/msg00016.html */
++
++/* This test requires you to build with CFLAGS="-fsanitize=address"
++   and disable valgrind since asan and valgrind conflict.  Thus
++   normally a bit uneffective, but may be useful to have around. */
++
++void
++doit (void)
++{
++  const char *in = "00000000000000000000000000000000000000000000000000"
++    "00000000000000";
++  char *output;
++  uint32_t *tmp;
++  int rc;
++
++  tmp = stringprep_utf8_to_ucs4 (in, -1, NULL);
++  if (!tmp)
++    fail ("stringprep_utf8_to_ucs4 failed");
++
++  rc = idna_to_ascii_4z (tmp, &output, 0);
++  free (tmp);
++  if (rc != IDNA_INVALID_LENGTH)
++    fail ("idna_to_ascii_4z: %d", rc);
++}
diff -Nru libidn-1.25/debian/patches/CVE-2016-6263.patch libidn-1.25/debian/patches/CVE-2016-6263.patch
--- libidn-1.25/debian/patches/CVE-2016-6263.patch	1969-12-31 21:00:00.000000000 -0300
+++ libidn-1.25/debian/patches/CVE-2016-6263.patch	2016-07-28 16:11:21.000000000 -0300
@@ -0,0 +1,86 @@
+Description: fix CVE-2016-6263
+ stringprep_utf8_nfkc_normalize reject invalid UTF-8.  It was always documented
+ to only accept UTF-8 data, but now it doesn't crash when presented with such
+ data. Reported by Hanno Böck.
+Author: Lucas Kanashiro <kanashiro@debian.org>
+Last-Updated: 2016-07-28
+
+From 	1fbee57ef3c72db2206dd87e4162108b2f425555 2016-01-14 13:31:33 (GMT)
+From: Simon Josefsson <simon@josefsson.org>
+Date: Thu, 14 Jan 2016 13:31:33 +0000
+Subject: stringprep_utf8_nfkc_normalize: Reject invalid UTF8 instead of crashing. CVE-2016-6263
+
+--- a/lib/nfkc.c
++++ b/lib/nfkc.c
+@@ -1073,6 +1073,16 @@ stringprep_ucs4_to_utf8 (const uint32_t
+ char *
+ stringprep_utf8_nfkc_normalize (const char *str, ssize_t len)
+ {
++  size_t n;
++
++  if (len < 0)
++    n = strlen (str);
++  else
++    n = len;
++
++  if (u8_check ((const uint8_t *) str, n))
++    return NULL;
++
+   return g_utf8_normalize (str, len, G_NORMALIZE_NFKC);
+ }
+ 
+--- a/tests/Makefile.am
++++ b/tests/Makefile.am
+@@ -27,7 +27,7 @@ libutils_a_SOURCES = utils.h utils.c
+ 
+ ctests = tst_stringprep tst_punycode tst_idna tst_idna2 tst_idna3	\
+ 	tst_idna4 tst_nfkc tst_pr29 tst_strerror tst_toutf8		\
+-	tst_symbols
++	tst_symbols tst_badutf8nfkc
+ if TLD
+ ctests += tst_tld
+ endif
+--- /dev/null
++++ b/tests/tst_badutf8nfkc.c
+@@ -0,0 +1,41 @@
++/* tst_badutf8nfkc.c --- Self tests for malformed UTF-8 NFKC input.
++ * Copyright (C) 2016 Simon Josefsson
++ *
++ * This file is part of GNU Libidn.
++ *
++ * 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/>.
++ *
++ */
++
++#ifdef HAVE_CONFIG_H
++# include "config.h"
++#endif
++
++#include <string.h>
++#include <stdlib.h>
++
++#include <stringprep.h>
++
++#include "utils.h"
++
++void
++doit (void)
++{
++  char *badutf8 = strdup ("\xe4");
++  char *s = NULL;
++
++  s = stringprep_utf8_nfkc_normalize (badutf8, -1);
++  free (s);
++  free (badutf8);
++}
diff -Nru libidn-1.25/debian/patches/series libidn-1.25/debian/patches/series
--- libidn-1.25/debian/patches/series	2016-05-06 04:37:02.000000000 -0300
+++ libidn-1.25/debian/patches/series	2016-07-28 14:34:25.000000000 -0300
@@ -1,2 +1,5 @@
+CVE-2016-6263.patch
 01_CVE-2015-2059.patch
 02_CVE-2015-2059-2.patch
+CVE-2016-6261.patch
+CVE-2015-8948.patch

Attachment: signature.asc
Description: OpenPGP digital signature


Reply to: