]> Savannah Git Hosting - gnulib.git/commitdiff
mbsrtowcs: Fix behaviour in the C locale.
authorBruno Haible <bruno@clisp.org>
Thu, 30 Mar 2023 21:12:50 +0000 (23:12 +0200)
committerBruno Haible <bruno@clisp.org>
Thu, 30 Mar 2023 21:12:50 +0000 (23:12 +0200)
* m4/mbsrtowcs.m4 (gl_FUNC_MBSRTOWCS): Invoke gl_MBRTOWC_C_LOCALE. If
mbrtowc is buggy in the C locale, override also mbsrtowcs.
* modules/mbsrtowcs (Files): Add m4/mbrtowc.m4.
* tests/test-mbsrtowcs.c (main): Add a test of the C locale, based on
tests/test-mbrtowc.c.
* tests/test-mbsrtowcs5.sh: New file, based on tests/test-mbrtowc5.sh.
* modules/mbsrtowcs-tests (Files): Add it.
(Makefile.am): Test it.
* doc/posix-functions/mbsrtowcs.texi: Mention the C locale behaviour
bug.

ChangeLog
doc/posix-functions/mbsrtowcs.texi
m4/mbsrtowcs.m4
modules/mbsrtowcs
modules/mbsrtowcs-tests
tests/test-mbsrtowcs.c
tests/test-mbsrtowcs5.sh [new file with mode: 0755]

index fba5f444f6ea42ec9200f02336778364304e1f6c..2fe167906103180cee426582faedf350e8010b04 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2023-03-30  Bruno Haible  <bruno@clisp.org>
+
+       mbsrtowcs: Fix behaviour in the C locale.
+       * m4/mbsrtowcs.m4 (gl_FUNC_MBSRTOWCS): Invoke gl_MBRTOWC_C_LOCALE. If
+       mbrtowc is buggy in the C locale, override also mbsrtowcs.
+       * modules/mbsrtowcs (Files): Add m4/mbrtowc.m4.
+       * tests/test-mbsrtowcs.c (main): Add a test of the C locale, based on
+       tests/test-mbrtowc.c.
+       * tests/test-mbsrtowcs5.sh: New file, based on tests/test-mbrtowc5.sh.
+       * modules/mbsrtowcs-tests (Files): Add it.
+       (Makefile.am): Test it.
+       * doc/posix-functions/mbsrtowcs.texi: Mention the C locale behaviour
+       bug.
+
 2023-03-30  Bruno Haible  <bruno@clisp.org>
 
        mbrlen: Add tests.
index f27ec0f6163f480c0b7672c03fc41bf60ea08616..28c450ddfb63aeef261e1353f98d9ab888c5bc9f 100644 (file)
@@ -15,6 +15,10 @@ Minix 3.1.8, HP-UX 11.00, IRIX 6.5, mingw.
 This function does not work on some platforms:
 HP-UX 11, Solaris 11 2010-11.
 @item
+In the C or POSIX locales, this function can return @code{(size_t) -1}
+and set @code{errno} to @code{EILSEQ}:
+glibc 2.35.
+@item
 This function does not work when the first argument is NULL on some platforms:
 mingw.
 @end itemize
index f95af621ddf188e4a7addc9ddef12e79bd2f26d9..4f2e88c5a0b898576db241862658642fa84849d8 100644 (file)
@@ -1,4 +1,4 @@
-# mbsrtowcs.m4 serial 14
+# mbsrtowcs.m4 serial 15
 dnl Copyright (C) 2008-2023 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -32,6 +32,13 @@ AC_DEFUN([gl_FUNC_MBSRTOWCS],
         *yes) ;;
         *) REPLACE_MBSRTOWCS=1 ;;
       esac
+      if test $REPLACE_MBSRTOWCS = 0; then
+        gl_MBRTOWC_C_LOCALE
+        case "$gl_cv_func_mbrtowc_C_locale_sans_EILSEQ" in
+          *yes) ;;
+          *) REPLACE_MBSRTOWCS=1 ;;
+        esac
+      fi
     fi
   fi
 ])
index 4b5fa61cf4982c132958060e4b4d5ec27bd5c814..70e7d0c36fb6bdd0601d1a742d3c002ef1a14016 100644 (file)
@@ -7,6 +7,7 @@ lib/mbsrtowcs-impl.h
 lib/mbsrtowcs-state.c
 m4/mbsrtowcs.m4
 m4/mbstate_t.m4
+m4/mbrtowc.m4
 m4/locale-fr.m4
 m4/locale-ja.m4
 m4/locale-zh.m4
