crt: fix return value of mbrlen and mbrtowc functions with DBCS code pages
CRT's mbrlen and mbrtowc functions return incorrect value if
previous call to either of them has returned (size_t)-2 when
converting using DBCS code page.
Previously, mingw-w64's implementation of those functions was
implementing the same buggy behavior for compatibility with CRT.
This commit fixes return value of mbrlen and mbrtowc functions.
Tests for mbrlen and mbrtowc functions are updated accordingly.
Signed-off-by: Kirill Makurin <maiddaisuki@outlook.com>
Signed-off-by: Martin Storsjö <martin@martin.st>
diff --git a/mingw-w64-crt/misc/mbrtowc.c b/mingw-w64-crt/misc/mbrtowc.c
index be5830a..75c9f98 100644
--- a/mingw-w64-crt/misc/mbrtowc.c
+++ b/mingw-w64-crt/misc/mbrtowc.c
@@ -68,8 +68,12 @@
/* Length of potential multibyte character */
int length = 1;
+ /* Number of bytes consumed from `mbs` */
+ int bytes_consumed = 0;
+
if (conversion_state.bytes[0]) {
conversion_state.bytes[1] = mbs[0];
+ bytes_consumed = 1;
length = 2;
} else if (mb_cur_max == 2 && isleadbyte (mbs[0])) {
conversion_state.bytes[0] = mbs[0];
@@ -81,9 +85,11 @@
}
conversion_state.bytes[1] = mbs[1];
+ bytes_consumed = 2;
length = 2;
} else {
conversion_state.bytes[0] = mbs[0];
+ bytes_consumed = 1;
}
/* Store terminating '\0' */
@@ -116,7 +122,7 @@
*state = 0;
}
- return length;
+ return bytes_consumed;
eilseq:
errno = EILSEQ;
diff --git a/mingw-w64-crt/testcases/t_mbrlen.c b/mingw-w64-crt/testcases/t_mbrlen.c
index 4d297e3..2e723a1 100644
--- a/mingw-w64-crt/testcases/t_mbrlen.c
+++ b/mingw-w64-crt/testcases/t_mbrlen.c
@@ -118,12 +118,9 @@
/**
* Complete multibyte character
- *
- * NOTE: return value does not conform to ISO C and POSIX.
- * This behavior is implemented for consistency with CRT.
*/
- assert (mbrlen ((char *) Multibyte + 1, 1, &state) == 2);
+ assert (mbrlen ((char *) Multibyte + 1, 1, &state) == 1);
assert (mbsinit (&state));
assert (errno == 0);
diff --git a/mingw-w64-crt/testcases/t_mbrtowc.c b/mingw-w64-crt/testcases/t_mbrtowc.c
index 1b94207..cb11b14 100644
--- a/mingw-w64-crt/testcases/t_mbrtowc.c
+++ b/mingw-w64-crt/testcases/t_mbrtowc.c
@@ -136,13 +136,10 @@
/**
* Complete multibyte character
- *
- * NOTE: return value does not conform to ISO C and POSIX.
- * This behavior is implemented for consistency with CRT.
*/
wc = WEOF;
- assert (mbrtowc (&wc, (char *) Multibyte + 1, 1, &state) == 2);
+ assert (mbrtowc (&wc, (char *) Multibyte + 1, 1, &state) == 1);
assert (wc != WEOF);
assert (mbsinit (&state));
assert (errno == 0);