summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog14
-rw-r--r--doc/posix-functions/mbsnrtowcs.texi4
-rw-r--r--m4/mbsnrtowcs.m49
-rw-r--r--modules/mbsnrtowcs1
-rw-r--r--modules/mbsnrtowcs-tests5
-rw-r--r--tests/test-mbsnrtowcs.c66
-rwxr-xr-xtests/test-mbsnrtowcs5.sh9
7 files changed, 106 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index 2fe1679061..4afba58a3c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,19 @@
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.
* m4/mbsrtowcs.m4 (gl_FUNC_MBSRTOWCS): Invoke gl_MBRTOWC_C_LOCALE. If
mbrtowc is buggy in the C locale, override also mbsrtowcs.
diff --git a/doc/posix-functions/mbsnrtowcs.texi b/doc/posix-functions/mbsnrtowcs.texi
index c6defd2c20..3a420c673a 100644
--- a/doc/posix-functions/mbsnrtowcs.texi
+++ b/doc/posix-functions/mbsnrtowcs.texi
@@ -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:
diff --git a/m4/mbsnrtowcs.m4 b/m4/mbsnrtowcs.m4
index 34dcf30e63..7cab5f79ed 100644
--- a/m4/mbsnrtowcs.m4
+++ b/m4/mbsnrtowcs.m4
@@ -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
])
diff --git a/modules/mbsnrtowcs b/modules/mbsnrtowcs
index 5b66cc2b8f..10260246ea 100644
--- a/modules/mbsnrtowcs
+++ b/modules/mbsnrtowcs
@@ -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
diff --git a/modules/mbsnrtowcs-tests b/modules/mbsnrtowcs-tests
index c7c528448f..7c5de260ba 100644
--- a/modules/mbsnrtowcs-tests
+++ b/modules/mbsnrtowcs-tests
@@ -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@' \
diff --git a/tests/test-mbsnrtowcs.c b/tests/test-mbsnrtowcs.c
index e3456b4e2b..2d0e6a7521 100644
--- a/tests/test-mbsnrtowcs.c
+++ b/tests/test-mbsnrtowcs.c
@@ -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
index 0000000000..b121fb1a69
--- /dev/null
+++ b/tests/test-mbsnrtowcs5.sh
@@ -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