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

Re: libidn test packages [resent]



Added CC Debian Libidn Team <help-libidn@gnu.org>

I now have fixed the packages libidn packages initially produced by
Alessandro Ghedini and destined for wheezy-security and jessie-security.
They now build fine.

In particular, for the Jessie version I had to edit the Makefile.am to
prevent it rebuilding the documentation which was failing to build after
applying security patches triggered a rebuild.

Versions for wheezy and jessie available here:
https://people.debian.org/~bam/debian/pool/main/libi/libidn/

Please test.

Also attached is the debdiff patches.
-- 
Brian May <bam@debian.org>
diff -Nru libidn-1.25/debian/changelog libidn-1.25/debian/changelog
--- libidn-1.25/debian/changelog	2012-05-30 22:41:06.000000000 +1000
+++ libidn-1.25/debian/changelog	2016-05-06 17:37:02.000000000 +1000
@@ -1,3 +1,9 @@
+libidn (1.25-2+deb7u1) wheezy-security; urgency=high
+
+  * Fix out-of-bounds read on invalid UTF-8 input as per CVE-2015-2059
+
+ -- Alessandro Ghedini <ghedo@debian.org>  Tue, 18 Aug 2015 10:21:50 +0200
+
 libidn (1.25-2) unstable; urgency=low
 
   * Fix copyright format.  Use https for upstream homepage.
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	1970-01-01 10:00:00.000000000 +1000
+++ libidn-1.25/debian/patches/01_CVE-2015-2059.patch	2016-05-06 17:37:02.000000000 +1000
@@ -0,0 +1,976 @@
+From 2e97c2796581c27213962c77f5a8571a598f9a2e Mon Sep 17 00:00:00 2001
+From: Simon Josefsson <simon@josefsson.org>
+Date: Wed, 08 Jul 2015 00:06:22 +0000
+Subject: libidn: stringprep_utf8_to_ucs4 now rejects invalid UTF-8. CVE-2015-2059
+
+---
+--- a/lib/gl/Makefile.am
++++ b/lib/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=lib/gl/override --lib=libgnu --source-base=lib/gl --m4-base=lib/gl/m4 --doc-base=doc --tests-base=lib/gltests --aux-dir=build-aux --with-tests --avoid=iconv-h-tests --avoid=string-tests --avoid=wchar-tests --lgpl=2 --no-conditional-dependencies --libtool --macro-prefix=lgl --no-vc-files gettext-h lib-msvc-compat lib-symbol-versions lib-symbol-visibility stdint striconv strverscmp
++# Reproduce by: gnulib-tool --import --dir=. --local-dir=lib/gl/override --lib=libgnu --source-base=lib/gl --m4-base=lib/gl/m4 --doc-base=doc --tests-base=lib/gltests --aux-dir=build-aux --with-tests --avoid=iconv-h-tests --avoid=string-tests --avoid=wchar-tests --lgpl=2 --no-conditional-dependencies --libtool --macro-prefix=lgl --no-vc-files gettext-h lib-msvc-compat lib-symbol-versions lib-symbol-visibility stdint striconv strverscmp unistr/u8-check
+ 
+ AUTOMAKE_OPTIONS = 1.5 gnits subdir-objects
+ 
+@@ -489,6 +489,14 @@
+ 
+ ## end   gnulib module unistr/base
+ 
++## begin gnulib module unistr/u8-check
++
++if LIBUNISTRING_COMPILE_UNISTR_U8_CHECK
++libgnu_la_SOURCES += unistr/u8-check.c
++endif
++
++## end   gnulib module unistr/u8-check
++
+ ## begin gnulib module unistr/u8-mbtoucr
+ 
+ if LIBUNISTRING_COMPILE_UNISTR_U8_MBTOUCR
+--- a/lib/gl/m4/gnulib-cache.m4
++++ b/lib/gl/m4/gnulib-cache.m4
+@@ -27,7 +27,7 @@
+ 
+ 
+ # Specification in the form of a command-line invocation:
+-#   gnulib-tool --import --dir=. --local-dir=lib/gl/override --lib=libgnu --source-base=lib/gl --m4-base=lib/gl/m4 --doc-base=doc --tests-base=lib/gltests --aux-dir=build-aux --with-tests --avoid=iconv-h-tests --avoid=string-tests --avoid=wchar-tests --lgpl=2 --no-conditional-dependencies --libtool --macro-prefix=lgl --no-vc-files gettext-h lib-msvc-compat lib-symbol-versions lib-symbol-visibility stdint striconv strverscmp
++#   gnulib-tool --import --dir=. --local-dir=lib/gl/override --lib=libgnu --source-base=lib/gl --m4-base=lib/gl/m4 --doc-base=doc --tests-base=lib/gltests --aux-dir=build-aux --with-tests --avoid=iconv-h-tests --avoid=string-tests --avoid=wchar-tests --lgpl=2 --no-conditional-dependencies --libtool --macro-prefix=lgl --no-vc-files gettext-h lib-msvc-compat lib-symbol-versions lib-symbol-visibility stdint striconv strverscmp unistr/u8-check
+ 
+ # Specification in the form of a few gnulib-tool.m4 macro invocations:
+ gl_LOCAL_DIR([lib/gl/override])
+@@ -39,6 +39,7 @@
+   stdint
+   striconv
+   strverscmp
++  unistr/u8-check
+ ])
+ gl_AVOID([iconv-h-tests string-tests wchar-tests])
+ gl_SOURCE_BASE([lib/gl])
+--- a/lib/gl/m4/gnulib-comp.m4
++++ b/lib/gl/m4/gnulib-comp.m4
+@@ -111,6 +111,8 @@
+   # Code from module unistd:
+   # Code from module unistd-tests:
+   # Code from module unistr/base:
++  # Code from module unistr/u8-check:
++  # Code from module unistr/u8-check-tests:
+   # Code from module unistr/u8-mbtoucr:
+   # Code from module unistr/u8-mbtoucr-tests:
+   # Code from module unistr/u8-uctomb:
+@@ -172,6 +174,7 @@
+ fi
+ gl_STRING_MODULE_INDICATOR([strverscmp])
+ gl_LIBUNISTRING_LIBHEADER([0.9.2], [unistr.h])
++gl_LIBUNISTRING_MODULE([0.9], [unistr/u8-check])
+ gl_MODULE_INDICATOR([unistr/u8-mbtoucr])
+ gl_LIBUNISTRING_MODULE([0.9], [unistr/u8-mbtoucr])
+ gl_MODULE_INDICATOR([unistr/u8-uctomb])
+@@ -399,6 +402,7 @@
+   lib/string.in.h
+   lib/strverscmp.c
+   lib/unistr.in.h
++  lib/unistr/u8-check.c
+   lib/unistr/u8-mbtoucr.c
+   lib/unistr/u8-uctomb-aux.c
+   lib/unistr/u8-uctomb.c
+@@ -493,6 +497,7 @@
+   tests/test-unsetenv.c
+   tests/test-verify.c
+   tests/test-verify.sh
++  tests/unistr/test-u8-check.c
+   tests/unistr/test-u8-mbtoucr.c
+   tests/unistr/test-u8-uctomb.c
+   tests=lib/alloca.in.h
+--- /dev/null
++++ b/lib/gl/unistr/u8-check.c
+@@ -0,0 +1,105 @@
++/* Check UTF-8 string.
++   Copyright (C) 2002, 2006-2007, 2009-2015 Free Software Foundation, Inc.
++   Written by Bruno Haible <bruno@clisp.org>, 2002.
++
++   This program is free software: you can redistribute it and/or modify it
++   under the terms of the GNU Lesser General Public License as published
++   by the Free Software Foundation; either version 2.1 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
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public License
++   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
++
++#include <config.h>
++
++/* Specification.  */
++#include "unistr.h"
++
++const uint8_t *
++u8_check (const uint8_t *s, size_t n)
++{
++  const uint8_t *s_end = s + n;
++
++  while (s < s_end)
++    {
++      /* Keep in sync with unistr.h and u8-mbtouc-aux.c.  */
++      uint8_t c = *s;
++
++      if (c < 0x80)
++        {
++          s++;
++          continue;
++        }
++      if (c >= 0xc2)
++        {
++          if (c < 0xe0)
++            {
++              if (s + 2 <= s_end
++                  && (s[1] ^ 0x80) < 0x40)
++                {
++                  s += 2;
++                  continue;
++                }
++            }
++          else if (c < 0xf0)
++            {
++              if (s + 3 <= s_end
++                  && (s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40
++                  && (c >= 0xe1 || s[1] >= 0xa0)
++                  && (c != 0xed || s[1] < 0xa0))
++                {
++                  s += 3;
++                  continue;
++                }
++            }
++          else if (c < 0xf8)
++            {
++              if (s + 4 <= s_end
++                  && (s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40
++                  && (s[3] ^ 0x80) < 0x40
++                  && (c >= 0xf1 || s[1] >= 0x90)
++#if 1
++                  && (c < 0xf4 || (c == 0xf4 && s[1] < 0x90))
++#endif
++                 )
++                {
++                  s += 4;
++                  continue;
++                }
++            }
++#if 0
++          else if (c < 0xfc)
++            {
++              if (s + 5 <= s_end
++                  && (s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40
++                  && (s[3] ^ 0x80) < 0x40 && (s[4] ^ 0x80) < 0x40
++                  && (c >= 0xf9 || s[1] >= 0x88))
++                {
++                  s += 5;
++                  continue;
++                }
++            }
++          else if (c < 0xfe)
++            {
++              if (s + 6 <= s_end
++                  && (s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40
++                  && (s[3] ^ 0x80) < 0x40 && (s[4] ^ 0x80) < 0x40
++                  && (s[5] ^ 0x80) < 0x40
++                  && (c >= 0xfd || s[1] >= 0x84))
++                {
++                  s += 6;
++                  continue;
++                }
++            }
++#endif
++        }
++      /* invalid or incomplete multibyte character */
++      return s;
++    }
++  return NULL;
++}
+--- a/lib/gltests/Makefile.am
++++ b/lib/gltests/Makefile.am
+@@ -823,6 +823,16 @@
+ 
+ ## end   gnulib module unistd-tests
+ 
++## begin gnulib module unistr/u8-check-tests
++
++TESTS += test-u8-check
++check_PROGRAMS += test-u8-check
++test_u8_check_SOURCES = unistr/test-u8-check.c
++test_u8_check_LDADD = $(LDADD) $(LIBUNISTRING)
++EXTRA_DIST += unistr/test-u8-check.c macros.h
++
++## end   gnulib module unistr/u8-check-tests
++
+ ## begin gnulib module unistr/u8-mbtoucr-tests
+ 
+ TESTS += test-u8-mbtoucr
+--- /dev/null
++++ b/lib/gltests/unistr/test-u8-check.c
+@@ -0,0 +1,188 @@
++/* Test of u8_check() function.
++   Copyright (C) 2010-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 Bruno Haible <bruno@clisp.org>, 2010.  */
++
++#include <config.h>
++
++#include "unistr.h"
++
++#include "macros.h"
++
++int
++main ()
++{
++  /* Test empty string.  */
++  {
++    static const uint8_t input[] = "";
++    ASSERT (u8_check (input, 0) == NULL);
++  }
++
++  /* Test valid non-empty string.  */
++  {
++    static const uint8_t input[] = /* "Данило Шеган" */
++      "\320\224\320\260\320\275\320\270\320\273\320\276 \320\250\320\265\320\263\320\260\320\275";
++    ASSERT (u8_check (input, sizeof (input) - 1) == NULL);
++  }
++
++  /* Test out-of-range character with 4 bytes: U+110000.  */
++  {
++    static const uint8_t input[] = "\320\224\320\260\364\220\200\200";
++    ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
++  }
++
++  /* Test out-of-range character with 5 bytes: U+200000.  */
++  {
++    static const uint8_t input[] = "\320\224\320\260\370\210\200\200\200";
++    ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
++  }
++
++  /* Test out-of-range character with 6 bytes: U+4000000.  */
++  {
++    static const uint8_t input[] = "\320\224\320\260\374\204\200\200\200\200";
++    ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
++  }
++
++  /* Test invalid lead byte.  */
++  {
++    static const uint8_t input[] = "\320\224\320\260\376\200\200\200\200\200";
++    ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
++  }
++  {
++    static const uint8_t input[] = "\320\224\320\260\377\200\200\200\200\200";
++    ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
++  }
++
++  /* Test overlong 2-byte character.  */
++  {
++    static const uint8_t input[] = "\320\224\320\260\301\200";
++    ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
++  }
++
++  /* Test overlong 3-byte character.  */
++  {
++    static const uint8_t input[] = "\320\224\320\260\340\200\277";
++    ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
++  }
++
++  /* Test overlong 4-byte character.  */
++  {
++    static const uint8_t input[] = "\320\224\320\260\360\200\277\277";
++    ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
++  }
++
++  /* Test invalid bytes in 2-byte character.  */
++  {
++    static const uint8_t input[] = "\320\224\320\260\302\200";
++    ASSERT (u8_check (input, sizeof (input) - 1) == NULL);
++  }
++  {
++    static const uint8_t input[] = "\320\224\320\260\302\100";
++    ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
++  }
++  {
++    static const uint8_t input[] = "\320\224\320\260\302\300";
++    ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
++  }
++
++  /* Test invalid bytes in 3-byte character.  */
++  {
++    static const uint8_t input[] = "\320\224\320\260\342\200\200";
++    ASSERT (u8_check (input, sizeof (input) - 1) == NULL);
++  }
++  {
++    static const uint8_t input[] = "\320\224\320\260\342\100\200";
++    ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
++  }
++  {
++    static const uint8_t input[] = "\320\224\320\260\342\300\200";
++    ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
++  }
++  {
++    static const uint8_t input[] = "\320\224\320\260\342\200\100";
++    ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
++  }
++  {
++    static const uint8_t input[] = "\320\224\320\260\342\200\300";
++    ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
++  }
++
++  /* Test invalid bytes in 4-byte character.  */
++  {
++    static const uint8_t input[] = "\320\224\320\260\362\200\200\200";
++    ASSERT (u8_check (input, sizeof (input) - 1) == NULL);
++  }
++  {
++    static const uint8_t input[] = "\320\224\320\260\362\100\200\200";
++    ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
++  }
++  {
++    static const uint8_t input[] = "\320\224\320\260\362\300\200\200";
++    ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
++  }
++  {
++    static const uint8_t input[] = "\320\224\320\260\362\200\100\200";
++    ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
++  }
++  {
++    static const uint8_t input[] = "\320\224\320\260\362\200\300\200";
++    ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
++  }
++  {
++    static const uint8_t input[] = "\320\224\320\260\362\200\200\100";
++    ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
++  }
++  {
++    static const uint8_t input[] = "\320\224\320\260\362\200\200\300";
++    ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
++  }
++
++  /* Test truncated/incomplete 2-byte character.  */
++  {
++    static const uint8_t input[] = "\320\224\320\260\302";
++    ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
++  }
++
++  /* Test truncated/incomplete 3-byte character.  */
++  {
++    static const uint8_t input[] = "\320\224\320\260\342\200";
++    ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
++  }
++
++  /* Test truncated/incomplete 4-byte character.  */
++  {
++    static const uint8_t input[] = "\320\224\320\260\362\200\200";
++    ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
++  }
++
++  /* Test missing lead byte.  */
++  {
++    static const uint8_t input[] = "\320\224\320\260\200\200\200\200\200";
++    ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
++  }
++
++  /* Test surrogate codepoints.  */
++  {
++    static const uint8_t input[] = "\320\224\320\260\355\240\200\355\260\200";
++    ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
++  }
++  {
++    static const uint8_t input[] = "\320\224\320\260\355\260\200";
++    ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
++  }
++
++  return 0;
++}
+--- a/lib/nfkc.c
++++ b/lib/nfkc.c
+@@ -1002,6 +1002,8 @@
+   return g_unichar_to_utf8 (c, outbuf);
+ }
+ 
++#include <unistr.h>
++
+ /**
+  * stringprep_utf8_to_ucs4:
+  * @str: a UTF-8 encoded string
+@@ -1010,9 +1012,10 @@
+  * @items_written: location to store the number of characters in the
+  *                 result, or %NULL.
+  *
+- * Convert a string from UTF-8 to a 32-bit fixed width
+- * representation as UCS-4, assuming valid UTF-8 input.
+- * This function does no error checking on the input.
++ * Convert a string from UTF-8 to a 32-bit fixed width representation
++ * as UCS-4.  The function now performs error checking to verify that
++ * the input is valid UTF-8 (before it was documented to not do error
++ * checking).
+  *
+  * Return value: a pointer to a newly allocated UCS-4 string.
+  *               This value must be deallocated by the caller.
+@@ -1020,6 +1023,16 @@
+ uint32_t *
+ stringprep_utf8_to_ucs4 (const char *str, ssize_t len, size_t * items_written)
+ {
++  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_to_ucs4_fast (str, (glong) len, (glong *) items_written);
+ }
+ 
+--- a/lib/strerror-idna.c
++++ b/lib/strerror-idna.c
+@@ -115,7 +115,7 @@
+       break;
+ 
+     case IDNA_ICONV_ERROR:
+-      p = _("System iconv failed");
++      p = _("Could not convert string in locale encoding");
+       break;
+ 
+     case IDNA_MALLOC_ERROR:
+--- a/lib/strerror-stringprep.c
++++ b/lib/strerror-stringprep.c
+@@ -65,6 +65,7 @@
+  *   This usually indicate a problem in the calling application.
+  * STRINGPREP_UNKNOWN_PROFILE: The supplied profile name was not
+  *   known to the library.
++ * STRINGPREP_ICONV_ERROR: Could not convert string in locale encoding.
+  * STRINGPREP_NFKC_FAILED: The Unicode NFKC operation failed.  This
+  *   usually indicate an internal error in the library.
+  * STRINGPREP_MALLOC_ERROR: The malloc() was out of memory.  This is
+@@ -121,6 +122,9 @@
+     case STRINGPREP_UNKNOWN_PROFILE:
+       p = _("Unknown profile");
+       break;
++    case STRINGPREP_ICONV_ERROR:
++      p = _("Could not convert string in locale encoding.");
++      break;
+ 
+     case STRINGPREP_NFKC_FAILED:
+       p = _("Unicode normalization failed (internal error)");
+--- a/lib/stringprep.c
++++ b/lib/stringprep.c
+@@ -380,6 +380,8 @@
+ 
+       free (ucs4);
+       ucs4 = stringprep_utf8_to_ucs4 (in, -1, &ucs4len);
++      if (ucs4 == NULL)
++	return STRINGPREP_ICONV_ERROR;
+       maxucs4len = ucs4len + adducs4len;
+       newp = realloc (ucs4, maxucs4len * sizeof (uint32_t));
+       if (!newp)
+@@ -402,7 +404,7 @@
+   utf8 = stringprep_ucs4_to_utf8 (ucs4, ucs4len, 0, 0);
+   free (ucs4);
+   if (!utf8)
+-    return STRINGPREP_MALLOC_ERROR;
++    return STRINGPREP_ICONV_ERROR;
+ 
+   if (strlen (utf8) >= maxlen)
+     {
+@@ -590,6 +592,7 @@
+  *   This usually indicate a problem in the calling application.
+  * @STRINGPREP_UNKNOWN_PROFILE: The supplied profile name was not
+  *   known to the library.
++ * @STRINGPREP_ICONV_ERROR: Could not convert string in locale encoding.
+  * @STRINGPREP_NFKC_FAILED: The Unicode NFKC operation failed.  This
+  *   usually indicate an internal error in the library.
+  * @STRINGPREP_MALLOC_ERROR: The malloc() was out of memory.  This is
+--- a/lib/stringprep.h
++++ b/lib/stringprep.h
+@@ -68,6 +68,7 @@
+     STRINGPREP_PROFILE_ERROR = 101,
+     STRINGPREP_FLAG_ERROR = 102,
+     STRINGPREP_UNKNOWN_PROFILE = 103,
++    STRINGPREP_ICONV_ERROR = 104,
+     /* Internal errors. */
+     STRINGPREP_NFKC_FAILED = 200,
+     STRINGPREP_MALLOC_ERROR = 201
+--- a/tests/Makefile.am
++++ b/tests/Makefile.am
+@@ -27,7 +27,7 @@
+ 
+ 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
+ if TLD
+ ctests += tst_tld
+ endif
+--- /dev/null
++++ b/tests/tst_badutf8.c
+@@ -0,0 +1,50 @@
++/* tst_badutf8.c --- Self tests for malformed UTF-8 regressions.
++ * Copyright (C) 2015 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"
++
++void
++doit (void)
++{
++  char *badutf8 = strdup ("\x7e\x64\x61\x72\x10\x2f\x2f\xf9\x2b\x71"
++			  "\x60\x79\x7b\x2e\x63\x75\x2b\x61\x65\x72"
++			  "\x75\x65\x56\x66\x7f\x62\xc5\x76\xe5\x00");
++  char *s = NULL;
++  int rc;
++
++  rc = idna_to_ascii_8z (badutf8, &s, 0);
++  free (badutf8);
++  if (rc != IDNA_ICONV_ERROR)
++    fail ("rc %d\n", rc);
++
++  idn_free (s);
++}
+--- a/tests/tst_stringprep.c
++++ b/tests/tst_stringprep.c
+@@ -100,7 +100,8 @@
+    "\xF4\x8F\xBF\xBF", NULL, "Nameprep", 0,
+    STRINGPREP_CONTAINS_PROHIBITED},
+   {"Surrogate code U+DF42",
+-   "\xED\xBD\x82", NULL, "Nameprep", 0, STRINGPREP_CONTAINS_PROHIBITED},
++   "\xED\xBD\x82", NULL, "Nameprep", 0, STRINGPREP_ICONV_ERROR
++   /* was STRINGPREP_CONTAINS_PROHIBITED */},
+   {"Non-plain text character U+FFFD",
+    "\xEF\xBF\xBD", NULL, "Nameprep", 0, STRINGPREP_CONTAINS_PROHIBITED},
+   {"Ideographic description character U+2FF5",
+@@ -229,15 +230,22 @@
+ 	  hexprint (strprep[i].in, strlen (strprep[i].in));
+ 	  binprint (strprep[i].in, strlen (strprep[i].in));
+ 	}
+-
+       {
+ 	uint32_t *l;
+-	char *x;
++	char *x = NULL;
+ 	l = stringprep_utf8_to_ucs4 (strprep[i].in, -1, NULL);
+-	x = stringprep_ucs4_to_utf8 (l, -1, NULL, NULL);
++	if (l)
++	  x = stringprep_ucs4_to_utf8 (l, -1, NULL, NULL);
+ 	free (l);
+-
+-	if (strcmp (strprep[i].in, x) != 0)
++	if (i == 29)
++	  /* Ignoring known bad UTF-8 in entry 29 */
++	  continue;
++	else if (l == NULL)
++	  {
++	    fail ("bad UTF-8 in entry %ld\n", i);
++	    continue;
++	  }
++	else if (strcmp (strprep[i].in, x) != 0)
+ 	  {
+ 	    fail ("bad UTF-8 in entry %ld\n", i);
+ 	    if (debug)
+@@ -249,10 +257,12 @@
+ 		escapeprint (x, strlen (x));
+ 		hexprint (x, strlen (x));
+ 	      }
++	    continue;
+ 	  }
+ 
+ 	free (x);
+       }
++
+       rc = stringprep_profile (strprep[i].in, &p,
+ 			       strprep[i].profile ?
+ 			       strprep[i].profile :
+--- a/configure
++++ b/configure
+@@ -704,6 +704,8 @@
+ LIBUNISTRING_COMPILE_UNISTR_U8_UCTOMB_TRUE
+ LIBUNISTRING_COMPILE_UNISTR_U8_MBTOUCR_FALSE
+ LIBUNISTRING_COMPILE_UNISTR_U8_MBTOUCR_TRUE
++LIBUNISTRING_COMPILE_UNISTR_U8_CHECK_FALSE
++LIBUNISTRING_COMPILE_UNISTR_U8_CHECK_TRUE
+ LIBUNISTRING_UNISTR_H
+ HAVE_VISIBILITY
+ CFLAG_VISIBILITY
+@@ -6541,6 +6543,8 @@
+   # Code from module unistd:
+   # Code from module unistd-tests:
+   # Code from module unistr/base:
++  # Code from module unistr/u8-check:
++  # Code from module unistr/u8-check-tests:
+   # Code from module unistr/u8-mbtoucr:
+   # Code from module unistr/u8-mbtoucr-tests:
+   # Code from module unistr/u8-uctomb:
+@@ -26366,6 +26369,35 @@
+ 
+ 
+ 
++       if  { test "$HAVE_LIBUNISTRING" != yes \
++    || {
++
++
++
++            test $LIBUNISTRING_VERSION_MAJOR -lt 0 \
++            || { test $LIBUNISTRING_VERSION_MAJOR -eq 0 \
++                 && { test $LIBUNISTRING_VERSION_MINOR -lt 9 \
++                      || { test $LIBUNISTRING_VERSION_MINOR -eq 9 \
++                           && test $LIBUNISTRING_VERSION_SUBMINOR -lt 0
++                         }
++                    }
++               }
++
++
++
++
++       }
++  }; then
++  LIBUNISTRING_COMPILE_UNISTR_U8_CHECK_TRUE=
++  LIBUNISTRING_COMPILE_UNISTR_U8_CHECK_FALSE='#'
++else
++  LIBUNISTRING_COMPILE_UNISTR_U8_CHECK_TRUE='#'
++  LIBUNISTRING_COMPILE_UNISTR_U8_CHECK_FALSE=
++fi
++
++
++
++
+ cat >>confdefs.h <<_ACEOF
+ #define GNULIB_UNISTR_U8_MBTOUCR 1
+ _ACEOF
+@@ -32886,6 +32918,10 @@
+   as_fn_error $? "conditional \"GL_GENERATE_STDDEF_H\" was never defined.
+ Usually this means the macro was only invoked conditionally." "$LINENO" 5
+ fi
++if test -z "${LIBUNISTRING_COMPILE_UNISTR_U8_CHECK_TRUE}" && test -z "${LIBUNISTRING_COMPILE_UNISTR_U8_CHECK_FALSE}"; then
++  as_fn_error $? "conditional \"LIBUNISTRING_COMPILE_UNISTR_U8_CHECK\" was never defined.
++Usually this means the macro was only invoked conditionally." "$LINENO" 5
++fi
+ if test -z "${LIBUNISTRING_COMPILE_UNISTR_U8_MBTOUCR_TRUE}" && test -z "${LIBUNISTRING_COMPILE_UNISTR_U8_MBTOUCR_FALSE}"; then
+   as_fn_error $? "conditional \"LIBUNISTRING_COMPILE_UNISTR_U8_MBTOUCR\" was never defined.
+ Usually this means the macro was only invoked conditionally." "$LINENO" 5
+--- a/lib/gl/Makefile.in
++++ b/lib/gl/Makefile.in
+@@ -36,7 +36,7 @@
+ # the same distribution terms as the rest of that program.
+ #
+ # Generated by gnulib-tool.
+-# Reproduce by: gnulib-tool --import --dir=. --local-dir=lib/gl/override --lib=libgnu --source-base=lib/gl --m4-base=lib/gl/m4 --doc-base=doc --tests-base=lib/gltests --aux-dir=build-aux --with-tests --avoid=iconv-h-tests --avoid=string-tests --avoid=wchar-tests --lgpl=2 --no-conditional-dependencies --libtool --macro-prefix=lgl --no-vc-files gettext-h lib-msvc-compat lib-symbol-versions lib-symbol-visibility stdint striconv strverscmp
++# Reproduce by: gnulib-tool --import --dir=. --local-dir=lib/gl/override --lib=libgnu --source-base=lib/gl --m4-base=lib/gl/m4 --doc-base=doc --tests-base=lib/gltests --aux-dir=build-aux --with-tests --avoid=iconv-h-tests --avoid=string-tests --avoid=wchar-tests --lgpl=2 --no-conditional-dependencies --libtool --macro-prefix=lgl --no-vc-files gettext-h lib-msvc-compat lib-symbol-versions lib-symbol-visibility stdint striconv strverscmp unistr/u8-check
+ 
+ 
+ 
+@@ -60,8 +60,9 @@
+ build_triplet = @build@
+ host_triplet = @host@
+ @GL_COND_LIBTOOL_TRUE@am__append_1 = $(LTLIBICONV)
+-@LIBUNISTRING_COMPILE_UNISTR_U8_MBTOUCR_TRUE@am__append_2 = unistr/u8-mbtoucr.c
+-@LIBUNISTRING_COMPILE_UNISTR_U8_UCTOMB_TRUE@am__append_3 = unistr/u8-uctomb.c unistr/u8-uctomb-aux.c
++@LIBUNISTRING_COMPILE_UNISTR_U8_CHECK_TRUE@am__append_2 = unistr/u8-check.c
++@LIBUNISTRING_COMPILE_UNISTR_U8_MBTOUCR_TRUE@am__append_3 = unistr/u8-mbtoucr.c
++@LIBUNISTRING_COMPILE_UNISTR_U8_UCTOMB_TRUE@am__append_4 = unistr/u8-uctomb.c unistr/u8-uctomb-aux.c
+ subdir = lib/gl
+ DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
+ 	$(srcdir)/Makefile.in
+@@ -149,13 +150,16 @@
+ am__DEPENDENCIES_1 =
+ am__libgnu_la_SOURCES_DIST = c-ctype.h c-ctype.c c-strcase.h \
+ 	c-strcasecmp.c c-strncasecmp.c gettext.h striconv.h striconv.c \
+-	unistr/u8-mbtoucr.c unistr/u8-uctomb.c unistr/u8-uctomb-aux.c
++	unistr/u8-check.c unistr/u8-mbtoucr.c unistr/u8-uctomb.c \
++	unistr/u8-uctomb-aux.c
+ am__dirstamp = $(am__leading_dot)dirstamp
+-@LIBUNISTRING_COMPILE_UNISTR_U8_MBTOUCR_TRUE@am__objects_1 = unistr/u8-mbtoucr.lo
+-@LIBUNISTRING_COMPILE_UNISTR_U8_UCTOMB_TRUE@am__objects_2 = unistr/u8-uctomb.lo \
++@LIBUNISTRING_COMPILE_UNISTR_U8_CHECK_TRUE@am__objects_1 =  \
++@LIBUNISTRING_COMPILE_UNISTR_U8_CHECK_TRUE@	unistr/u8-check.lo
++@LIBUNISTRING_COMPILE_UNISTR_U8_MBTOUCR_TRUE@am__objects_2 = unistr/u8-mbtoucr.lo
++@LIBUNISTRING_COMPILE_UNISTR_U8_UCTOMB_TRUE@am__objects_3 = unistr/u8-uctomb.lo \
+ @LIBUNISTRING_COMPILE_UNISTR_U8_UCTOMB_TRUE@	unistr/u8-uctomb-aux.lo
+ am_libgnu_la_OBJECTS = c-ctype.lo c-strcasecmp.lo c-strncasecmp.lo \
+-	striconv.lo $(am__objects_1) $(am__objects_2)
++	striconv.lo $(am__objects_1) $(am__objects_2) $(am__objects_3)
+ libgnu_la_OBJECTS = $(am_libgnu_la_OBJECTS)
+ AM_V_lt = $(am__v_lt_@AM_V@)
+ am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+@@ -1131,7 +1135,7 @@
+ AM_CFLAGS = $(CFLAG_VISIBILITY)
+ libgnu_la_SOURCES = c-ctype.h c-ctype.c c-strcase.h c-strcasecmp.c \
+ 	c-strncasecmp.c gettext.h striconv.h striconv.c \
+-	$(am__append_2) $(am__append_3)
++	$(am__append_2) $(am__append_3) $(am__append_4)
+ libgnu_la_LIBADD = $(lgl_LTLIBOBJS)
+ libgnu_la_DEPENDENCIES = $(lgl_LTLIBOBJS)
+ EXTRA_libgnu_la_SOURCES = iconv.c iconv_close.c iconv_open.c \
+@@ -1196,6 +1200,8 @@
+ unistr/$(DEPDIR)/$(am__dirstamp):
+ 	@$(MKDIR_P) unistr/$(DEPDIR)
+ 	@: > unistr/$(DEPDIR)/$(am__dirstamp)
++unistr/u8-check.lo: unistr/$(am__dirstamp) \
++	unistr/$(DEPDIR)/$(am__dirstamp)
+ unistr/u8-mbtoucr.lo: unistr/$(am__dirstamp) \
+ 	unistr/$(DEPDIR)/$(am__dirstamp)
+ unistr/u8-uctomb.lo: unistr/$(am__dirstamp) \
+@@ -1207,6 +1213,8 @@
+ 
+ mostlyclean-compile:
+ 	-rm -f *.$(OBJEXT)
++	-rm -f unistr/u8-check.$(OBJEXT)
++	-rm -f unistr/u8-check.lo
+ 	-rm -f unistr/u8-mbtoucr.$(OBJEXT)
+ 	-rm -f unistr/u8-mbtoucr.lo
+ 	-rm -f unistr/u8-uctomb-aux.$(OBJEXT)
+@@ -1225,6 +1233,7 @@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iconv_open.Plo@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/striconv.Plo@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strverscmp.Plo@am__quote@
++@AMDEP_TRUE@@am__include@ @am__quote@unistr/$(DEPDIR)/u8-check.Plo@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@unistr/$(DEPDIR)/u8-mbtoucr.Plo@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@unistr/$(DEPDIR)/u8-uctomb-aux.Plo@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@unistr/$(DEPDIR)/u8-uctomb.Plo@am__quote@
+--- a/lib/gltests/Makefile.in
++++ b/lib/gltests/Makefile.in
+@@ -68,8 +68,9 @@
+ 	test-striconv$(EXEEXT) test-strverscmp$(EXEEXT) \
+ 	test-sys_types$(EXEEXT) test-init.sh test-thread_self$(EXEEXT) \
+ 	test-thread_create$(EXEEXT) test-unistd$(EXEEXT) \
+-	test-u8-mbtoucr$(EXEEXT) test-u8-uctomb$(EXEEXT) \
+-	test-unsetenv$(EXEEXT) test-verify$(EXEEXT) test-verify.sh
++	test-u8-check$(EXEEXT) test-u8-mbtoucr$(EXEEXT) \
++	test-u8-uctomb$(EXEEXT) test-unsetenv$(EXEEXT) \
++	test-verify$(EXEEXT) test-verify.sh
+ XFAIL_TESTS =
+ noinst_PROGRAMS =
+ check_PROGRAMS = test-alloca-opt$(EXEEXT) test-c-ctype$(EXEEXT) \
+@@ -84,8 +85,9 @@
+ 	test-striconv$(EXEEXT) test-strverscmp$(EXEEXT) \
+ 	test-sys_types$(EXEEXT) test-thread_self$(EXEEXT) \
+ 	test-thread_create$(EXEEXT) test-unistd$(EXEEXT) \
+-	test-u8-mbtoucr$(EXEEXT) test-u8-uctomb$(EXEEXT) \
+-	test-unsetenv$(EXEEXT) test-verify$(EXEEXT)
++	test-u8-check$(EXEEXT) test-u8-mbtoucr$(EXEEXT) \
++	test-u8-uctomb$(EXEEXT) test-unsetenv$(EXEEXT) \
++	test-verify$(EXEEXT)
+ subdir = lib/gltests
+ DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
+ 	$(srcdir)/Makefile.in
+@@ -297,6 +299,9 @@
+ test_thread_self_SOURCES = test-thread_self.c
+ test_thread_self_OBJECTS = test-thread_self.$(OBJEXT)
+ test_thread_self_DEPENDENCIES = $(am__DEPENDENCIES_2)
++am_test_u8_check_OBJECTS = unistr/test-u8-check.$(OBJEXT)
++test_u8_check_OBJECTS = $(am_test_u8_check_OBJECTS)
++test_u8_check_DEPENDENCIES = $(am__DEPENDENCIES_2)
+ am_test_u8_mbtoucr_OBJECTS = unistr/test-u8-mbtoucr.$(OBJEXT)
+ test_u8_mbtoucr_OBJECTS = $(am_test_u8_mbtoucr_OBJECTS)
+ test_u8_mbtoucr_DEPENDENCIES = $(am__DEPENDENCIES_2)
+@@ -349,9 +354,9 @@
+ 	test-setlocale1.c test-setlocale2.c test-stdbool.c \
+ 	test-stddef.c test-stdint.c test-stdlib.c test-striconv.c \
+ 	test-strverscmp.c test-sys_types.c test-thread_create.c \
+-	test-thread_self.c $(test_u8_mbtoucr_SOURCES) \
+-	$(test_u8_uctomb_SOURCES) test-unistd.c test-unsetenv.c \
+-	test-verify.c
++	test-thread_self.c $(test_u8_check_SOURCES) \
++	$(test_u8_mbtoucr_SOURCES) $(test_u8_uctomb_SOURCES) \
++	test-unistd.c test-unsetenv.c test-verify.c
+ DIST_SOURCES = $(libtests_a_SOURCES) $(EXTRA_libtests_a_SOURCES) \
+ 	test-alloca-opt.c test-c-ctype.c test-c-strcasecmp.c \
+ 	test-c-strncasecmp.c test-environ.c test-iconv.c \
+@@ -360,9 +365,9 @@
+ 	test-setlocale1.c test-setlocale2.c test-stdbool.c \
+ 	test-stddef.c test-stdint.c test-stdlib.c test-striconv.c \
+ 	test-strverscmp.c test-sys_types.c test-thread_create.c \
+-	test-thread_self.c $(test_u8_mbtoucr_SOURCES) \
+-	$(test_u8_uctomb_SOURCES) test-unistd.c test-unsetenv.c \
+-	test-verify.c
++	test-thread_self.c $(test_u8_check_SOURCES) \
++	$(test_u8_mbtoucr_SOURCES) $(test_u8_uctomb_SOURCES) \
++	test-unistd.c test-unsetenv.c test-verify.c
+ RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+ 	html-recursive info-recursive install-data-recursive \
+ 	install-dvi-recursive install-exec-recursive \
+@@ -1275,9 +1280,10 @@
+ 	signature.h macros.h sys_types.in.h test-sys_types.c init.sh \
+ 	test-init.sh test-thread_self.c test-thread_create.c macros.h \
+ 	$(top_srcdir)/build-aux/config.rpath unistd.in.h test-unistd.c \
+-	unistr/test-u8-mbtoucr.c macros.h unistr/test-u8-uctomb.c \
+-	macros.h unsetenv.c test-unsetenv.c signature.h macros.h \
+-	verify.h test-verify.c test-verify.sh wchar.in.h
++	unistr/test-u8-check.c macros.h unistr/test-u8-mbtoucr.c \
++	macros.h unistr/test-u8-uctomb.c macros.h unsetenv.c \
++	test-unsetenv.c signature.h macros.h verify.h test-verify.c \
++	test-verify.sh wchar.in.h
+ 
+ # The BUILT_SOURCES created by this Makefile snippet are not used via #include
+ # statements but through direct file reference. Therefore this snippet must be
+@@ -1336,6 +1342,8 @@
+ test_striconv_LDADD = $(LDADD) @LIBICONV@
+ test_thread_self_LDADD = $(LDADD) @LIBTHREAD@
+ test_thread_create_LDADD = $(LDADD) @LIBMULTITHREAD@
++test_u8_check_SOURCES = unistr/test-u8-check.c
++test_u8_check_LDADD = $(LDADD) $(LIBUNISTRING)
+ test_u8_mbtoucr_SOURCES = unistr/test-u8-mbtoucr.c
+ test_u8_mbtoucr_LDADD = $(LDADD) $(LIBUNISTRING)
+ test_u8_uctomb_SOURCES = unistr/test-u8-uctomb.c
+@@ -1493,6 +1501,11 @@
+ unistr/$(DEPDIR)/$(am__dirstamp):
+ 	@$(MKDIR_P) unistr/$(DEPDIR)
+ 	@: > unistr/$(DEPDIR)/$(am__dirstamp)
++unistr/test-u8-check.$(OBJEXT): unistr/$(am__dirstamp) \
++	unistr/$(DEPDIR)/$(am__dirstamp)
++test-u8-check$(EXEEXT): $(test_u8_check_OBJECTS) $(test_u8_check_DEPENDENCIES) $(EXTRA_test_u8_check_DEPENDENCIES) 
++	@rm -f test-u8-check$(EXEEXT)
++	$(AM_V_CCLD)$(LINK) $(test_u8_check_OBJECTS) $(test_u8_check_LDADD) $(LIBS)
+ unistr/test-u8-mbtoucr.$(OBJEXT): unistr/$(am__dirstamp) \
+ 	unistr/$(DEPDIR)/$(am__dirstamp)
+ test-u8-mbtoucr$(EXEEXT): $(test_u8_mbtoucr_OBJECTS) $(test_u8_mbtoucr_DEPENDENCIES) $(EXTRA_test_u8_mbtoucr_DEPENDENCIES) 
+@@ -1518,6 +1531,7 @@
+ 	-rm -f glthread/lock.$(OBJEXT)
+ 	-rm -f glthread/thread.$(OBJEXT)
+ 	-rm -f glthread/threadlib.$(OBJEXT)
++	-rm -f unistr/test-u8-check.$(OBJEXT)
+ 	-rm -f unistr/test-u8-mbtoucr.$(OBJEXT)
+ 	-rm -f unistr/test-u8-uctomb.$(OBJEXT)
+ 
+@@ -1561,6 +1575,7 @@
+ @AMDEP_TRUE@@am__include@ @am__quote@glthread/$(DEPDIR)/lock.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@glthread/$(DEPDIR)/thread.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@glthread/$(DEPDIR)/threadlib.Po@am__quote@
++@AMDEP_TRUE@@am__include@ @am__quote@unistr/$(DEPDIR)/test-u8-check.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@unistr/$(DEPDIR)/test-u8-mbtoucr.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@unistr/$(DEPDIR)/test-u8-uctomb.Po@am__quote@
+ 
+--- a/tests/Makefile.in
++++ b/tests/Makefile.in
+@@ -149,14 +149,18 @@
+ 	tst_idna$(EXEEXT) tst_idna2$(EXEEXT) tst_idna3$(EXEEXT) \
+ 	tst_idna4$(EXEEXT) tst_nfkc$(EXEEXT) tst_pr29$(EXEEXT) \
+ 	tst_strerror$(EXEEXT) tst_toutf8$(EXEEXT) tst_symbols$(EXEEXT) \
+-	$(am__EXEEXT_1)
++	tst_badutf8$(EXEEXT) $(am__EXEEXT_1)
++tst_badutf8_SOURCES = tst_badutf8.c
++tst_badutf8_OBJECTS = tst_badutf8.$(OBJEXT)
++tst_badutf8_LDADD = $(LDADD)
++tst_badutf8_DEPENDENCIES = libutils.a ../lib/libidn.la
++AM_V_lt = $(am__v_lt_@AM_V@)
++am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
++am__v_lt_0 = --silent
+ tst_idna_SOURCES = tst_idna.c
+ tst_idna_OBJECTS = tst_idna.$(OBJEXT)
+ tst_idna_LDADD = $(LDADD)
+ tst_idna_DEPENDENCIES = libutils.a ../lib/libidn.la
+-AM_V_lt = $(am__v_lt_@AM_V@)
+-am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+-am__v_lt_0 = --silent
+ tst_idna2_SOURCES = tst_idna2.c
+ tst_idna2_OBJECTS = tst_idna2.$(OBJEXT)
+ tst_idna2_LDADD = $(LDADD)
+@@ -224,14 +228,14 @@
+ AM_V_GEN = $(am__v_GEN_@AM_V@)
+ am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+ am__v_GEN_0 = @echo "  GEN   " $@;
+-SOURCES = $(libutils_a_SOURCES) tst_idna.c tst_idna2.c tst_idna3.c \
+-	tst_idna4.c tst_nfkc.c tst_pr29.c tst_punycode.c \
+-	tst_strerror.c tst_stringprep.c tst_symbols.c tst_tld.c \
+-	tst_toutf8.c
+-DIST_SOURCES = $(libutils_a_SOURCES) tst_idna.c tst_idna2.c \
++SOURCES = $(libutils_a_SOURCES) tst_badutf8.c tst_idna.c tst_idna2.c \
+ 	tst_idna3.c tst_idna4.c tst_nfkc.c tst_pr29.c tst_punycode.c \
+ 	tst_strerror.c tst_stringprep.c tst_symbols.c tst_tld.c \
+ 	tst_toutf8.c
++DIST_SOURCES = $(libutils_a_SOURCES) tst_badutf8.c tst_idna.c \
++	tst_idna2.c tst_idna3.c tst_idna4.c tst_nfkc.c tst_pr29.c \
++	tst_punycode.c tst_strerror.c tst_stringprep.c tst_symbols.c \
++	tst_tld.c tst_toutf8.c
+ ETAGS = etags
+ CTAGS = ctags
+ am__tty_colors = \
+@@ -1083,7 +1087,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 $(am__append_1)
++	tst_symbols tst_badutf8 $(am__append_1)
+ EXTRA_DIST = libidn.supp
+ TESTS_ENVIRONMENT = $(VALGRIND)
+ all: all-am
+@@ -1136,6 +1140,9 @@
+ 	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ 	echo " rm -f" $$list; \
+ 	rm -f $$list
++tst_badutf8$(EXEEXT): $(tst_badutf8_OBJECTS) $(tst_badutf8_DEPENDENCIES) $(EXTRA_tst_badutf8_DEPENDENCIES) 
++	@rm -f tst_badutf8$(EXEEXT)
++	$(AM_V_CCLD)$(LINK) $(tst_badutf8_OBJECTS) $(tst_badutf8_LDADD) $(LIBS)
+ tst_idna$(EXEEXT): $(tst_idna_OBJECTS) $(tst_idna_DEPENDENCIES) $(EXTRA_tst_idna_DEPENDENCIES) 
+ 	@rm -f tst_idna$(EXEEXT)
+ 	$(AM_V_CCLD)$(LINK) $(tst_idna_OBJECTS) $(tst_idna_LDADD) $(LIBS)
+@@ -1179,6 +1186,7 @@
+ distclean-compile:
+ 	-rm -f *.tab.c
+ 
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst_badutf8.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst_idna.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst_idna2.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst_idna3.Po@am__quote@
+--- a/tests/tst_idna4.c
++++ b/tests/tst_idna4.c
+@@ -46,7 +46,9 @@
+   if (rc != IDNA_INVALID_LENGTH)
+     fail ("unexpected rc %d\n", rc);
+ 
+-  rc = idna_to_ascii_8z("Loading...°°°°°°°°°°°°°°]", &out, 0);
++  rc = idna_to_ascii_8z("Loading...\xC2\xB0\xC2\xB0\xC2\xB0\xC2\xB0\xC2\xB0"
++			"\xC2\xB0\xC2\xB0\xC2\xB0\xC2\xB0\xC2\xB0\xC2\xB0"
++			"\xC2\xB0\xC2\xB0\xC2\xB0]", &out, 0);
+   if (rc != IDNA_INVALID_LENGTH)
+     fail ("unexpected rc %d\n", rc);
+ }
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	1970-01-01 10:00:00.000000000 +1000
+++ libidn-1.25/debian/patches/02_CVE-2015-2059-2.patch	2016-05-06 17:37:02.000000000 +1000
@@ -0,0 +1,169 @@
+From 58c721ac2dc96bccd737f3f544f3a22a50477bbf Mon Sep 17 00:00:00 2001
+From: Simon Josefsson <simon@josefsson.org>
+Date: Sat, 01 Aug 2015 13:12:10 +0000
+Subject: libidn: Fix crash in idna_to_unicode_8z8z and idna_to_unicode_8zlz.
+
+---
+--- a/lib/idna.c
++++ b/lib/idna.c
+@@ -743,13 +743,16 @@
+   int rc;
+ 
+   rc = idna_to_unicode_8z4z (input, &ucs4, flags);
++  if (rc != IDNA_SUCCESS)
++    return rc;
++
+   *output = stringprep_ucs4_to_utf8 (ucs4, -1, NULL, NULL);
+   free (ucs4);
+ 
+   if (!*output)
+     return IDNA_ICONV_ERROR;
+ 
+-  return rc;
++  return IDNA_SUCCESS;
+ }
+ 
+ /**
+@@ -774,13 +777,16 @@
+   int rc;
+ 
+   rc = idna_to_unicode_8z8z (input, &utf8, flags);
++  if (rc != IDNA_SUCCESS)
++    return rc;
++
+   *output = stringprep_utf8_to_locale (utf8);
+   free (utf8);
+ 
+   if (!*output)
+     return IDNA_ICONV_ERROR;
+ 
+-  return rc;
++  return IDNA_SUCCESS;
+ }
+ 
+ /**
+--- a/tests/Makefile.am
++++ b/tests/Makefile.am
+@@ -27,7 +27,7 @@
+ 
+ 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
+ if TLD
+ ctests += tst_tld
+ endif
+--- /dev/null
++++ b/tests/tst_utf8crash.c
+@@ -0,0 +1,48 @@
++/* tst_utf8crash.c --- Self tests for malformed UTF-8 regressions.
++ * Copyright (C) 2015 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"
++
++/* Based on report from Adam Sampson:
++   https://lists.gnu.org/archive/html/help-libidn/2015-07/msg00026.html */
++
++void
++doit (void)
++{
++  const char input[] = "\200bad.com";
++  char *output;
++  int rc;
++
++  rc = idna_to_unicode_8z8z(input, &output, 0);
++  if (rc != IDNA_ICONV_ERROR)
++    fail ("rc %d\n", rc);
++}
+--- a/tests/Makefile.in
++++ b/tests/Makefile.in
+@@ -149,7 +149,7 @@
+ 	tst_idna$(EXEEXT) tst_idna2$(EXEEXT) tst_idna3$(EXEEXT) \
+ 	tst_idna4$(EXEEXT) tst_nfkc$(EXEEXT) tst_pr29$(EXEEXT) \
+ 	tst_strerror$(EXEEXT) tst_toutf8$(EXEEXT) tst_symbols$(EXEEXT) \
+-	tst_badutf8$(EXEEXT) $(am__EXEEXT_1)
++	tst_badutf8$(EXEEXT) tst_utf8crash$(EXEEXT) $(am__EXEEXT_1)
+ tst_badutf8_SOURCES = tst_badutf8.c
+ tst_badutf8_OBJECTS = tst_badutf8.$(OBJEXT)
+ tst_badutf8_LDADD = $(LDADD)
+@@ -205,6 +205,10 @@
+ tst_toutf8_OBJECTS = tst_toutf8.$(OBJEXT)
+ tst_toutf8_LDADD = $(LDADD)
+ tst_toutf8_DEPENDENCIES = libutils.a ../lib/libidn.la
++tst_utf8crash_SOURCES = tst_utf8crash.c
++tst_utf8crash_OBJECTS = tst_utf8crash.$(OBJEXT)
++tst_utf8crash_LDADD = $(LDADD)
++tst_utf8crash_DEPENDENCIES = libutils.a ../lib/libidn.la
+ DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+ depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+ am__depfiles_maybe = depfiles
+@@ -231,11 +235,11 @@
+ SOURCES = $(libutils_a_SOURCES) tst_badutf8.c tst_idna.c tst_idna2.c \
+ 	tst_idna3.c tst_idna4.c tst_nfkc.c tst_pr29.c tst_punycode.c \
+ 	tst_strerror.c tst_stringprep.c tst_symbols.c tst_tld.c \
+-	tst_toutf8.c
++	tst_toutf8.c tst_utf8crash.c
+ DIST_SOURCES = $(libutils_a_SOURCES) tst_badutf8.c tst_idna.c \
+ 	tst_idna2.c tst_idna3.c tst_idna4.c tst_nfkc.c tst_pr29.c \
+ 	tst_punycode.c tst_strerror.c tst_stringprep.c tst_symbols.c \
+-	tst_tld.c tst_toutf8.c
++	tst_tld.c tst_toutf8.c tst_utf8crash.c
+ ETAGS = etags
+ CTAGS = ctags
+ am__tty_colors = \
+@@ -1087,7 +1091,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_badutf8 $(am__append_1)
++	tst_symbols tst_badutf8 tst_utf8crash $(am__append_1)
+ EXTRA_DIST = libidn.supp
+ TESTS_ENVIRONMENT = $(VALGRIND)
+ all: all-am
+@@ -1179,6 +1183,9 @@
+ tst_toutf8$(EXEEXT): $(tst_toutf8_OBJECTS) $(tst_toutf8_DEPENDENCIES) $(EXTRA_tst_toutf8_DEPENDENCIES) 
+ 	@rm -f tst_toutf8$(EXEEXT)
+ 	$(AM_V_CCLD)$(LINK) $(tst_toutf8_OBJECTS) $(tst_toutf8_LDADD) $(LIBS)
++tst_utf8crash$(EXEEXT): $(tst_utf8crash_OBJECTS) $(tst_utf8crash_DEPENDENCIES) $(EXTRA_tst_utf8crash_DEPENDENCIES) 
++	@rm -f tst_utf8crash$(EXEEXT)
++	$(AM_V_CCLD)$(LINK) $(tst_utf8crash_OBJECTS) $(tst_utf8crash_LDADD) $(LIBS)
+ 
+ mostlyclean-compile:
+ 	-rm -f *.$(OBJEXT)
+@@ -1199,6 +1206,7 @@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst_symbols.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst_tld.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst_toutf8.Po@am__quote@
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst_utf8crash.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utils.Po@am__quote@
+ 
+ .c.o:
diff -Nru libidn-1.25/debian/patches/series libidn-1.25/debian/patches/series
--- libidn-1.25/debian/patches/series	1970-01-01 10:00:00.000000000 +1000
+++ libidn-1.25/debian/patches/series	2016-05-06 17:37:02.000000000 +1000
@@ -0,0 +1,2 @@
+01_CVE-2015-2059.patch
+02_CVE-2015-2059-2.patch
diff -Nru libidn-1.29/debian/changelog libidn-1.29/debian/changelog
--- libidn-1.29/debian/changelog	2014-08-17 08:47:43.000000000 +1000
+++ libidn-1.29/debian/changelog	2016-05-06 17:40:36.000000000 +1000
@@ -1,3 +1,9 @@
+libidn (1.29-1+deb8u1) jessie-security; urgency=high
+
+  * Fix out-of-bounds read on invalid UTF-8 input as per CVE-2015-2059
+
+ -- Alessandro Ghedini <ghedo@debian.org>  Tue, 18 Aug 2015 10:10:07 +0200
+
 libidn (1.29-1) unstable; urgency=low
 
   [ Simon Josefsson ]