index d7301057d9376d7023c17fe417d53c90671fe472..36050c670d6473572d4c96484c3f4db5b8324ca5 100644 (file)
@@ -3,6 +3,7 @@ tests/test-mbsrtowcs1.sh
 tests/test-mbsrtowcs2.sh
 tests/test-mbsrtowcs3.sh
 tests/test-mbsrtowcs4.sh
+tests/test-mbsrtowcs5.sh
 tests/test-mbsrtowcs.c
 tests/signature.h
 tests/macros.h
@@ -24,7 +25,9 @@ gt_LOCALE_JA
 gt_LOCALE_ZH_CN
 
 Makefile.am:
-TESTS += test-mbsrtowcs1.sh test-mbsrtowcs2.sh test-mbsrtowcs3.sh test-mbsrtowcs4.sh
+TESTS += \
+  test-mbsrtowcs1.sh test-mbsrtowcs2.sh test-mbsrtowcs3.sh test-mbsrtowcs4.sh \
+  test-mbsrtowcs5.sh
 TESTS_ENVIRONMENT += \
   LOCALE_FR='@LOCALE_FR@' \
   LOCALE_FR_UTF8='@LOCALE_FR_UTF8@' \
index d511690db9061c2f36b90bb613cf154d0f8a369a..7e8cc4a1eacb82705ddb9539b282301845f7fb88 100644 (file)
@@ -281,6 +281,72 @@ main (int argc, char *argv[])
               }
               break;
 
+            case '5':
+              /* C or POSIX locale.  */
+              {
+                char input[] = "n/a";
+                memset (&state, '\0', sizeof (mbstate_t));
+
+                src = input;
+                temp_state = state;
+                ret = mbsrtowcs (NULL, &src, unlimited ? BUFSIZE : 1, &temp_state);
+                ASSERT (ret == 3);
+                ASSERT (src == input);
+                ASSERT (mbsinit (&state));
+
+                src = input;
+                ret = mbsrtowcs (buf, &src, unlimited ? BUFSIZE : 1, &state);
+                ASSERT (ret == (unlimited ? 3 : 1));
+                ASSERT (src == (unlimited ? NULL : input + 1));
+                ASSERT (buf[0] == 'n');
+                if (unlimited)
+                  {
+                    ASSERT (buf[1] == '/');
+                    ASSERT (buf[2] == 'a');
+                    ASSERT (buf[3] == 0);
+                    ASSERT (buf[4] == (wchar_t) 0xBADFACE);
+                  }
+                else
+                  ASSERT (buf[1] == (wchar_t) 0xBADFACE);
+                ASSERT (mbsinit (&state));
+              }
+              {
+                int c;
+                char input[2];
+
+                memset (&state, '\0', sizeof (mbstate_t));
+                for (c = 0; c < 0x100; c++)
+                  if (c != 0)
+                    {
+                      /* We are testing all nonnull bytes.  */
+                      input[0] = c;
+                      input[1] = '\0';
+
+                      src = input;
+                      ret = mbsrtowcs (NULL, &src, unlimited ? BUFSIZE : 1, &state);
+                      ASSERT (ret == 1);
+                      ASSERT (src == input);
+                      ASSERT (mbsinit (&state));
+
+                      buf[0] = buf[1] = (wchar_t) 0xBADFACE;
+                      src = input;
+                      ret = mbsrtowcs (buf, &src, unlimited ? BUFSIZE : 1, &state);
+                      /* POSIX:2018 says: "In the POSIX locale an [EILSEQ] error
+                         cannot occur since all byte values are valid characters."  */
+                      ASSERT (ret == 1);
+                      ASSERT (src == (unlimited ? NULL : input + 1));
+                      if (c < 0x80)
+                        /* c is an ASCII character.  */
+                        ASSERT (buf[0] == c);
+                      else
+                        /* On most platforms, the bytes 0x80..0xFF map to U+0080..U+00FF.
+                           But on musl libc, the bytes 0x80..0xFF map to U+DF80..U+DFFF.  */
+                        ASSERT (buf[0] == (btowc (c) == 0xDF00 + c ? btowc (c) : c));
+                      ASSERT (mbsinit (&state));
+                    }
+              }
+              break;
+
             default:
               return 1;
             }
diff --git a/tests/test-mbsrtowcs5.sh b/tests/test-mbsrtowcs5.sh
new file mode 100755 (executable)
index 0000000..96734a7
--- /dev/null
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+# Test whether the POSIX locale has encoding errors.
+LC_ALL=C \
+${CHECKER} ./test-mbsrtowcs${EXEEXT} 5 || exit 1
+LC_ALL=POSIX \
+${CHECKER} ./test-mbsrtowcs${EXEEXT} 5 || exit 1
+
+exit 0