[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] mbrlen, mbrtowc: fix bug with empty input
From: |
Paul Eggert |
Subject: |
[PATCH] mbrlen, mbrtowc: fix bug with empty input |
Date: |
Fri, 16 May 2014 13:56:00 -0700 |
* 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.
---
ChangeLog | 10 ++++++++++
lib/mbrtowc.c | 7 ++++++-
m4/mbrlen.m4 | 36 +++++++++++++++++++++++++++++++++++-
m4/mbrtowc.m4 | 46 +++++++++++++++++++++++++++++++++++++++++++++-
tests/test-mbrtowc.c | 5 +----
5 files changed, 97 insertions(+), 7 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 2e59362..39e4c10 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2014-05-16 Paul Eggert <address@hidden>
+
+ 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 <address@hidden>
doc: document mbrtowc and mbrlen problem with empty input
diff --git a/lib/mbrtowc.c b/lib/mbrtowc.c
index 9415fd7..5743f43 100644
--- a/lib/mbrtowc.c
+++ b/lib/mbrtowc.c
@@ -328,7 +328,7 @@ mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t
*ps)
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;
@@ -337,6 +337,11 @@ rpl_mbrtowc (wchar_t *pwc, const char *s, size_t n,
mbstate_t *ps)
}
# endif
+# if MBRTOWC_EMPTY_INPUT_BUG
+ if (n == 0)
+ return (size_t) -2;
+# endif
+
# if MBRTOWC_RETVAL_BUG
{
static mbstate_t internal_state;
diff --git a/m4/mbrlen.m4 b/m4/mbrlen.m4
index 57db29a..10df9b3 100644
--- a/m4/mbrlen.m4
+++ b/m4/mbrlen.m4
@@ -1,4 +1,4 @@
-# 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,
@@ -227,6 +227,40 @@ int main ()
])
])
+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], [
:
diff --git a/m4/mbrtowc.m4 b/m4/mbrtowc.m4
index a9d1570..47ab2f4 100644
--- a/m4/mbrtowc.m4
+++ b/m4/mbrtowc.m4
@@ -1,4 +1,4 @@
-# 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
@@ -39,6 +39,7 @@ AC_DEFUN([gl_FUNC_MBRTOWC],
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],
@@ -67,6 +68,14 @@ AC_DEFUN([gl_FUNC_MBRTOWC],
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
])
@@ -533,6 +542,41 @@ int main ()
])
])
+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], [
:
diff --git a/tests/test-mbrtowc.c b/tests/test-mbrtowc.c
index f64af4f..e8cdea0 100644
--- a/tests/test-mbrtowc.c
+++ b/tests/test-mbrtowc.c
@@ -46,10 +46,7 @@ main (int argc, char *argv[])
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));
}
--
1.9.0
- [PATCH] mbrlen, mbrtowc: fix bug with empty input,
Paul Eggert <=