| Summary: | wcstombs(), mbstowcs() not complying with standard | ||||||
|---|---|---|---|---|---|---|---|
| Product: | Base System | Reporter: | mikko <mikko> | ||||
| Component: | standards | Assignee: | Tim Robbins <tjr> | ||||
| Status: | Closed FIXED | ||||||
| Severity: | Affects Only Me | ||||||
| Priority: | Normal | ||||||
| Version: | 5.0-CURRENT | ||||||
| Hardware: | Any | ||||||
| OS: | Any | ||||||
| Attachments: |
|
||||||
> ...
> >Synopsis: wcstombs(), mbstowcs() not complying with standard
> ...
> >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.
This is a nonstandard extension. It is not present in C89 or in at
least the n869 draft of C99.
Bruce
<whine> But everybody else has it... </whine> Seriously, though: I have not been able to find *any* other implementation that does not support this behaviour (HP-UX, AIX, Irix, Solaris and Linux/RH6.1). They must have gotten the idea *somewhere*... I wouldn't even have noticed had not the stuff I was porting started to mysteriously fail. /Mikko On Thu, 30 Mar 2000, [ISO-8859-1] Mikko Ty=F6l=E4j=E4rvi wrote:
> <whine>
> But everybody else has it...
> </whine>
>=20
> Seriously, though: I have not been able to find *any* other
> implementation that does not support this behaviour (HP-UX, AIX, Irix,
> Solaris and Linux/RH6.1). They must have gotten the idea *somewhere*...
It doesn't seem to be in glibc-2.1.1 either.
Bruce
On Fri, 31 Mar 2000, Bruce Evans wrote: > On Thu, 30 Mar 2000, [ISO-8859-1] Mikko Työläjärvi wrote: > > > <whine> > > But everybody else has it... > > </whine> > > > > Seriously, though: I have not been able to find *any* other > > implementation that does not support this behaviour (HP-UX, AIX, Irix, > > Solaris and Linux/RH6.1). They must have gotten the idea *somewhere*... > > It doesn't seem to be in glibc-2.1.1 either. Oh, it is there alright, but not documented in the info files (RH must be rolling their own man-pages?). Follow "stdlib/wcstombs.c" to "wcsmbs/wcsrtombs.c", search for "NULL special". No mention of why they do it, though. MSVC++ 6.0 does it too (might be a hint where it comes from :-( ). Finally, I did find another system that does not handle the NULL case, according to its documentation at least: DEC (i.e. Compaq whatever). Never mind. /Mikko Mikko Työläjärvi_______________________________________mikko@rsasecurity.com RSA Security DEC (Compaq) Tru64 UNIX v. 4.0 D+ supports passing NULL in to find the length required. Just to let you guys know. Daniel Responsible Changed From-To: freebsd-bugs->freebsd-standards SUS issue. Responsible Changed From-To: freebsd-standards->tjr It looks like POSIX.1-2001 standardized this extention. Over to tjr. State Changed From-To: open->patched This XSI extension has been implemented in -CURRENT, I'll probably MFC it along with other recent wide char. changes for 4.8. State Changed From-To: patched->closed Fixed in -stable. |
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 <http://www.opengroup.org/onlinepubs/007908799/xsh/mbstowcs.html> "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] 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): How-To-Repeat: #include <stdlib.h> #include <locale.h> 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); }