diff -Nru libidn-1.29/debian/patches/01_CVE-2015-2059.patch libidn-1.29/debian/patches/01_CVE-2015-2059.patch
--- libidn-1.29/debian/patches/01_CVE-2015-2059.patch	1970-01-01 10:00:00.000000000 +1000
+++ libidn-1.29/debian/patches/01_CVE-2015-2059.patch	2016-05-06 17:40:36.000000000 +1000
@@ -0,0 +1,645 @@
+From 2e97c2796581c27213962c77f5a8571a598f9a2e Mon Sep 17 00:00:00 2001
+From: Simon Josefsson <simon@josefsson.org>
+Date: Wed, 08 Jul 2015 00:06:22 +0000
+Subject: libidn: stringprep_utf8_to_ucs4 now rejects invalid UTF-8. CVE-2015-2059
+
+---
+--- a/lib/gl/Makefile.am
++++ b/lib/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=lib/gl/override --lib=libgnu --source-base=lib/gl --m4-base=lib/gl/m4 --doc-base=doc --tests-base=lib/gltests --aux-dir=build-aux --with-tests --avoid=iconv-h-tests --avoid=string-tests --avoid=wchar-tests --lgpl=2 --no-conditional-dependencies --libtool --macro-prefix=lgl --no-vc-files gettext-h lib-msvc-compat lib-symbol-versions lib-symbol-visibility stdint striconv strverscmp
++# Reproduce by: gnulib-tool --import --dir=. --local-dir=lib/gl/override --lib=libgnu --source-base=lib/gl --m4-base=lib/gl/m4 --doc-base=doc --tests-base=lib/gltests --aux-dir=build-aux --with-tests --avoid=iconv-h-tests --avoid=string-tests --avoid=wchar-tests --lgpl=2 --no-conditional-dependencies --libtool --macro-prefix=lgl --no-vc-files gettext-h lib-msvc-compat lib-symbol-versions lib-symbol-visibility stdint striconv strverscmp unistr/u8-check
+ 
+ AUTOMAKE_OPTIONS = 1.9.6 gnits subdir-objects
+ 
+@@ -523,6 +523,14 @@
+ 
+ ## end   gnulib module unistr/base
+ 
++## begin gnulib module unistr/u8-check
++
++if LIBUNISTRING_COMPILE_UNISTR_U8_CHECK
++libgnu_la_SOURCES += unistr/u8-check.c
++endif
++
++## end   gnulib module unistr/u8-check
++
+ ## begin gnulib module unistr/u8-mbtoucr
+ 
+ if LIBUNISTRING_COMPILE_UNISTR_U8_MBTOUCR
+--- a/lib/gl/m4/gnulib-cache.m4
++++ b/lib/gl/m4/gnulib-cache.m4
+@@ -27,7 +27,7 @@
+ 
+ 
+ # Specification in the form of a command-line invocation:
+-#   gnulib-tool --import --dir=. --local-dir=lib/gl/override --lib=libgnu --source-base=lib/gl --m4-base=lib/gl/m4 --doc-base=doc --tests-base=lib/gltests --aux-dir=build-aux --with-tests --avoid=iconv-h-tests --avoid=string-tests --avoid=wchar-tests --lgpl=2 --no-conditional-dependencies --libtool --macro-prefix=lgl --no-vc-files gettext-h lib-msvc-compat lib-symbol-versions lib-symbol-visibility stdint striconv strverscmp
++#   gnulib-tool --import --dir=. --local-dir=lib/gl/override --lib=libgnu --source-base=lib/gl --m4-base=lib/gl/m4 --doc-base=doc --tests-base=lib/gltests --aux-dir=build-aux --with-tests --avoid=iconv-h-tests --avoid=string-tests --avoid=wchar-tests --lgpl=2 --no-conditional-dependencies --libtool --macro-prefix=lgl --no-vc-files gettext-h lib-msvc-compat lib-symbol-versions lib-symbol-visibility stdint striconv strverscmp unistr/u8-check
+ 
+ # Specification in the form of a few gnulib-tool.m4 macro invocations:
+ gl_LOCAL_DIR([lib/gl/override])
+@@ -39,6 +39,7 @@
+   stdint
+   striconv
+   strverscmp
++  unistr/u8-check
+ ])
+ gl_AVOID([iconv-h-tests string-tests wchar-tests])
+ gl_SOURCE_BASE([lib/gl])
+--- a/lib/gl/m4/gnulib-comp.m4
++++ b/lib/gl/m4/gnulib-comp.m4
+@@ -113,6 +113,8 @@
+   # Code from module unistd:
+   # Code from module unistd-tests:
+   # Code from module unistr/base:
++  # Code from module unistr/u8-check:
++  # Code from module unistr/u8-check-tests:
+   # Code from module unistr/u8-mbtoucr:
+   # Code from module unistr/u8-mbtoucr-tests:
+   # Code from module unistr/u8-uctomb:
+@@ -178,6 +180,7 @@
+   gl_SYS_TYPES_H
+   AC_PROG_MKDIR_P
+   gl_LIBUNISTRING_LIBHEADER([0.9.2], [unistr.h])
++  gl_LIBUNISTRING_MODULE([0.9], [unistr/u8-check])
+   gl_MODULE_INDICATOR([unistr/u8-mbtoucr])
+   gl_LIBUNISTRING_MODULE([0.9], [unistr/u8-mbtoucr])
+   gl_MODULE_INDICATOR([unistr/u8-uctomb])
+@@ -405,6 +408,7 @@
+   lib/strverscmp.c
+   lib/sys_types.in.h
+   lib/unistr.in.h
++  lib/unistr/u8-check.c
+   lib/unistr/u8-mbtoucr.c
+   lib/unistr/u8-uctomb-aux.c
+   lib/unistr/u8-uctomb.c
+@@ -501,6 +505,7 @@
+   tests/test-unsetenv.c
+   tests/test-verify.c
+   tests/test-verify.sh
++  tests/unistr/test-u8-check.c
+   tests/unistr/test-u8-mbtoucr.c
+   tests/unistr/test-u8-uctomb.c
+   tests=lib/alloca.in.h
+--- /dev/null
++++ b/lib/gl/unistr/u8-check.c
+@@ -0,0 +1,105 @@
++/* Check UTF-8 string.
++   Copyright (C) 2002, 2006-2007, 2009-2015 Free Software Foundation, Inc.
++   Written by Bruno Haible <bruno@clisp.org>, 2002.
++
++   This program is free software: you can redistribute it and/or modify it
++   under the terms of the GNU Lesser General Public License as published
++   by the Free Software Foundation; either version 2.1 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
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public License
++   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
++
++#include <config.h>
++
++/* Specification.  */
++#include "unistr.h"
++
++const uint8_t *
++u8_check (const uint8_t *s, size_t n)
++{
++  const uint8_t *s_end = s + n;
++
++  while (s < s_end)
++    {
++      /* Keep in sync with unistr.h and u8-mbtouc-aux.c.  */
++      uint8_t c = *s;
++
++      if (c < 0x80)
++        {
++          s++;
++          continue;
++        }
++      if (c >= 0xc2)
++        {
++          if (c < 0xe0)
++            {
++              if (s + 2 <= s_end
++                  && (s[1] ^ 0x80) < 0x40)
++                {
++                  s += 2;
++                  continue;
++                }
++            }
++          else if (c < 0xf0)
++            {
++              if (s + 3 <= s_end
++                  && (s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40
++                  && (c >= 0xe1 || s[1] >= 0xa0)
++                  && (c != 0xed || s[1] < 0xa0))
++                {
++                  s += 3;
++                  continue;
++                }
++            }
++          else if (c < 0xf8)
++            {
++              if (s + 4 <= s_end
++                  && (s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40
++                  && (s[3] ^ 0x80) < 0x40
++                  && (c >= 0xf1 || s[1] >= 0x90)
++#if 1
++                  && (c < 0xf4 || (c == 0xf4 && s[1] < 0x90))
++#endif
++                 )
++                {
++                  s += 4;
++                  continue;
++                }
++            }
++#if 0
++          else if (c < 0xfc)
++            {
++              if (s + 5 <= s_end
++                  && (s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40
++                  && (s[3] ^ 0x80) < 0x40 && (s[4] ^ 0x80) < 0x40
++                  && (c >= 0xf9 || s[1] >= 0x88))
++                {
++                  s += 5;
++                  continue;
++                }
++            }
++          else if (c < 0xfe)
++            {
++              if (s + 6 <= s_end
++                  && (s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40
++                  && (s[3] ^ 0x80) < 0x40 && (s[4] ^ 0x80) < 0x40
++                  && (s[5] ^ 0x80) < 0x40
++                  && (c >= 0xfd || s[1] >= 0x84))
++                {
++                  s += 6;
++                  continue;
++                }
++            }
++#endif
++        }
++      /* invalid or incomplete multibyte character */
++      return s;
++    }
++  return NULL;
++}
+--- a/lib/gltests/Makefile.am
++++ b/lib/gltests/Makefile.am
+@@ -804,6 +804,16 @@
+ 
+ ## end   gnulib module unistd-tests
+ 
++## begin gnulib module unistr/u8-check-tests
++
++TESTS += test-u8-check
++check_PROGRAMS += test-u8-check
++test_u8_check_SOURCES = unistr/test-u8-check.c
++test_u8_check_LDADD = $(LDADD) $(LIBUNISTRING)
++EXTRA_DIST += unistr/test-u8-check.c macros.h
++
++## end   gnulib module unistr/u8-check-tests
++
+ ## begin gnulib module unistr/u8-mbtoucr-tests
+ 
+ TESTS += test-u8-mbtoucr
+--- /dev/null
++++ b/lib/gltests/unistr/test-u8-check.c
+@@ -0,0 +1,188 @@
++/* Test of u8_check() function.
++   Copyright (C) 2010-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 Bruno Haible <bruno@clisp.org>, 2010.  */
++
++#include <config.h>
++
++#include "unistr.h"
++
++#include "macros.h"
++
++int
++main ()
++{
++  /* Test empty string.  */
++  {
++    static const uint8_t input[] = "";
++    ASSERT (u8_check (input, 0) == NULL);
++  }
++
++  /* Test valid non-empty string.  */
++  {
++    static const uint8_t input[] = /* "Данило Шеган" */
++      "\320\224\320\260\320\275\320\270\320\273\320\276 \320\250\320\265\320\263\320\260\320\275";
++    ASSERT (u8_check (input, sizeof (input) - 1) == NULL);
++  }
++
++  /* Test out-of-range character with 4 bytes: U+110000.  */
++  {
++    static const uint8_t input[] = "\320\224\320\260\364\220\200\200";
++    ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
++  }
++
++  /* Test out-of-range character with 5 bytes: U+200000.  */
++  {
++    static const uint8_t input[] = "\320\224\320\260\370\210\200\200\200";
++    ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
++  }
++
++  /* Test out-of-range character with 6 bytes: U+4000000.  */
++  {
++    static const uint8_t input[] = "\320\224\320\260\374\204\200\200\200\200";
++    ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
++  }
++
++  /* Test invalid lead byte.  */
++  {
++    static const uint8_t input[] = "\320\224\320\260\376\200\200\200\200\200";
++    ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
++  }
++  {
++    static const uint8_t input[] = "\320\224\320\260\377\200\200\200\200\200";
++    ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
++  }
++
++  /* Test overlong 2-byte character.  */
++  {
++    static const uint8_t input[] = "\320\224\320\260\301\200";
++    ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
++  }
++
++  /* Test overlong 3-byte character.  */
++  {
++    static const uint8_t input[] = "\320\224\320\260\340\200\277";
++    ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
++  }
++
++  /* Test overlong 4-byte character.  */
++  {
++    static const uint8_t input[] = "\320\224\320\260\360\200\277\277";
++    ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
++  }
++
++  /* Test invalid bytes in 2-byte character.  */
++  {
++    static const uint8_t input[] = "\320\224\320\260\302\200";
++    ASSERT (u8_check (input, sizeof (input) - 1) == NULL);
++  }
++  {
++    static const uint8_t input[] = "\320\224\320\260\302\100";
++    ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
++  }
++  {
++    static const uint8_t input[] = "\320\224\320\260\302\300";
++    ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
++  }
++
++  /* Test invalid bytes in 3-byte character.  */
++  {
++    static const uint8_t input[] = "\320\224\320\260\342\200\200";
++    ASSERT (u8_check (input, sizeof (input) - 1) == NULL);
++  }
++  {
++    static const uint8_t input[] = "\320\224\320\260\342\100\200";
++    ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
++  }
++  {
++    static const uint8_t input[] = "\320\224\320\260\342\300\200";
++    ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
++  }
++  {
++    static const uint8_t input[] = "\320\224\320\260\342\200\100";
++    ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
++  }
++  {
++    static const uint8_t input[] = "\320\224\320\260\342\200\300";
++    ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
++  }
++
++  /* Test invalid bytes in 4-byte character.  */
++  {
++    static const uint8_t input[] = "\320\224\320\260\362\200\200\200";
++    ASSERT (u8_check (input, sizeof (input) - 1) == NULL);
++  }
++  {
++    static const uint8_t input[] = "\320\224\320\260\362\100\200\200";
++    ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
++  }
++  {
++    static const uint8_t input[] = "\320\224\320\260\362\300\200\200";
++    ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
++  }
++  {
++    static const uint8_t input[] = "\320\224\320\260\362\200\100\200";
++    ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
++  }
++  {
++    static const uint8_t input[] = "\320\224\320\260\362\200\300\200";
++    ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
++  }
++  {
++    static const uint8_t input[] = "\320\224\320\260\362\200\200\100";
++    ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
++  }
++  {
++    static const uint8_t input[] = "\320\224\320\260\362\200\200\300";
++    ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
++  }
++
++  /* Test truncated/incomplete 2-byte character.  */
++  {
++    static const uint8_t input[] = "\320\224\320\260\302";
++    ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
++  }
++
++  /* Test truncated/incomplete 3-byte character.  */
++  {
++    static const uint8_t input[] = "\320\224\320\260\342\200";
++    ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
++  }
++
++  /* Test truncated/incomplete 4-byte character.  */
++  {
++    static const uint8_t input[] = "\320\224\320\260\362\200\200";
++    ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
++  }
++
++  /* Test missing lead byte.  */
++  {
++    static const uint8_t input[] = "\320\224\320\260\200\200\200\200\200";
++    ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
++  }
++
++  /* Test surrogate codepoints.  */
++  {
++    static const uint8_t input[] = "\320\224\320\260\355\240\200\355\260\200";
++    ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
++  }
++  {
++    static const uint8_t input[] = "\320\224\320\260\355\260\200";
++    ASSERT (u8_check (input, sizeof (input) - 1) == input + 4);
++  }
++
++  return 0;
++}
+--- a/lib/nfkc.c
++++ b/lib/nfkc.c
+@@ -1002,6 +1002,8 @@
+   return g_unichar_to_utf8 (c, outbuf);
+ }
+ 
++#include <unistr.h>
++
+ /**
+  * stringprep_utf8_to_ucs4:
+  * @str: a UTF-8 encoded string
+@@ -1010,9 +1012,10 @@
+  * @items_written: location to store the number of characters in the
+  *                 result, or %NULL.
+  *
+- * Convert a string from UTF-8 to a 32-bit fixed width
+- * representation as UCS-4, assuming valid UTF-8 input.
+- * This function does no error checking on the input.
++ * Convert a string from UTF-8 to a 32-bit fixed width representation
++ * as UCS-4.  The function now performs error checking to verify that
++ * the input is valid UTF-8 (before it was documented to not do error
++ * checking).
+  *
+  * Return value: a pointer to a newly allocated UCS-4 string.
+  *               This value must be deallocated by the caller.
+@@ -1020,6 +1023,16 @@
+ uint32_t *
+ stringprep_utf8_to_ucs4 (const char *str, ssize_t len, size_t * items_written)
+ {
++  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_to_ucs4_fast (str, (glong) len, (glong *) items_written);
+ }
+ 
+--- a/lib/strerror-idna.c
++++ b/lib/strerror-idna.c
+@@ -115,7 +115,7 @@
+       break;
+ 
+     case IDNA_ICONV_ERROR:
+-      p = _("System iconv failed");
++      p = _("Could not convert string in locale encoding");
+       break;
+ 
+     case IDNA_MALLOC_ERROR:
+--- a/lib/strerror-stringprep.c
++++ b/lib/strerror-stringprep.c
+@@ -65,6 +65,7 @@
+  *   This usually indicate a problem in the calling application.
+  * STRINGPREP_UNKNOWN_PROFILE: The supplied profile name was not
+  *   known to the library.
++ * STRINGPREP_ICONV_ERROR: Could not convert string in locale encoding.
+  * STRINGPREP_NFKC_FAILED: The Unicode NFKC operation failed.  This
+  *   usually indicate an internal error in the library.
+  * STRINGPREP_MALLOC_ERROR: The malloc() was out of memory.  This is
+@@ -121,6 +122,9 @@
+     case STRINGPREP_UNKNOWN_PROFILE:
+       p = _("Unknown profile");
+       break;
++    case STRINGPREP_ICONV_ERROR:
++      p = _("Could not convert string in locale encoding.");
++      break;
+ 
+     case STRINGPREP_NFKC_FAILED:
+       p = _("Unicode normalization failed (internal error)");
+--- a/lib/stringprep.c
++++ b/lib/stringprep.c
+@@ -380,6 +380,8 @@
+ 
+       free (ucs4);
+       ucs4 = stringprep_utf8_to_ucs4 (in, -1, &ucs4len);
++      if (ucs4 == NULL)
++	return STRINGPREP_ICONV_ERROR;
+       maxucs4len = ucs4len + adducs4len;
+       newp = realloc (ucs4, maxucs4len * sizeof (uint32_t));
+       if (!newp)
+@@ -402,7 +404,7 @@
+   utf8 = stringprep_ucs4_to_utf8 (ucs4, ucs4len, 0, 0);
+   free (ucs4);
+   if (!utf8)
+-    return STRINGPREP_MALLOC_ERROR;
++    return STRINGPREP_ICONV_ERROR;
+ 
+   if (strlen (utf8) >= maxlen)
+     {
+@@ -590,6 +592,7 @@
+  *   This usually indicate a problem in the calling application.
+  * @STRINGPREP_UNKNOWN_PROFILE: The supplied profile name was not
+  *   known to the library.
++ * @STRINGPREP_ICONV_ERROR: Could not convert string in locale encoding.
+  * @STRINGPREP_NFKC_FAILED: The Unicode NFKC operation failed.  This
+  *   usually indicate an internal error in the library.
+  * @STRINGPREP_MALLOC_ERROR: The malloc() was out of memory.  This is
+--- a/lib/stringprep.h
++++ b/lib/stringprep.h
+@@ -68,6 +68,7 @@
+     STRINGPREP_PROFILE_ERROR = 101,
+     STRINGPREP_FLAG_ERROR = 102,
+     STRINGPREP_UNKNOWN_PROFILE = 103,
++    STRINGPREP_ICONV_ERROR = 104,
+     /* Internal errors. */
+     STRINGPREP_NFKC_FAILED = 200,
+     STRINGPREP_MALLOC_ERROR = 201
+--- a/tests/Makefile.am
++++ b/tests/Makefile.am
+@@ -27,7 +27,7 @@
+ 
+ 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
+ if TLD
+ ctests += tst_tld
+ endif
+--- /dev/null
++++ b/tests/tst_badutf8.c
+@@ -0,0 +1,50 @@
++/* tst_badutf8.c --- Self tests for malformed UTF-8 regressions.
++ * Copyright (C) 2015 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"
++
++void
++doit (void)
++{
++  char *badutf8 = strdup ("\x7e\x64\x61\x72\x10\x2f\x2f\xf9\x2b\x71"
++			  "\x60\x79\x7b\x2e\x63\x75\x2b\x61\x65\x72"
++			  "\x75\x65\x56\x66\x7f\x62\xc5\x76\xe5\x00");
++  char *s = NULL;
++  int rc;
++
++  rc = idna_to_ascii_8z (badutf8, &s, 0);
++  free (badutf8);
++  if (rc != IDNA_ICONV_ERROR)
++    fail ("rc %d\n", rc);
++
++  idn_free (s);
++}
+--- a/tests/tst_stringprep.c
++++ b/tests/tst_stringprep.c
+@@ -100,7 +100,8 @@
+    "\xF4\x8F\xBF\xBF", NULL, "Nameprep", 0,
+    STRINGPREP_CONTAINS_PROHIBITED},
+   {"Surrogate code U+DF42",
+-   "\xED\xBD\x82", NULL, "Nameprep", 0, STRINGPREP_CONTAINS_PROHIBITED},
++   "\xED\xBD\x82", NULL, "Nameprep", 0, STRINGPREP_ICONV_ERROR
++   /* was STRINGPREP_CONTAINS_PROHIBITED */},
+   {"Non-plain text character U+FFFD",
+    "\xEF\xBF\xBD", NULL, "Nameprep", 0, STRINGPREP_CONTAINS_PROHIBITED},
+   {"Ideographic description character U+2FF5",
+@@ -234,15 +235,22 @@
+ 	  hexprint (strprep[i].in, strlen (strprep[i].in));
+ 	  binprint (strprep[i].in, strlen (strprep[i].in));
+ 	}
+-
+       {
+ 	uint32_t *l;
+-	char *x;
++	char *x = NULL;
+ 	l = stringprep_utf8_to_ucs4 (strprep[i].in, -1, NULL);
+-	x = stringprep_ucs4_to_utf8 (l, -1, NULL, NULL);
++	if (l)
++	  x = stringprep_ucs4_to_utf8 (l, -1, NULL, NULL);
+ 	free (l);
+-
+-	if (strcmp (strprep[i].in, x) != 0)
++	if (i == 29)
++	  /* Ignoring known bad UTF-8 in entry 29 */
++	  continue;
++	else if (l == NULL)
++	  {
++	    fail ("bad UTF-8 in entry %ld\n", i);
++	    continue;
++	  }
++	else if (strcmp (strprep[i].in, x) != 0)
+ 	  {
+ 	    fail ("bad UTF-8 in entry %ld\n", i);
+ 	    if (debug)
+@@ -254,10 +262,12 @@
+ 		escapeprint (x, strlen (x));
+ 		hexprint (x, strlen (x));
+ 	      }
++	    continue;
+ 	  }
+ 
+ 	free (x);
+       }
++
+       rc = stringprep_profile (strprep[i].in, &p,
+ 			       strprep[i].profile ?
+ 			       strprep[i].profile :
+--- a/tests/tst_idna4.c
++++ b/tests/tst_idna4.c
+@@ -46,7 +46,9 @@
+   if (rc != IDNA_INVALID_LENGTH)
+     fail ("unexpected rc %d\n", rc);
+ 
+-  rc = idna_to_ascii_8z("Loading...°°°°°°°°°°°°°°]", &out, 0);
++  rc = idna_to_ascii_8z("Loading...\xC2\xB0\xC2\xB0\xC2\xB0\xC2\xB0\xC2\xB0"
++			"\xC2\xB0\xC2\xB0\xC2\xB0\xC2\xB0\xC2\xB0\xC2\xB0"
++			"\xC2\xB0\xC2\xB0\xC2\xB0]", &out, 0);
+   if (rc != IDNA_INVALID_LENGTH)
+     fail ("unexpected rc %d\n", rc);
+ }
diff -Nru libidn-1.29/debian/patches/02_CVE-2015-2059-2.patch libidn-1.29/debian/patches/02_CVE-2015-2059-2.patch
--- libidn-1.29/debian/patches/02_CVE-2015-2059-2.patch	1970-01-01 10:00:00.000000000 +1000
+++ libidn-1.29/debian/patches/02_CVE-2015-2059-2.patch	2016-05-06 17:40:36.000000000 +1000
@@ -0,0 +1,106 @@
+From 58c721ac2dc96bccd737f3f544f3a22a50477bbf Mon Sep 17 00:00:00 2001
+From: Simon Josefsson <simon@josefsson.org>
+Date: Sat, 01 Aug 2015 13:12:10 +0000
+Subject: libidn: Fix crash in idna_to_unicode_8z8z and idna_to_unicode_8zlz.
+
+---
+--- a/lib/idna.c
++++ b/lib/idna.c
+@@ -746,13 +746,16 @@
+   int rc;
+ 
+   rc = idna_to_unicode_8z4z (input, &ucs4, flags);
++  if (rc != IDNA_SUCCESS)
++    return rc;
++
+   *output = stringprep_ucs4_to_utf8 (ucs4, -1, NULL, NULL);
+   free (ucs4);
+ 
+   if (!*output)
+     return IDNA_ICONV_ERROR;
+ 
+-  return rc;
++  return IDNA_SUCCESS;
+ }
+ 
+ /**
+@@ -777,13 +780,16 @@
+   int rc;
+ 
+   rc = idna_to_unicode_8z8z (input, &utf8, flags);
++  if (rc != IDNA_SUCCESS)
++    return rc;
++
+   *output = stringprep_utf8_to_locale (utf8);
+   free (utf8);
+ 
+   if (!*output)
+     return IDNA_ICONV_ERROR;
+ 
+-  return rc;
++  return IDNA_SUCCESS;
+ }
+ 
+ /**
+--- a/tests/Makefile.am
++++ b/tests/Makefile.am
+@@ -27,7 +27,7 @@
+ 
+ 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
+ if TLD
+ ctests += tst_tld
+ endif
+--- /dev/null
++++ b/tests/tst_utf8crash.c
+@@ -0,0 +1,48 @@
++/* tst_utf8crash.c --- Self tests for malformed UTF-8 regressions.
++ * Copyright (C) 2015 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"
++
++/* Based on report from Adam Sampson:
++   https://lists.gnu.org/archive/html/help-libidn/2015-07/msg00026.html */
++
++void
++doit (void)
++{
++  const char input[] = "\200bad.com";
++  char *output;
++  int rc;
++
++  rc = idna_to_unicode_8z8z(input, &output, 0);
++  if (rc != IDNA_ICONV_ERROR)
++    fail ("rc %d\n", rc);
++}
diff -Nru libidn-1.29/debian/patches/series libidn-1.29/debian/patches/series
--- libidn-1.29/debian/patches/series	1970-01-01 10:00:00.000000000 +1000
+++ libidn-1.29/debian/patches/series	2016-05-09 08:40:38.000000000 +1000
@@ -0,0 +1,3 @@
+01_CVE-2015-2059.patch
+02_CVE-2015-2059-2.patch
+skip_makeinfo.patch
diff -Nru libidn-1.29/debian/patches/skip_makeinfo.patch libidn-1.29/debian/patches/skip_makeinfo.patch
--- libidn-1.29/debian/patches/skip_makeinfo.patch	1970-01-01 10:00:00.000000000 +1000
+++ libidn-1.29/debian/patches/skip_makeinfo.patch	2016-05-09 08:41:11.000000000 +1000
@@ -0,0 +1,19 @@
+--- a/doc/Makefile.am
++++ b/doc/Makefile.am
+@@ -61,15 +61,7 @@
+ # GDOC
+ 
+ GDOC_BIN = $(srcdir)/gdoc
+-GDOC_SRC = $(top_srcdir)/lib/idna.c $(top_srcdir)/lib/nfkc.c	\
+-	$(top_srcdir)/lib/pr29.c $(top_srcdir)/lib/punycode.c	\
+-	$(top_srcdir)/lib/stringprep.c $(top_srcdir)/lib/tld.c	\
+-	$(top_srcdir)/lib/toutf8.c $(top_srcdir)/lib/version.c \
+-	$(top_srcdir)/lib/idn-free.c \
+-	$(top_srcdir)/lib/strerror-idna.c $(top_srcdir)/lib/strerror-pr29.c \
+-	$(top_srcdir)/lib/strerror-punycode.c \
+-	$(top_srcdir)/lib/strerror-stringprep.c \
+-	$(top_srcdir)/lib/strerror-tld.c
++GDOC_SRC =
+ GDOC_TEXI_PREFIX = texi/
+ GDOC_MAN_PREFIX = man/
+ GDOC_MAN_EXTRA_ARGS = -module $(PACKAGE) -sourceversion $(VERSION) \

Reply to: