* lib/mbrtowc.c (rpl_mbrtowc) [MBRTOWC_EMPTY_INPUT_BUG]: Fix the bug.
* m4/mbrlen.m4 (gl_MBRLEN_EMPTY_INPUT): New macro. It's not used,
so this is mainly for documentation.
* m4/mbrtowc.m4 (gl_MBRTOWC_EMPTY_INPUT): New macro.
(gl_FUNC_MBRTOWC): Use it.
* tests/test-mbrtowc.c (main): Test for the bug.
+2014-05-16 Paul Eggert <eggert@cs.ucla.edu>
+
+ mbrlen, mbrtowc: fix bug with empty input
+ * lib/mbrtowc.c (rpl_mbrtowc) [MBRTOWC_EMPTY_INPUT_BUG]: Fix the bug.
+ * m4/mbrlen.m4 (gl_MBRLEN_EMPTY_INPUT): New macro. It's not used,
+ so this is mainly for documentation.
+ * m4/mbrtowc.m4 (gl_MBRTOWC_EMPTY_INPUT): New macro.
+ (gl_FUNC_MBRTOWC): Use it.
+ * tests/test-mbrtowc.c (main): Test for the bug.
+
2014-05-15 Paul Eggert <eggert@cs.ucla.edu>
doc: document mbrtowc and mbrlen problem with empty input
size_t
rpl_mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)
{
-# if MBRTOWC_NULL_ARG2_BUG || MBRTOWC_RETVAL_BUG
+# if MBRTOWC_NULL_ARG2_BUG || MBRTOWC_RETVAL_BUG || MBRTOWC_EMPTY_INPUT_BUG
if (s == NULL)
{
pwc = NULL;
}
# endif
+# if MBRTOWC_EMPTY_INPUT_BUG
+ if (n == 0)
+ return (size_t) -2;
+# endif
+
# if MBRTOWC_RETVAL_BUG
{
static mbstate_t internal_state;
-# mbrlen.m4 serial 8
+# mbrlen.m4 serial 9
dnl Copyright (C) 2008, 2010-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 Test whether mbrlen returns the correct value on empty input.
+
+AC_DEFUN([gl_MBRLEN_EMPTY_INPUT],
+[
+ AC_REQUIRE([AC_PROG_CC])
+ AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+ AC_CACHE_CHECK([whether mbrlen works on empty input],
+ [gl_cv_func_mbrlen_empty_input],
+ [
+ dnl Initial guess, used when cross-compiling or when no suitable locale
+ dnl is present.
+changequote(,)dnl
+ case "$host_os" in
+ # Guess no on AIX and glibc systems.
+ aix* | *-gnu*)
+ gl_cv_func_mbrlen_empty_input="guessing no" ;;
+ *) gl_cv_func_mbrlen_empty_input="guessing yes" ;;
+ esac
+changequote([,])dnl
+ AC_RUN_IFELSE(
+ [AC_LANG_SOURCE([[
+ #include <wchar.h>
+ static mbstate_t mbs;
+ int
+ main (void)
+ {
+ return mbrlen ("", 0, &mbs) == (size_t) -2;
+ }]])],
+ [gl_cv_func_mbrlen_empty_input=no],
+ [gl_cv_func_mbrlen_empty_input=yes],
+ [:])
+ ])
+])
+
# Prerequisites of lib/mbrlen.c.
AC_DEFUN([gl_PREREQ_MBRLEN], [
:
-# mbrtowc.m4 serial 25
+# mbrtowc.m4 serial 26
dnl Copyright (C) 2001-2002, 2004-2005, 2008-2014 Free Software Foundation,
dnl Inc.
dnl This file is free software; the Free Software Foundation
gl_MBRTOWC_NULL_ARG2
gl_MBRTOWC_RETVAL
gl_MBRTOWC_NUL_RETVAL
+ gl_MBRTOWC_EMPTY_INPUT
case "$gl_cv_func_mbrtowc_null_arg1" in
*yes) ;;
*) AC_DEFINE([MBRTOWC_NULL_ARG1_BUG], [1],
REPLACE_MBRTOWC=1
;;
esac
+ case "$gl_cv_func_mbrtowc_empty_input" in
+ *yes) ;;
+ *) AC_DEFINE([MBRTOWC_EMPTY_INPUT_BUG], [1],
+ [Define if the mbrtowc function does not return (size_t) 2
+ for empty input.])
+ REPLACE_MBRTOWC=1
+ ;;
+ esac
fi
fi
])
])
])
+dnl Test whether mbrtowc returns the correct value on empty input.
+
+AC_DEFUN([gl_MBRTOWC_EMPTY_INPUT],
+[
+ AC_REQUIRE([AC_PROG_CC])
+ AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+ AC_CACHE_CHECK([whether mbrtowc works on empty input],
+ [gl_cv_func_mbrtowc_empty_input],
+ [
+ dnl Initial guess, used when cross-compiling or when no suitable locale
+ dnl is present.
+changequote(,)dnl
+ case "$host_os" in
+ # Guess no on AIX and glibc systems.
+ aix* | *-gnu*)
+ gl_cv_func_mbrtowc_empty_input="guessing no" ;;
+ *) gl_cv_func_mbrtowc_empty_input="guessing yes" ;;
+ esac
+changequote([,])dnl
+ AC_RUN_IFELSE(
+ [AC_LANG_SOURCE([[
+ #include <wchar.h>
+ static wchar_t wc;
+ static mbstate_t mbs;
+ int
+ main (void)
+ {
+ return mbrtowc (&wc, "", 0, &mbs) == (size_t) -2;
+ }]])],
+ [gl_cv_func_mbrtowc_empty_input=no],
+ [gl_cv_func_mbrtowc_empty_input=yes],
+ [:])
+ ])
+])
+
# Prerequisites of lib/mbrtowc.c.
AC_DEFUN([gl_PREREQ_MBRTOWC], [
:
memset (&state, '\0', sizeof (mbstate_t));
wc = (wchar_t) 0xBADFACE;
ret = mbrtowc (&wc, "x", 0, &state);
- /* gnulib's implementation returns (size_t)(-2).
- The AIX 5.1 implementation returns (size_t)(-1).
- glibc's implementation returns 0. */
- ASSERT (ret == (size_t)(-2) || ret == (size_t)(-1) || ret == 0);
+ ASSERT (ret == (size_t)(-2));
ASSERT (mbsinit (&state));
}