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

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

index 2fe167906103180cee426582faedf350e8010b04..4afba58a3cf7bddbe0b2832b498866e8da029fc6 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2023-03-30  Bruno Haible  <bruno@clisp.org>
+
+       mbsnrtowcs: Fix behaviour in the C locale.
+       * m4/mbsnrtowcs.m4 (gl_FUNC_MBSNRTOWCS): Invoke gl_MBRTOWC_C_LOCALE. If
+       mbrtowc is buggy in the C locale, override also mbsnrtowcs.
+       * modules/mbsnrtowcs (Files): Add m4/mbrtowc.m4.
+       * tests/test-mbsnrtowcs.c (main): Add a test of the C locale, based on
+       tests/test-mbsrtowcs.c.
+       * tests/test-mbsnrtowcs5.sh: New file, based on tests/test-mbrtowc5.sh.
+       * modules/mbsnrtowcs-tests (Files): Add it.
+       (Makefile.am): Test it.
+       * doc/posix-functions/mbsnrtowcs.texi: Mention the C locale behaviour
+       bug.
+
 2023-03-30  Bruno Haible  <bruno@clisp.org>
 
        mbsrtowcs: Fix behaviour in the C locale.
index c6defd2c20663c9b5baa9b1e8441ba602d4398f7..3a420c673aec1885a6bd179645481325fd378d40 100644 (file)
@@ -14,6 +14,10 @@ FreeBSD 5.2.1, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, HP-UX 11, IRIX 6.5, Solaris
 @item
 This function produces invalid wide characters on some platforms:
 Solaris 11.4.
+@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.
 @end itemize
 
 Portability problems not fixed by Gnulib:
index 34dcf30e63fd1f1125b233668b428601b08ea257..7cab5f79ed31300a992056791afa379bae8c8b98 100644 (file)
@@ -1,4 +1,4 @@
-# mbsnrtowcs.m4 serial 8
+# mbsnrtowcs.m4 serial 9
 dnl Copyright (C) 2008, 2010-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,
@@ -29,6 +29,13 @@ AC_DEFUN([gl_FUNC_MBSNRTOWCS],
         *yes) ;;
         *) REPLACE_MBSNRTOWCS=1 ;;
       esac
+      if test $REPLACE_MBSNRTOWCS = 0; then
+        gl_MBRTOWC_C_LOCALE
+        case "$gl_cv_func_mbrtowc_C_locale_sans_EILSEQ" in
+          *yes) ;;
+          *) REPLACE_MBSNRTOWCS=1 ;;
+        esac
+      fi
     fi
   fi
 ])
index 5b66cc2b8f824bf9bb4b5a859a096494d9d90499..10260246ea8cf65b383fb68d95084d31df49c154 100644 (file)
@@ -7,6 +7,7 @@ lib/mbsnrtowcs-impl.h
 lib/mbsrtowcs-state.c
 m4/mbsnrtowcs.m4
 m4/mbstate_t.m4
+m4/mbrtowc.m4
 
 Depends-on:
 wchar
index c7c528448ffea02dae7fac5b6b62e94ab6dc57f3..7c5de260baf7cc40acfa59af3ebf1c745e4b1733 100644 (file)
@@ -3,6 +3,7 @@ tests/test-mbsnrtowcs1.sh
 tests/test-mbsnrtowcs2.sh
 tests/test-mbsnrtowcs3.sh
 tests/test-mbsnrtowcs4.sh
+tests/test-mbsnrtowcs5.sh
 tests/test-mbsnrtowcs.c
 tests/signature.h
 tests/macros.h
@@ -24,7 +25,9 @@ gt_LOCALE_JA
 gt_LOCALE_ZH_CN
 
 Makefile.am:
-TESTS += test-mbsnrtowcs1.sh test-mbsnrtowcs2.sh test-mbsnrtowcs3.sh test-mbsnrtowcs4.sh
+TESTS += \
+  test-mbsnrtowcs1.sh test-mbsnrtowcs2.sh test-mbsnrtowcs3.sh \
+  test-mbsnrtowcs4.sh test-mbsnrtowcs5.sh
 TESTS_ENVIRONMENT += \
   LOCALE_FR='@LOCALE_FR@' \
   LOCALE_FR_UTF8='@LOCALE_FR_UTF8@' \
index e3456b4e2b2c1f035469d3cbc69285c6403c546a..2d0e6a7521b7efa65dae9974f6c112627ef36d13 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 = mbsnrtowcs (NULL, &src, 4, unlimited ? BUFSIZE : 1, &temp_state);
+                ASSERT (ret == 3);
+                ASSERT (src == input);
+                ASSERT (mbsinit (&state));
+
+                src = input;
+                ret = mbsnrtowcs (buf, &src, 4, 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 = mbsnrtowcs (NULL, &src, 2, unlimited ? BUFSIZE : 1, &state);
+                      ASSERT (ret == 1);
+                      ASSERT (src == input);
+                      ASSERT (mbsinit (&state));
+
+                      buf[0] = buf[1] = (wchar_t) 0xBADFACE;
+                      src = input;
+                      ret = mbsnrtowcs (buf, &src, 2, 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-mbsnrtowcs5.sh b/tests/test-mbsnrtowcs5.sh
new file mode 100755 (executable)
index 0000000..b121fb1
--- /dev/null
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+# Test whether the POSIX locale has encoding errors.
+LC_ALL=C \
+${CHECKER} ./test-mbsnrtowcs${EXEEXT} 5 || exit 1
+LC_ALL=POSIX \
+${CHECKER} ./test-mbsnrtowcs${EXEEXT} 5 || exit 1
+
+exit 0