bug-gnulib
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]