From owner-freebsd-bugs Thu Mar 30 9:50: 8 2000 Delivered-To: freebsd-bugs@freebsd.org Received: from freefall.freebsd.org (freefall.FreeBSD.ORG [204.216.27.21]) by hub.freebsd.org (Postfix) with ESMTP id 578BC37B84F for ; Thu, 30 Mar 2000 09:50:02 -0800 (PST) (envelope-from gnats@FreeBSD.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.9.3/8.9.2) id JAA62064; Thu, 30 Mar 2000 09:50:02 -0800 (PST) (envelope-from gnats@FreeBSD.org) Received: from karon.dynas.se (karon.dynas.se [192.71.43.4]) by hub.freebsd.org (Postfix) with SMTP id 6014537B664 for ; Thu, 30 Mar 2000 09:49:29 -0800 (PST) (envelope-from mikko@mt.dynas.se) Received: (qmail 7930 invoked from network); 30 Mar 2000 17:49:27 -0000 Received: from spirit.sto.dynas.se (HELO spirit.dynas.se) (172.16.1.10) by karon.sto.dynas.se with SMTP; 30 Mar 2000 17:49:27 -0000 Received: (qmail 2071 invoked from network); 30 Mar 2000 17:49:27 -0000 Received: from mt.dynas.se (172.16.1.144) by spirit.dynas.se with SMTP; 30 Mar 2000 17:49:27 -0000 Received: (from mikko@localhost) by mt.dynas.se (8.9.3/8.9.3) id TAA00862; Thu, 30 Mar 2000 19:03:47 +0200 (CEST) (envelope-from mikko) Message-Id: <200003301703.TAA00862@mt.dynas.se> Date: Thu, 30 Mar 2000 19:03:47 +0200 (CEST) From: mikko@dynas.se Reply-To: mikko@dynas.se To: FreeBSD-gnats-submit@freebsd.org X-Send-Pr-Version: 3.2 Subject: bin/17694: wcstombs() and mbstowcs() unable to handle NULL argument Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org >Number: 17694 >Category: bin >Synopsis: wcstombs(), mbstowcs() not complying with standard >Confidential: no >Severity: non-critical >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Thu Mar 30 09:50:01 PST 2000 >Closed-Date: >Last-Modified: >Originator: Mikko Työläjärvi >Release: FreeBSD 5.0-CURRENT i386 >Organization: >Environment: FreeBSD 4.0 and 5.x >Description: Looks like these two functions are supposed to be able to take a NULL destination pointer (the first one), in which case they should return the length required to do the actual copy. Stubled across this whilst porting code that made use of this feature to figure out how much memory to allocate. C.f. Solaris man-pages (e.g. at docs.sun.com) and "Single UNIX Specification" at "If s is a null pointer, wcstombs() returns the length required to convert the entire array regardless of the value of n, but no values are stored. function returns the number of bytes required for the character array." ["s" is the output string] and "If pwcs is a null pointer, mbstowcs() returns the length required to convert the entire array regardless of the value of n, but no values are stored." ["pwcs" is the output string] >How-To-Repeat: #include #include int main(int argc, char **argv) { int len; setlocale(LC_ALL, "C"); len = mbstowcs(NULL, "SE", 0); printf("len = %d (should be 2)\n", len); } >Fix: Suggested patch (actually somewhat tested with different arguments, but not in real multibyte locales, and relies on all flavours of sputrune being able to handle NULL args): --- ansi.c.org Thu Mar 30 18:45:34 2000 +++ ansi.c Thu Mar 30 18:44:57 2000 @@ -103,16 +103,22 @@ size_t n; { char const *e; + wchar_t wc; int cnt = 0; - if (!pwcs || !s) + if (!s) return (-1); - while (n-- > 0) { - *pwcs = sgetrune(s, MB_LEN_MAX, &e); - if (*pwcs == _INVALID_RUNE) + for (;;) { + wc = sgetrune(s, MB_LEN_MAX, &e); + if (wc == _INVALID_RUNE) return (-1); - if (*pwcs++ == 0) + if (pwcs) { + if (n-- <= 0) + break; + *pwcs++ = wc; + } + if (wc == 0) break; s = e; ++cnt; @@ -129,23 +135,27 @@ char *e; int cnt, nb; - if (!pwcs || !s || n > INT_MAX) + if (!pwcs || n > INT_MAX) return (-1); - nb = n; cnt = 0; - while (nb > 0) { + for (;;) { if (*pwcs == 0) { - *s = 0; + if (s) + *s = 0; break; } - if (!sputrune(*pwcs++, s, nb, &e)) + if (!(nb = sputrune(*pwcs++, s, nb, &e))) return (-1); /* encoding error */ if (!e) /* too long */ return (cnt); - cnt += e - s; - nb -= e - s; - s = e; + cnt += nb; + n -= nb; + if (s) { + if (n <= 0) + break; + s = e; + } } return (cnt); } >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message