This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GNU libidn".
http://git.savannah.gnu.org/cgit/libidn.git/commit/?id=2e97c2796581c27213962c77f5a8571a598f9a2e The branch, master has been updated via 2e97c2796581c27213962c77f5a8571a598f9a2e (commit) via a8dc72ad1cc0c666a99b472e7fbcee96fe9c5c96 (commit) via 45a3679b29106042cb522c6cd41167498d3284c3 (commit) via 7e9aae41e0d7ac8f1d1cadac00f6155b3cbda31c (commit) via d28219f5f0607d06c43eccb4e407708c38ed8f9c (commit) via 3f2961e6da21a0c33c0521914024466f3c4cf575 (commit) from 8fb4aad877b52cbd348524cc30fefe141d552f20 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 2e97c2796581c27213962c77f5a8571a598f9a2e Author: Simon Josefsson <[email protected]> Date: Wed Jul 8 02:06:22 2015 +0200 libidn: stringprep_utf8_to_ucs4 now rejects invalid UTF-8. CVE-2015-2059 commit a8dc72ad1cc0c666a99b472e7fbcee96fe9c5c96 Author: Simon Josefsson <[email protected]> Date: Wed Jul 8 01:02:00 2015 +0200 Fix broken encoding (ISO-8859-1 vs UTF-8) of this file. commit 45a3679b29106042cb522c6cd41167498d3284c3 Author: Simon Josefsson <[email protected]> Date: Tue Jul 7 23:56:58 2015 +0200 Use LOG_COMPILER instead of TEST_ENVIRONMENT, for valgrind. commit 7e9aae41e0d7ac8f1d1cadac00f6155b3cbda31c Author: Simon Josefsson <[email protected]> Date: Tue Jul 7 23:05:00 2015 +0200 Bump versions. Doc fix. commit d28219f5f0607d06c43eccb4e407708c38ed8f9c Author: Alessandro Ghedini <[email protected]> Date: Thu Jun 4 11:42:38 2015 +0200 Use strdup() to duplicate a buffer This apparently fixes the "Invalid read of size 4" error from valgrind that was reported at https://bugs.debian.org/724069 Signed-off-by: Simon Josefsson <[email protected]> commit 3f2961e6da21a0c33c0521914024466f3c4cf575 Author: Simon Josefsson <[email protected]> Date: Tue Jul 7 22:59:26 2015 +0200 Update gnulib files. ----------------------------------------------------------------------- Summary of changes: .gitignore | 8 ++ NEWS | 38 +++++++ build-aux/gendocs.sh | 20 ++-- build-aux/update-copyright | 2 +- configure.ac | 4 +- gl/error.c | 4 +- gl/error.h | 14 ++- gl/m4/extern-inline.m4 | 5 +- gl/m4/gnulib-common.m4 | 4 +- gl/m4/lstat.m4 | 48 ++++----- gl/m4/manywarnings.m4 | 23 ++++- gl/m4/stdio_h.m4 | 20 +++-- gl/stddef.in.h | 19 +++- gl/stdio.in.h | 3 +- gl/string.in.h | 21 ++++- gltests/init.sh | 1 + gltests/inttypes.in.h | 4 + gltests/test-stddef.c | 10 ++ gltests/wchar.in.h | 9 ++- lib/gl/Makefile.am | 10 ++- lib/gl/m4/codeset.m4 | 2 +- lib/gl/m4/extern-inline.m4 | 5 +- lib/gl/m4/gnulib-cache.m4 | 3 +- lib/gl/m4/gnulib-common.m4 | 4 +- lib/gl/m4/gnulib-comp.m4 | 5 + lib/gl/m4/iconv.m4 | 2 +- lib/gl/m4/intlmacosx.m4 | 2 +- lib/gl/m4/lcmessage.m4 | 2 +- lib/gl/stddef.in.h | 19 +++- lib/gl/string.in.h | 21 ++++- lib/gl/unistr/u8-check.c | 105 +++++++++++++++++++ lib/gltests/Makefile.am | 10 ++ lib/gltests/init.sh | 1 + lib/gltests/inttypes.in.h | 4 + lib/gltests/test-stddef.c | 10 ++ lib/gltests/unistr/test-u8-check.c | 188 ++++++++++++++++++++++++++++++++++ lib/gltests/wchar.in.h | 9 ++- lib/idna.c | 4 +- lib/nfkc.c | 19 +++- lib/strerror-idna.c | 2 +- lib/strerror-stringprep.c | 4 + lib/stringprep.c | 5 +- lib/stringprep.h | 3 +- tests/Makefile.am | 4 +- tests/{tst_idna4.c => tst_badutf8.c} | 24 ++--- tests/tst_idna4.c | 4 +- tests/tst_stringprep.c | 22 +++- 47 files changed, 637 insertions(+), 113 deletions(-) create mode 100644 lib/gl/unistr/u8-check.c create mode 100644 lib/gltests/unistr/test-u8-check.c copy tests/{tst_idna4.c => tst_badutf8.c} (64%) diff --git a/.gitignore b/.gitignore index bba0c12..37c5729 100644 --- a/.gitignore +++ b/.gitignore @@ -385,8 +385,12 @@ lib/gl/unistr.h lib/gl/unistr/.deps/ lib/gl/unistr/.dirstamp lib/gl/unistr/.libs/ +lib/gl/unistr/u8-check.lo +lib/gl/unistr/u8-check.o lib/gl/unistr/u8-mbtoucr.lo lib/gl/unistr/u8-mbtoucr.o +lib/gl/unistr/u8-to-u32.lo +lib/gl/unistr/u8-to-u32.o lib/gl/unistr/u8-uctomb-aux.lo lib/gl/unistr/u8-uctomb-aux.o lib/gl/unistr/u8-uctomb.lo @@ -471,6 +475,7 @@ lib/gltests/test-thread_create lib/gltests/test-thread_create.o lib/gltests/test-thread_self lib/gltests/test-thread_self.o +lib/gltests/test-u8-check lib/gltests/test-u8-mbtoucr lib/gltests/test-u8-uctomb lib/gltests/test-unistd @@ -484,6 +489,7 @@ lib/gltests/unistd.h lib/gltests/unistd.o lib/gltests/unistr/.deps/ lib/gltests/unistr/.dirstamp +lib/gltests/unistr/test-u8-check.o lib/gltests/unistr/test-u8-mbtoucr.o lib/gltests/unistr/test-u8-uctomb.o lib/gltests/unistr/unistr @@ -606,6 +612,8 @@ tests/.deps/ tests/Makefile tests/Makefile.in tests/libutils.a +tests/tst_badutf8 +tests/tst_badutf8.o tests/tst_idna tests/tst_idna.o tests/tst_idna2 diff --git a/NEWS b/NEWS index f6edf5a..22821d6 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,44 @@ Libidn NEWS -- History of user-visible changes. -*- outline -*- Copyright (C) 2002-2015 Simon Josefsson See the end for copying conditions. +* Version 1.31 (unreleased) [beta] + +** libidn: stringprep_utf8_to_ucs4 now rejects invalid UTF-8. CVE-2015-2059 +This function has always been documented to not validate that the +input UTF-8 string is actually valid UTF-8. Like the rest of the API, +when you call a function that works on UTF-8 data, you have to pass it +valid UTF-8 data. Application writers appear to have difficulties +using interfaces designed like that, as bugs triggered by invalid +UTF-8 has been identified in a number of projects (jabberd2, gnutls, +wget, and curl). While we could introduce a new API to perform UTF-8 +validation, so that applications can easily implement the proper +checks, this appear error prone because there is a risk that the check +will be forgotten. Instead, we took the more radical approach of +modifying the documentation and the implementation of the API. The +intention is that all functions that accepts UTF-8 data should +validate it before use. This will solve the problem for applications, +without needing to change them. This change has the unfortunate +side-effect that Surrogate codes (see section 5.5 of RFC 3454) no +longer trigger the STRINGPREP_CONTAINS_PROHIBITED error code but +instead will trigger the newly introduced STRINGPREP_ICONV_ERROR error +code, as the gnulib/libunistring-based code that we use to test +UTF-8-compliance rejects Surrogate codes. We hope that this is an +acceptable cost to live with in order to improve application security. +We welcome feedback on this solution, and we are marking this release +as beta rather than stable to signal that we may reconsider this +approach if people disagree. Reported by several people including +Thijs Alkemade, Gustavo Grieco, Daniel Stenberg, and Nikos +Mavrogiannopoulos. + +** libidn: Added STRINGPREP_ICONV_ERROR error code. + +** libidn: Workaround valgrind/gcc/glibc issue. +Valgrind reported a 'Invalid read of size 4' that was caused by +optimized strlen implementation. Reported and patch by Alessandro +Ghedini <[email protected]>. + +** API and ABI is backwards compatible with the previous version. + * Version 1.30 (released 2015-03-02) [stable] ** libidn: The punycode.{c,h} files were re-imported from RFC 3492bis. diff --git a/build-aux/gendocs.sh b/build-aux/gendocs.sh index 46faaaf..c8ca1bb 100755 --- a/build-aux/gendocs.sh +++ b/build-aux/gendocs.sh @@ -2,7 +2,7 @@ # gendocs.sh -- generate a GNU manual in many formats. This script is # mentioned in maintain.texi. See the help message below for usage details. -scriptversion=2015-01-02.22 +scriptversion=2015-05-05.16 # Copyright 2003-2015 Free Software Foundation, Inc. # @@ -29,7 +29,7 @@ scriptversion=2015-01-02.22 # http://git.savannah.gnu.org/cgit/gnulib.git/tree/doc/gendocs_template # TODO: -# - image importation was only implemented for HTML generated by +# - image importing was only implemented for HTML generated by # makeinfo. But it should be simple enough to adjust. # - images are not imported in the source tarball. All the needed # formats (PDF, PNG, etc.) should be included. @@ -42,7 +42,7 @@ templateurl="http://git.savannah.gnu.org/cgit/gnulib.git/plain/doc/gendocs_templ : ${SETLANG="env LANG= LC_MESSAGES= LC_ALL= LANGUAGE="} : ${MAKEINFO="makeinfo"} -: ${TEXI2DVI="texi2dvi -t @finalout"} +: ${TEXI2DVI="texi2dvi"} : ${DOCBOOK2HTML="docbook2html"} : ${DOCBOOK2PDF="docbook2pdf"} : ${DOCBOOK2TXT="docbook2txt"} @@ -54,7 +54,7 @@ unset use_texi2html version="gendocs.sh $scriptversion -Copyright 2013 Free Software Foundation, Inc. +Copyright 2015 Free Software Foundation, Inc. There is NO warranty. You may redistribute this software under the terms of the GNU General Public License. For more information about these matters, see the files named COPYING." @@ -73,7 +73,8 @@ Options: -o OUTDIR write files into OUTDIR, instead of manual/. -I DIR append DIR to the Texinfo search path. --common ARG pass ARG in all invocations. - --html ARG pass ARG to makeinfo or texi2html for HTML targets. + --html ARG pass ARG to makeinfo or texi2html for HTML targets, + instead of --css-ref=/software/gnulib/manual.css. --info ARG pass ARG to makeinfo for Info, instead of --no-split. --no-ascii skip generating the plain text output. --no-html skip generating the html output. @@ -81,6 +82,7 @@ Options: --no-tex skip generating the dvi and pdf output. --source ARG include ARG in tar archive of sources. --split HOW make split HTML by node, section, chapter; default node. + --tex ARG pass ARG to texi2dvi for DVI and PDF, instead of -t @finalout. --texi2html use texi2html to make HTML target, with all split versions. --docbook convert through DocBook too (xml, txt, html, pdf). @@ -141,7 +143,7 @@ [email protected] # please override with --email commonarg= # passed to all makeinfo/texi2html invcations. dirargs= # passed to all tools (-I dir). dirs= # -I directories. -htmlarg= +htmlarg=--css-ref=/software/gnulib/manual.css infoarg=--no-split generate_ascii=true generate_html=true @@ -151,6 +153,7 @@ outdir=manual source_extra= split=node srcfile= +texarg="-t @finalout" while test $# -gt 0; do case $1 in @@ -168,6 +171,7 @@ while test $# -gt 0; do --no-tex) generate_tex=false;; --source) shift; source_extra=$1;; --split) shift; split=$1;; + --tex) shift; texarg=$1;; --texi2html) use_texi2html=1;; --help) echo "$usage"; exit 0;; @@ -293,7 +297,7 @@ fi # end info # if $generate_tex; then - cmd="$SETLANG $TEXI2DVI $dirargs \"$srcfile\"" + cmd="$SETLANG $TEXI2DVI $dirargs $texarg \"$srcfile\"" printf "\nGenerating dvi... ($cmd)\n" eval "$cmd" # compress/finish dvi: @@ -302,7 +306,7 @@ if $generate_tex; then mv $PACKAGE.dvi.gz "$outdir/" ls -l "$outdir/$PACKAGE.dvi.gz" - cmd="$SETLANG $TEXI2DVI --pdf $dirargs \"$srcfile\"" + cmd="$SETLANG $TEXI2DVI --pdf $dirargs $texarg \"$srcfile\"" printf "\nGenerating pdf... ($cmd)\n" eval "$cmd" pdf_size=`calcsize $PACKAGE.pdf` diff --git a/build-aux/update-copyright b/build-aux/update-copyright index 4eb4b93..8cc36e2 100755 --- a/build-aux/update-copyright +++ b/build-aux/update-copyright @@ -124,7 +124,7 @@ use strict; use warnings; my $copyright_re = 'Copyright'; -my $circle_c_re = '(?:\([cC]\)|@copyright{}|\\\\\(co|©)'; +my $circle_c_re = '(?:\([cC]\)|@copyright\{}|\\\\\(co|©)'; my $holder = $ENV{UPDATE_COPYRIGHT_HOLDER}; $holder ||= 'Free Software Foundation, Inc.'; my $prefix_max = 5; diff --git a/configure.ac b/configure.ac index b20849e..79221f5 100644 --- a/configure.ac +++ b/configure.ac @@ -18,7 +18,7 @@ dnl You should have received a copy of the GNU General Public License dnl along with this program. If not, see <http://www.gnu.org/licenses/>. AC_PREREQ(2.61) -AC_INIT([GNU Libidn], [1.30], [[email protected]]) +AC_INIT([GNU Libidn], [1.31], [[email protected]]) AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_HEADERS(config.h) @@ -30,7 +30,7 @@ AM_SILENT_RULES([yes]) # Interfaces added: AGE++ # Interfaces removed: AGE=0 AC_SUBST(LT_CURRENT, 17) -AC_SUBST(LT_REVISION, 13) +AC_SUBST(LT_REVISION, 14) AC_SUBST(LT_AGE, 6) AC_PROG_CC diff --git a/gl/error.c b/gl/error.c index 6683197..0ac7695 100644 --- a/gl/error.c +++ b/gl/error.c @@ -379,10 +379,10 @@ error_at_line (int status, int errnum, const char *file_name, } #if _LIBC - __fxprintf (NULL, file_name != NULL ? "%s:%d: " : " ", + __fxprintf (NULL, file_name != NULL ? "%s:%u: " : " ", file_name, line_number); #else - fprintf (stderr, file_name != NULL ? "%s:%d: " : " ", + fprintf (stderr, file_name != NULL ? "%s:%u: " : " ", file_name, line_number); #endif diff --git a/gl/error.h b/gl/error.h index ccffef5..eb4fb70 100644 --- a/gl/error.h +++ b/gl/error.h @@ -31,6 +31,16 @@ # define _GL_ATTRIBUTE_FORMAT(spec) /* empty */ #endif +/* On mingw, the flavor of printf depends on whether the extensions module + * is in use; the check for <stdio.h> determines the witness macro. */ +#ifndef _GL_ATTRIBUTE_SPEC_PRINTF +# if GNULIB_PRINTF_ATTRIBUTE_FLAVOR_GNU +# define _GL_ATTRIBUTE_SPEC_PRINTF __gnu_printf__ +# else +# define _GL_ATTRIBUTE_SPEC_PRINTF __printf__ +# endif +#endif + #ifdef __cplusplus extern "C" { #endif @@ -40,11 +50,11 @@ extern "C" { If STATUS is nonzero, terminate the program with 'exit (STATUS)'. */ extern void error (int __status, int __errnum, const char *__format, ...) - _GL_ATTRIBUTE_FORMAT ((__printf__, 3, 4)); + _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF, 3, 4)); extern void error_at_line (int __status, int __errnum, const char *__fname, unsigned int __lineno, const char *__format, ...) - _GL_ATTRIBUTE_FORMAT ((__printf__, 5, 6)); + _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF, 5, 6)); /* If NULL, error will flush stdout, then print on stderr the program name, a colon and a space. Otherwise, error will call this diff --git a/gl/m4/extern-inline.m4 b/gl/m4/extern-inline.m4 index e74339a..7280065 100644 --- a/gl/m4/extern-inline.m4 +++ b/gl/m4/extern-inline.m4 @@ -74,12 +74,13 @@ AC_DEFUN([gl_EXTERN_INLINE], # define _GL_EXTERN_INLINE static _GL_UNUSED #endif -/* In GCC, suppress bogus "no previous prototype for 'FOO'" +/* In GCC 4.6 (inclusive) to 5.1 (exclusive), + suppress bogus "no previous prototype for 'FOO'" and "no previous declaration for 'FOO'" diagnostics, when FOO is an inline function in the header; see <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54113> and <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63877>. */ -#if 4 < __GNUC__ + (6 <= __GNUC_MINOR__) +#if __GNUC__ == 4 && 6 <= __GNUC_MINOR__ # if defined __GNUC_STDC_INLINE__ && __GNUC_STDC_INLINE__ # define _GL_INLINE_HEADER_CONST_PRAGMA # else diff --git a/gl/m4/gnulib-common.m4 b/gl/m4/gnulib-common.m4 index b301abe..40e82f6 100644 --- a/gl/m4/gnulib-common.m4 +++ b/gl/m4/gnulib-common.m4 @@ -278,12 +278,12 @@ Amsterdam dnl but prefer ${host}-ar over ar (useful for cross-compiling). AC_CHECK_TOOL([AR], [ar], [ar]) if test -z "$ARFLAGS"; then - ARFLAGS='cru' + ARFLAGS='cr' fi fi else if test -z "$ARFLAGS"; then - ARFLAGS='cru' + ARFLAGS='cr' fi fi AC_SUBST([AR]) diff --git a/gl/m4/lstat.m4 b/gl/m4/lstat.m4 index f6c7dd1..adf752c 100644 --- a/gl/m4/lstat.m4 +++ b/gl/m4/lstat.m4 @@ -1,4 +1,4 @@ -# serial 26 +# serial 27 # Copyright (C) 1997-2001, 2003-2015 Free Software Foundation, Inc. # @@ -37,30 +37,28 @@ AC_DEFUN([gl_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK], [gl_cv_func_lstat_dereferences_slashed_symlink], [rm -f conftest.sym conftest.file echo >conftest.file - if test "$as_ln_s" = "ln -s" && ln -s conftest.file conftest.sym; then - AC_RUN_IFELSE( - [AC_LANG_PROGRAM( - [AC_INCLUDES_DEFAULT], - [[struct stat sbuf; - /* Linux will dereference the symlink and fail, as required by - POSIX. That is better in the sense that it means we will not - have to compile and use the lstat wrapper. */ - return lstat ("conftest.sym/", &sbuf) == 0; - ]])], - [gl_cv_func_lstat_dereferences_slashed_symlink=yes], - [gl_cv_func_lstat_dereferences_slashed_symlink=no], - [case "$host_os" in - # Guess yes on glibc systems. - *-gnu*) gl_cv_func_lstat_dereferences_slashed_symlink="guessing yes" ;; - # If we don't know, assume the worst. - *) gl_cv_func_lstat_dereferences_slashed_symlink="guessing no" ;; - esac - ]) - else - # If the 'ln -s' command failed, then we probably don't even - # have an lstat function. - gl_cv_func_lstat_dereferences_slashed_symlink="guessing no" - fi + AC_RUN_IFELSE( + [AC_LANG_PROGRAM( + [AC_INCLUDES_DEFAULT], + [[struct stat sbuf; + if (symlink ("conftest.file", "conftest.sym") != 0) + return 1; + /* Linux will dereference the symlink and fail, as required by + POSIX. That is better in the sense that it means we will not + have to compile and use the lstat wrapper. */ + return lstat ("conftest.sym/", &sbuf) == 0; + ]])], + [gl_cv_func_lstat_dereferences_slashed_symlink=yes], + [gl_cv_func_lstat_dereferences_slashed_symlink=no], + [case "$host_os" in + *-gnu*) + # Guess yes on glibc systems. + gl_cv_func_lstat_dereferences_slashed_symlink="guessing yes" ;; + *) + # If we don't know, assume the worst. + gl_cv_func_lstat_dereferences_slashed_symlink="guessing no" ;; + esac + ]) rm -f conftest.sym conftest.file ]) case "$gl_cv_func_lstat_dereferences_slashed_symlink" in diff --git a/gl/m4/manywarnings.m4 b/gl/m4/manywarnings.m4 index 44da98e..b4e38d9 100644 --- a/gl/m4/manywarnings.m4 +++ b/gl/m4/manywarnings.m4 @@ -108,12 +108,13 @@ AC_DEFUN([gl_MANYWARN_ALL_GCC], -Waddress \ -Waggressive-loop-optimizations \ -Wall \ - -Warray-bounds \ -Wattributes \ -Wbad-function-cast \ + -Wbool-compare \ -Wbuiltin-macro-redefined \ -Wcast-align \ -Wchar-subscripts \ + -Wchkp \ -Wclobbered \ -Wcomment \ -Wcomments \ @@ -122,7 +123,10 @@ AC_DEFUN([gl_MANYWARN_ALL_GCC], -Wdate-time \ -Wdeprecated \ -Wdeprecated-declarations \ + -Wdesignated-init \ -Wdisabled-optimization \ + -Wdiscarded-array-qualifiers \ + -Wdiscarded-qualifiers \ -Wdiv-by-zero \ -Wdouble-promotion \ -Wempty-body \ @@ -133,6 +137,7 @@ AC_DEFUN([gl_MANYWARN_ALL_GCC], -Wformat-extra-args \ -Wformat-nonliteral \ -Wformat-security \ + -Wformat-signedness \ -Wformat-y2k \ -Wformat-zero-length \ -Wfree-nonheap-object \ @@ -140,15 +145,19 @@ AC_DEFUN([gl_MANYWARN_ALL_GCC], -Wimplicit \ -Wimplicit-function-declaration \ -Wimplicit-int \ + -Wincompatible-pointer-types \ -Winit-self \ -Winline \ + -Wint-conversion \ -Wint-to-pointer-cast \ -Winvalid-memory-model \ -Winvalid-pch \ -Wjump-misses-init \ + -Wlogical-not-parentheses \ -Wlogical-op \ -Wmain \ -Wmaybe-uninitialized \ + -Wmemset-transposed-args \ -Wmissing-braces \ -Wmissing-declarations \ -Wmissing-field-initializers \ @@ -159,6 +168,7 @@ AC_DEFUN([gl_MANYWARN_ALL_GCC], -Wnarrowing \ -Wnested-externs \ -Wnonnull \ + -Wodr \ -Wold-style-declaration \ -Wold-style-definition \ -Wopenmp-simd \ @@ -176,6 +186,9 @@ AC_DEFUN([gl_MANYWARN_ALL_GCC], -Wreturn-type \ -Wsequence-point \ -Wshadow \ + -Wshift-count-negative \ + -Wshift-count-overflow \ + -Wsizeof-array-argument \ -Wsizeof-pointer-memaccess \ -Wstack-protector \ -Wstrict-aliasing \ @@ -185,7 +198,10 @@ AC_DEFUN([gl_MANYWARN_ALL_GCC], -Wsuggest-attribute=format \ -Wsuggest-attribute=noreturn \ -Wsuggest-attribute=pure \ + -Wsuggest-final-methods \ + -Wsuggest-final-types \ -Wswitch \ + -Wswitch-bool \ -Wswitch-default \ -Wsync-nand \ -Wsystem-headers \ @@ -217,8 +233,9 @@ AC_DEFUN([gl_MANYWARN_ALL_GCC], gl_manywarn_set="$gl_manywarn_set $gl_manywarn_item" done - # gcc --help=warnings outputs an unusual form for this option; list - # it here so that the above 'comm' command doesn't report a false match. + # gcc --help=warnings outputs an unusual form for these options; list + # them here so that the above 'comm' command doesn't report a false match. + gl_manywarn_set="$gl_manywarn_set -Warray-bounds=2" gl_manywarn_set="$gl_manywarn_set -Wnormalized=nfc" # These are needed for older GCC versions. diff --git a/gl/m4/stdio_h.m4 b/gl/m4/stdio_h.m4 index e0c4bde..f60cc21 100644 --- a/gl/m4/stdio_h.m4 +++ b/gl/m4/stdio_h.m4 @@ -1,4 +1,4 @@ -# stdio_h.m4 serial 44 +# stdio_h.m4 serial 46 dnl Copyright (C) 2007-2015 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -15,15 +15,21 @@ AC_DEFUN([gl_STDIO_H], dnl Determine whether __USE_MINGW_ANSI_STDIO makes printf and dnl inttypes.h behave like gnu instead of system; we must give our dnl printf wrapper the right attribute to match. - AC_CACHE_CHECK([whether inttypes macros match system or gnu printf], + AC_CACHE_CHECK([which flavor of printf attribute matches inttypes macros], [gl_cv_func_printf_attribute_flavor], - [AC_EGREP_CPP([findme .(ll|j)d. findme], - [#define __STDC_FORMAT_MACROS 1 + [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + #define __STDC_FORMAT_MACROS 1 #include <stdio.h> #include <inttypes.h> - findme PRIdMAX findme - ], [gl_cv_func_printf_attribute_flavor=gnu], - [gl_cv_func_printf_attribute_flavor=system])]) + /* For non-mingw systems, compilation will trivially succeed. + For mingw, compilation will succeed for older mingw (system + printf, "I64d") and fail for newer mingw (gnu printf, "lld"). */ + #if ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__) && \ + (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) + extern char PRIdMAX_probe[sizeof PRIdMAX == sizeof "I64d" ? 1 : -1]; + #endif + ]])], [gl_cv_func_printf_attribute_flavor=system], + [gl_cv_func_printf_attribute_flavor=gnu])]) if test "$gl_cv_func_printf_attribute_flavor" = gnu; then AC_DEFINE([GNULIB_PRINTF_ATTRIBUTE_FLAVOR_GNU], [1], [Define to 1 if printf and friends should be labeled with diff --git a/gl/stddef.in.h b/gl/stddef.in.h index 44db241..698307b 100644 --- a/gl/stddef.in.h +++ b/gl/stddef.in.h @@ -83,12 +83,23 @@ /* Some platforms lack max_align_t. */ #if !@HAVE_MAX_ALIGN_T@ +/* On the x86, the maximum storage alignment of double, long, etc. is 4, + but GCC's C11 ABI for x86 says that max_align_t has an alignment of 8, + and the C11 standard allows this. Work around this problem by + using __alignof__ (which returns 8 for double) rather than _Alignof + (which returns 4), and align each union member accordingly. */ +# ifdef __GNUC__ +# define _GL_STDDEF_ALIGNAS(type) \ + __attribute__ ((__aligned__ (__alignof__ (type)))) +# else +# define _GL_STDDEF_ALIGNAS(type) /* */ +# endif typedef union { - char *__p; - double __d; - long double __ld; - long int __i; + char *__p _GL_STDDEF_ALIGNAS (char *); + double __d _GL_STDDEF_ALIGNAS (double); + long double __ld _GL_STDDEF_ALIGNAS (long double); + long int __i _GL_STDDEF_ALIGNAS (long int); } max_align_t; #endif diff --git a/gl/stdio.in.h b/gl/stdio.in.h index 759c94d..ec43874 100644 --- a/gl/stdio.in.h +++ b/gl/stdio.in.h @@ -723,11 +723,10 @@ _GL_WARN_ON_USE (getline, "getline is unportable - " so any use of gets warrants an unconditional warning; besides, C11 removed it. */ #undef gets -#if HAVE_RAW_DECL_GETS +#if HAVE_RAW_DECL_GETS && !defined __cplusplus _GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead"); #endif - #if @GNULIB_OBSTACK_PRINTF@ || @GNULIB_OBSTACK_PRINTF_POSIX@ struct obstack; /* Grow an obstack with formatted output. Return the number of diff --git a/gl/string.in.h b/gl/string.in.h index ebd727e..2abd6bc 100644 --- a/gl/string.in.h +++ b/gl/string.in.h @@ -15,16 +15,32 @@ You should have received a copy of the GNU General Public License along with this program; if not, see <http://www.gnu.org/licenses/>. */ -#ifndef _@GUARD_PREFIX@_STRING_H - #if __GNUC__ >= 3 @PRAGMA_SYSTEM_HEADER@ #endif @PRAGMA_COLUMNS@ +#if defined _GL_ALREADY_INCLUDING_STRING_H +/* Special invocation convention: + - On OS X/NetBSD we have a sequence of nested includes + <string.h> -> <strings.h> -> "string.h" + In this situation system _chk variants due to -D_FORTIFY_SOURCE + might be used after any replacements defined here. */ + +#@INCLUDE_NEXT@ @NEXT_STRING_H@ + +#else +/* Normal invocation convention. */ + +#ifndef _@GUARD_PREFIX@_STRING_H + +#define _GL_ALREADY_INCLUDING_STRING_H + /* The include_next requires a split double-inclusion guard. */ #@INCLUDE_NEXT@ @NEXT_STRING_H@ +#undef _GL_ALREADY_INCLUDING_STRING_H + #ifndef _@GUARD_PREFIX@_STRING_H #define _@GUARD_PREFIX@_STRING_H @@ -1027,3 +1043,4 @@ _GL_WARN_ON_USE (strverscmp, "strverscmp is unportable - " #endif /* _@GUARD_PREFIX@_STRING_H */ #endif /* _@GUARD_PREFIX@_STRING_H */ +#endif diff --git a/gltests/init.sh b/gltests/init.sh index 9f403c5..d366206 100644 --- a/gltests/init.sh +++ b/gltests/init.sh @@ -150,6 +150,7 @@ fi # ? - not ok gl_shell_test_script_=' test $(echo y) = y || exit 1 +f_local_() { local v=1; }; f_local_ || exit 1 score_=10 if test "$VERBOSE" = yes; then test -n "$( (exec 3>&1; set -x; P=1 true 2>&3) 2> /dev/null)" && score_=9 diff --git a/gltests/inttypes.in.h b/gltests/inttypes.in.h index 13a72be..78846f6 100644 --- a/gltests/inttypes.in.h +++ b/gltests/inttypes.in.h @@ -51,6 +51,10 @@ #endif /* Get CHAR_BIT. */ #include <limits.h> +/* On mingw, __USE_MINGW_ANSI_STDIO only works if <stdio.h> is also included */ +#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ +# include <stdio.h> +#endif #if !(INT_MIN == INT32_MIN && INT_MAX == INT32_MAX) # error "This file assumes that 'int' has exactly 32 bits. Please report your platform and compiler to <[email protected]>." diff --git a/gltests/test-stddef.c b/gltests/test-stddef.c index 3179496..aa6ae54 100644 --- a/gltests/test-stddef.c +++ b/gltests/test-stddef.c @@ -55,6 +55,16 @@ verify (alignof (ptrdiff_t) <= alignof (max_align_t)); verify (alignof (size_t) <= alignof (max_align_t)); verify (alignof (wchar_t) <= alignof (max_align_t)); verify (alignof (struct d) <= alignof (max_align_t)); +#if defined __GNUC__ || defined __IBM__ALIGNOF__ +verify (__alignof__ (double) <= __alignof__ (max_align_t)); +verify (__alignof__ (int) <= __alignof__ (max_align_t)); +verify (__alignof__ (long double) <= __alignof__ (max_align_t)); +verify (__alignof__ (long int) <= __alignof__ (max_align_t)); +verify (__alignof__ (ptrdiff_t) <= __alignof__ (max_align_t)); +verify (__alignof__ (size_t) <= __alignof__ (max_align_t)); +verify (__alignof__ (wchar_t) <= __alignof__ (max_align_t)); +verify (__alignof__ (struct d) <= __alignof__ (max_align_t)); +#endif int main (void) diff --git a/gltests/wchar.in.h b/gltests/wchar.in.h index fc06d27..684299f 100644 --- a/gltests/wchar.in.h +++ b/gltests/wchar.in.h @@ -30,9 +30,14 @@ #endif @PRAGMA_COLUMNS@ -#if defined __need_mbstate_t || defined __need_wint_t || (defined __hpux && ((defined _INTTYPES_INCLUDED && !defined strtoimax) || defined _GL_JUST_INCLUDE_SYSTEM_WCHAR_H)) || defined _GL_ALREADY_INCLUDING_WCHAR_H +#if (((defined __need_mbstate_t || defined __need_wint_t) \ + && !defined __MINGW32__) \ + || (defined __hpux \ + && ((defined _INTTYPES_INCLUDED && !defined strtoimax) \ + || defined _GL_JUST_INCLUDE_SYSTEM_WCHAR_H)) \ + || defined _GL_ALREADY_INCLUDING_WCHAR_H) /* Special invocation convention: - - Inside glibc and uClibc header files. + - Inside glibc and uClibc header files, but not MinGW. - On HP-UX 11.00 we have a sequence of nested includes <wchar.h> -> <stdlib.h> -> <stdint.h>, and the latter includes <wchar.h>, once indirectly <stdint.h> -> <sys/types.h> -> <inttypes.h> -> <wchar.h> diff --git a/lib/gl/Makefile.am b/lib/gl/Makefile.am index e453192..3902005 100644 --- 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 @@ -524,6 +524,14 @@ EXTRA_DIST += unistr.in.h ## 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 diff --git a/lib/gl/m4/codeset.m4 b/lib/gl/m4/codeset.m4 index 1c52ffc..d7de8d6 100644 --- a/lib/gl/m4/codeset.m4 +++ b/lib/gl/m4/codeset.m4 @@ -1,5 +1,5 @@ # codeset.m4 serial 5 (gettext-0.18.2) -dnl Copyright (C) 2000-2002, 2006, 2008-2015 Free Software Foundation, Inc. +dnl Copyright (C) 2000-2002, 2006, 2008-2014 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. diff --git a/lib/gl/m4/extern-inline.m4 b/lib/gl/m4/extern-inline.m4 index e74339a..7280065 100644 --- a/lib/gl/m4/extern-inline.m4 +++ b/lib/gl/m4/extern-inline.m4 @@ -74,12 +74,13 @@ AC_DEFUN([gl_EXTERN_INLINE], # define _GL_EXTERN_INLINE static _GL_UNUSED #endif -/* In GCC, suppress bogus "no previous prototype for 'FOO'" +/* In GCC 4.6 (inclusive) to 5.1 (exclusive), + suppress bogus "no previous prototype for 'FOO'" and "no previous declaration for 'FOO'" diagnostics, when FOO is an inline function in the header; see <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54113> and <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63877>. */ -#if 4 < __GNUC__ + (6 <= __GNUC_MINOR__) +#if __GNUC__ == 4 && 6 <= __GNUC_MINOR__ # if defined __GNUC_STDC_INLINE__ && __GNUC_STDC_INLINE__ # define _GL_INLINE_HEADER_CONST_PRAGMA # else diff --git a/lib/gl/m4/gnulib-cache.m4 b/lib/gl/m4/gnulib-cache.m4 index 16a70bb..1c59f8f 100644 --- 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 @@ gl_MODULES([ stdint striconv strverscmp + unistr/u8-check ]) gl_AVOID([iconv-h-tests string-tests wchar-tests]) gl_SOURCE_BASE([lib/gl]) diff --git a/lib/gl/m4/gnulib-common.m4 b/lib/gl/m4/gnulib-common.m4 index b301abe..40e82f6 100644 --- a/lib/gl/m4/gnulib-common.m4 +++ b/lib/gl/m4/gnulib-common.m4 @@ -278,12 +278,12 @@ Amsterdam dnl but prefer ${host}-ar over ar (useful for cross-compiling). AC_CHECK_TOOL([AR], [ar], [ar]) if test -z "$ARFLAGS"; then - ARFLAGS='cru' + ARFLAGS='cr' fi fi else if test -z "$ARFLAGS"; then - ARFLAGS='cru' + ARFLAGS='cr' fi fi AC_SUBST([AR]) diff --git a/lib/gl/m4/gnulib-comp.m4 b/lib/gl/m4/gnulib-comp.m4 index 83f0b0f..715104c 100644 --- a/lib/gl/m4/gnulib-comp.m4 +++ b/lib/gl/m4/gnulib-comp.m4 @@ -117,6 +117,8 @@ AC_DEFUN([lgl_EARLY], # 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: @@ -182,6 +184,7 @@ AC_DEFUN([lgl_INIT], gl_SYS_TYPES_H AC_PROG_MKDIR_P gl_LIBUNISTRING_LIBHEADER([0.9.4], [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]) @@ -411,6 +414,7 @@ AC_DEFUN([lgl_FILE_LIST], [ 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 @@ -511,6 +515,7 @@ AC_DEFUN([lgl_FILE_LIST], [ 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 diff --git a/lib/gl/m4/iconv.m4 b/lib/gl/m4/iconv.m4 index 5a6c29b..4e37363 100644 --- a/lib/gl/m4/iconv.m4 +++ b/lib/gl/m4/iconv.m4 @@ -1,5 +1,5 @@ # iconv.m4 serial 19 (gettext-0.18.2) -dnl Copyright (C) 2000-2002, 2007-2015 Free Software Foundation, Inc. +dnl Copyright (C) 2000-2002, 2007-2014 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. diff --git a/lib/gl/m4/intlmacosx.m4 b/lib/gl/m4/intlmacosx.m4 index 0d8d298..8a045f6 100644 --- a/lib/gl/m4/intlmacosx.m4 +++ b/lib/gl/m4/intlmacosx.m4 @@ -1,5 +1,5 @@ # intlmacosx.m4 serial 5 (gettext-0.18.2) -dnl Copyright (C) 2004-2015 Free Software Foundation, Inc. +dnl Copyright (C) 2004-2014 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. diff --git a/lib/gl/m4/lcmessage.m4 b/lib/gl/m4/lcmessage.m4 index 2fcce61..7470ec5 100644 --- a/lib/gl/m4/lcmessage.m4 +++ b/lib/gl/m4/lcmessage.m4 @@ -1,5 +1,5 @@ # lcmessage.m4 serial 7 (gettext-0.18.2) -dnl Copyright (C) 1995-2002, 2004-2005, 2008-2015 Free Software Foundation, +dnl Copyright (C) 1995-2002, 2004-2005, 2008-2014 Free Software Foundation, dnl Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, diff --git a/lib/gl/stddef.in.h b/lib/gl/stddef.in.h index 86777bd..5398faf 100644 --- a/lib/gl/stddef.in.h +++ b/lib/gl/stddef.in.h @@ -83,12 +83,23 @@ /* Some platforms lack max_align_t. */ #if !@HAVE_MAX_ALIGN_T@ +/* On the x86, the maximum storage alignment of double, long, etc. is 4, + but GCC's C11 ABI for x86 says that max_align_t has an alignment of 8, + and the C11 standard allows this. Work around this problem by + using __alignof__ (which returns 8 for double) rather than _Alignof + (which returns 4), and align each union member accordingly. */ +# ifdef __GNUC__ +# define _GL_STDDEF_ALIGNAS(type) \ + __attribute__ ((__aligned__ (__alignof__ (type)))) +# else +# define _GL_STDDEF_ALIGNAS(type) /* */ +# endif typedef union { - char *__p; - double __d; - long double __ld; - long int __i; + char *__p _GL_STDDEF_ALIGNAS (char *); + double __d _GL_STDDEF_ALIGNAS (double); + long double __ld _GL_STDDEF_ALIGNAS (long double); + long int __i _GL_STDDEF_ALIGNAS (long int); } max_align_t; #endif diff --git a/lib/gl/string.in.h b/lib/gl/string.in.h index fefc421..47e1188 100644 --- a/lib/gl/string.in.h +++ b/lib/gl/string.in.h @@ -15,16 +15,32 @@ 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/>. */ -#ifndef _@GUARD_PREFIX@_STRING_H - #if __GNUC__ >= 3 @PRAGMA_SYSTEM_HEADER@ #endif @PRAGMA_COLUMNS@ +#if defined _GL_ALREADY_INCLUDING_STRING_H +/* Special invocation convention: + - On OS X/NetBSD we have a sequence of nested includes + <string.h> -> <strings.h> -> "string.h" + In this situation system _chk variants due to -D_FORTIFY_SOURCE + might be used after any replacements defined here. */ + +#@INCLUDE_NEXT@ @NEXT_STRING_H@ + +#else +/* Normal invocation convention. */ + +#ifndef _@GUARD_PREFIX@_STRING_H + +#define _GL_ALREADY_INCLUDING_STRING_H + /* The include_next requires a split double-inclusion guard. */ #@INCLUDE_NEXT@ @NEXT_STRING_H@ +#undef _GL_ALREADY_INCLUDING_STRING_H + #ifndef _@GUARD_PREFIX@_STRING_H #define _@GUARD_PREFIX@_STRING_H @@ -1027,3 +1043,4 @@ _GL_WARN_ON_USE (strverscmp, "strverscmp is unportable - " #endif /* _@GUARD_PREFIX@_STRING_H */ #endif /* _@GUARD_PREFIX@_STRING_H */ +#endif diff --git a/lib/gl/unistr/u8-check.c b/lib/gl/unistr/u8-check.c new file mode 100644 index 0000000..0e87f11 --- /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 <[email protected]>, 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; +} diff --git a/lib/gltests/Makefile.am b/lib/gltests/Makefile.am index 4544746..d6de4bc 100644 --- a/lib/gltests/Makefile.am +++ b/lib/gltests/Makefile.am @@ -880,6 +880,16 @@ EXTRA_DIST += test-unistd.c ## 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 diff --git a/lib/gltests/init.sh b/lib/gltests/init.sh index 9f403c5..d366206 100644 --- a/lib/gltests/init.sh +++ b/lib/gltests/init.sh @@ -150,6 +150,7 @@ fi # ? - not ok gl_shell_test_script_=' test $(echo y) = y || exit 1 +f_local_() { local v=1; }; f_local_ || exit 1 score_=10 if test "$VERBOSE" = yes; then test -n "$( (exec 3>&1; set -x; P=1 true 2>&3) 2> /dev/null)" && score_=9 diff --git a/lib/gltests/inttypes.in.h b/lib/gltests/inttypes.in.h index 13a72be..78846f6 100644 --- a/lib/gltests/inttypes.in.h +++ b/lib/gltests/inttypes.in.h @@ -51,6 +51,10 @@ #endif /* Get CHAR_BIT. */ #include <limits.h> +/* On mingw, __USE_MINGW_ANSI_STDIO only works if <stdio.h> is also included */ +#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ +# include <stdio.h> +#endif #if !(INT_MIN == INT32_MIN && INT_MAX == INT32_MAX) # error "This file assumes that 'int' has exactly 32 bits. Please report your platform and compiler to <[email protected]>." diff --git a/lib/gltests/test-stddef.c b/lib/gltests/test-stddef.c index 3179496..aa6ae54 100644 --- a/lib/gltests/test-stddef.c +++ b/lib/gltests/test-stddef.c @@ -55,6 +55,16 @@ verify (alignof (ptrdiff_t) <= alignof (max_align_t)); verify (alignof (size_t) <= alignof (max_align_t)); verify (alignof (wchar_t) <= alignof (max_align_t)); verify (alignof (struct d) <= alignof (max_align_t)); +#if defined __GNUC__ || defined __IBM__ALIGNOF__ +verify (__alignof__ (double) <= __alignof__ (max_align_t)); +verify (__alignof__ (int) <= __alignof__ (max_align_t)); +verify (__alignof__ (long double) <= __alignof__ (max_align_t)); +verify (__alignof__ (long int) <= __alignof__ (max_align_t)); +verify (__alignof__ (ptrdiff_t) <= __alignof__ (max_align_t)); +verify (__alignof__ (size_t) <= __alignof__ (max_align_t)); +verify (__alignof__ (wchar_t) <= __alignof__ (max_align_t)); +verify (__alignof__ (struct d) <= __alignof__ (max_align_t)); +#endif int main (void) diff --git a/lib/gltests/unistr/test-u8-check.c b/lib/gltests/unistr/test-u8-check.c new file mode 100644 index 0000000..fcf678c --- /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 <[email protected]>, 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; +} diff --git a/lib/gltests/wchar.in.h b/lib/gltests/wchar.in.h index fc06d27..684299f 100644 --- a/lib/gltests/wchar.in.h +++ b/lib/gltests/wchar.in.h @@ -30,9 +30,14 @@ #endif @PRAGMA_COLUMNS@ -#if defined __need_mbstate_t || defined __need_wint_t || (defined __hpux && ((defined _INTTYPES_INCLUDED && !defined strtoimax) || defined _GL_JUST_INCLUDE_SYSTEM_WCHAR_H)) || defined _GL_ALREADY_INCLUDING_WCHAR_H +#if (((defined __need_mbstate_t || defined __need_wint_t) \ + && !defined __MINGW32__) \ + || (defined __hpux \ + && ((defined _INTTYPES_INCLUDED && !defined strtoimax) \ + || defined _GL_JUST_INCLUDE_SYSTEM_WCHAR_H)) \ + || defined _GL_ALREADY_INCLUDING_WCHAR_H) /* Special invocation convention: - - Inside glibc and uClibc header files. + - Inside glibc and uClibc header files, but not MinGW. - On HP-UX 11.00 we have a sequence of nested includes <wchar.h> -> <stdlib.h> -> <stdint.h>, and the latter includes <wchar.h>, once indirectly <stdint.h> -> <sys/types.h> -> <inttypes.h> -> <wchar.h> diff --git a/lib/idna.c b/lib/idna.c index bf93bfe..17774d0 100644 --- a/lib/idna.c +++ b/lib/idna.c @@ -539,11 +539,9 @@ idna_to_ascii_4z (const uint32_t * input, char **output, int flags) } else { - size_t l = strlen (buf) + 1; - out = (char *) malloc (l); + out = strdup (buf); if (!out) return IDNA_MALLOC_ERROR; - strcpy (out, buf); } start = end + 1; diff --git a/lib/nfkc.c b/lib/nfkc.c index fbea0c8..4992074 100644 --- a/lib/nfkc.c +++ b/lib/nfkc.c @@ -1002,6 +1002,8 @@ stringprep_unichar_to_utf8 (uint32_t c, char *outbuf) return g_unichar_to_utf8 (c, outbuf); } +#include <unistr.h> + /** * stringprep_utf8_to_ucs4: * @str: a UTF-8 encoded string @@ -1010,9 +1012,10 @@ stringprep_unichar_to_utf8 (uint32_t c, char *outbuf) * @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 @@ stringprep_unichar_to_utf8 (uint32_t c, char *outbuf) 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); } diff --git a/lib/strerror-idna.c b/lib/strerror-idna.c index 0163c7e..f1e94ec 100644 --- a/lib/strerror-idna.c +++ b/lib/strerror-idna.c @@ -115,7 +115,7 @@ idna_strerror (Idna_rc rc) break; case IDNA_ICONV_ERROR: - p = _("System iconv failed"); + p = _("Could not convert string in locale encoding"); break; case IDNA_MALLOC_ERROR: diff --git a/lib/strerror-stringprep.c b/lib/strerror-stringprep.c index f3a8c9c..f53fbbd 100644 --- 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 @@ stringprep_strerror (Stringprep_rc rc) 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)"); diff --git a/lib/stringprep.c b/lib/stringprep.c index fc17c5c..8ff28e6 100644 --- a/lib/stringprep.c +++ b/lib/stringprep.c @@ -380,6 +380,8 @@ stringprep (char *in, 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 @@ stringprep (char *in, 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 @@ stringprep_profile (const char *in, * 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 diff --git a/lib/stringprep.h b/lib/stringprep.h index 513483f..309d01e 100644 --- a/lib/stringprep.h +++ b/lib/stringprep.h @@ -51,7 +51,7 @@ extern "C" { # endif -# define STRINGPREP_VERSION "1.30" +# define STRINGPREP_VERSION "1.31" /* Error codes. */ typedef enum @@ -68,6 +68,7 @@ extern "C" 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 diff --git a/tests/Makefile.am b/tests/Makefile.am index 0f491ec..0f890fe 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -27,7 +27,7 @@ libutils_a_SOURCES = utils.h utils.c ctests = tst_stringprep tst_punycode tst_idna tst_idna2 tst_idna3 \ tst_idna4 tst_nfkc tst_pr29 tst_strerror tst_toutf8 \ - tst_symbols + tst_symbols tst_badutf8 if TLD ctests += tst_tld endif @@ -37,4 +37,4 @@ EXTRA_DIST = libidn.supp TESTS = $(ctests) check_PROGRAMS = $(ctests) -TESTS_ENVIRONMENT = $(VALGRIND) +LOG_COMPILER = $(VALGRIND) diff --git a/tests/tst_idna4.c b/tests/tst_badutf8.c similarity index 64% copy from tests/tst_idna4.c copy to tests/tst_badutf8.c index 72d676f..2feb099 100644 --- a/tests/tst_idna4.c +++ b/tests/tst_badutf8.c @@ -1,5 +1,5 @@ -/* tst_idna4.c --- Self tests for memory leak regression. - * Copyright (C) 2011-2015 Simon Josefsson +/* tst_badutf8.c --- Self tests for malformed UTF-8 regressions. + * Copyright (C) 2015 Simon Josefsson * * This file is part of GNU Libidn. * @@ -35,18 +35,16 @@ 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; - char *out = NULL; - rc = idna_to_ascii_8z("search...", &out, 0); - if (rc != IDNA_INVALID_LENGTH) - fail ("unexpected rc %d\n", rc); + rc = idna_to_ascii_8z (badutf8, &s, 0); + free (badutf8); + if (rc != IDNA_ICONV_ERROR) + fail ("rc %d\n", rc); - rc = idna_to_ascii_8z("google.com................point", &out, 0); - if (rc != IDNA_INVALID_LENGTH) - fail ("unexpected rc %d\n", rc); - - rc = idna_to_ascii_8z("Loading...°°°°°°°°°°°°°°]", &out, 0); - if (rc != IDNA_INVALID_LENGTH) - fail ("unexpected rc %d\n", rc); + idn_free (s); } diff --git a/tests/tst_idna4.c b/tests/tst_idna4.c index 72d676f..f5550c0 100644 --- a/tests/tst_idna4.c +++ b/tests/tst_idna4.c @@ -46,7 +46,9 @@ doit (void) 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 --git a/tests/tst_stringprep.c b/tests/tst_stringprep.c index 1856d35..c352dd9 100644 --- a/tests/tst_stringprep.c +++ b/tests/tst_stringprep.c @@ -100,7 +100,8 @@ const struct stringprep strprep[] = { "\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 @@ doit (void) 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 @@ doit (void) escapeprint (x, strlen (x)); hexprint (x, strlen (x)); } + continue; } free (x); } + rc = stringprep_profile (strprep[i].in, &p, strprep[i].profile ? strprep[i].profile : hooks/post-receive -- GNU libidn
_______________________________________________ Libidn-commit mailing list [email protected] https://lists.gnu.org/mailman/listinfo/libidn-commit
