summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruno Haible <bruno@clisp.org>2023-03-30 23:12:50 +0200
committerBruno Haible <bruno@clisp.org>2023-03-30 23:12:50 +0200
commit63861afac8004becc3907993cd16b59a5bca5195 (patch)
tree6247e3ab6379e50c0ab1aa83e8aae1d22c0dd5b6
parent1ab07af585358746e7fcc0176ab1716db31ca902 (diff)
downloadgnulib-63861afac8004becc3907993cd16b59a5bca5195.tar.gz
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.
-rw-r--r--ChangeLog14
-rw-r--r--doc/posix-functions/mbsrtowcs.texi4
-rw-r--r--m4/mbsrtowcs.m49
-rw-r--r--modules/mbsrtowcs1
-rw-r--r--modules/mbsrtowcs-tests5
-rw-r--r--tests/test-mbsrtowcs.c66
-rwxr-xr-xtests/test-mbsrtowcs5.sh9
7 files changed, 106 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index fba5f444f6..2fe1679061 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,19 @@
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.
* tests/test-mbrlen1.sh: New file, based on tests/test-mbrtowc1.sh.
* tests/test-mbrlen2.sh: New file, based on tests/test-mbrtowc2.sh.
diff --git a/doc/posix-functions/mbsrtowcs.texi b/doc/posix-functions/mbsrtowcs.texi
index f27ec0f616..28c450ddfb 100644
--- a/doc/posix-functions/mbsrtowcs.texi
+++ b/doc/posix-functions/mbsrtowcs.texi
@@ -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
diff --git a/m4/mbsrtowcs.m4 b/m4/mbsrtowcs.m4
index f95af621dd..4f2e88c5a0 100644
--- a/m4/mbsrtowcs.m4
+++ b/m4/mbsrtowcs.m4
@@ -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
])
diff --git a/modules/mbsrtowcs b/modules/mbsrtowcs
index 4b5fa61cf4..70e7d0c36f 100644
--- a/modules/mbsrtowcs
+++ b/modules/mbsrtowcs
@@ -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
diff --git a/modules/mbsrtowcs-tests b/modules/mbsrtowcs-tests
index d7301057d9..36050c670d 100644
--- a/modules/mbsrtowcs-tests
+++ b/modules/mbsrtowcs-tests
@@ -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@' \
diff --git a/tests/test-mbsrtowcs.c b/tests/test-mbsrtowcs.c
index d511690db9..7e8cc4a1ea 100644
--- a/tests/test-mbsrtowcs.c
+++ b/tests/test-mbsrtowcs.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 = 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
index 0000000000..96734a73bd
--- /dev/null
+++ b/tests/test-mbsrtowcs5.sh
@@ -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