summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Sperling <stsp@cvs.openbsd.org>2010-08-03 11:23:38 +0000
committerStefan Sperling <stsp@cvs.openbsd.org>2010-08-03 11:23:38 +0000
commit0054e3c6e28f0db5a6e6dd1605f975a166e19aa8 (patch)
tree125b60668866ae0afe9d9c31f1d1ac4000fa2e05
parent7d3746f8a11471a3fbd594bb2fb66d587ecedf4c (diff)
When the target pointer 'pwcs' passed to mbsrtowcs() is NULL, mbsrtowcs()
is supposed to ignore the 'n' parameter and return the number of wide characters needed to represent the given multi-byte character sequence. However, in the special case where 'pwcs' is NULL and 'n' is zero, our mbsrtowcs() implementation for single-byte locales mistakenly returned zero. Before the UTF-8 locale was added, this bug was invisible to callers of mbstowcs() because mbstowcs() handled this special case itself. But our new mbstowcs() implementation simply forwards to the locale-specific mbsrtowcs() implementation and expects it to do the right thing. The "awesome" window manager's "Run:" command prompt uses mbstowcs() to measure how many (possibly multi-byte) characters a user has typed, and due to this bug would always be tricked into thinking the user had entered zero characters when a single-byte locale was used. Found after prodding by dcoppa. ok deraadt sthen espie
-rw-r--r--lib/libc/citrus/citrus_none.c24
1 files changed, 9 insertions, 15 deletions
diff --git a/lib/libc/citrus/citrus_none.c b/lib/libc/citrus/citrus_none.c
index b7b039ee773..e0dfafdecd0 100644
--- a/lib/libc/citrus/citrus_none.c
+++ b/lib/libc/citrus/citrus_none.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: citrus_none.c,v 1.1 2010/07/27 16:59:03 stsp Exp $ */
+/* $OpenBSD: citrus_none.c,v 1.2 2010/08/03 11:23:37 stsp Exp $ */
/* $NetBSD: citrus_none.c,v 1.18 2008/06/14 16:01:07 tnozaki Exp $ */
/*-
@@ -83,20 +83,14 @@ _citrus_none_ctype_mbsrtowcs(wchar_t * __restrict pwcs,
if (!s || !*s)
return 0;
- if (n != 0) {
- if (pwcs != NULL) {
- do {
- if ((*pwcs++ = (wchar_t)(unsigned char)*(*s)++) == 0)
- break;
- count++;
- } while (--n != 0);
- } else {
- do {
- if (((wchar_t)*(*s)++) == 0)
- break;
- count++;
- } while (--n != 0);
- }
+ if (pwcs == NULL)
+ return strlen(*s);
+
+ while (n > 0) {
+ if ((*pwcs++ = (wchar_t)(unsigned char)*(*s)++) == 0)
+ break;
+ count++;
+ n--;
}
return count;