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 <b...@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 <gh...@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 <si...@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 <br...@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 <br...@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 <si...@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 <gh...@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 <si...@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 <br...@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 <br...@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 <si...@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) \
_______________________________________________ Help-libidn mailing list Help-libidn@gnu.org https://lists.gnu.org/mailman/listinfo/help-libidn