This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: strxfrm() returns an incorrect value on a short buffer


On 12/04/2016 07:07, Tony Cook wrote:
strxfrm() returns an incorrect value if you supply an output buffer
and that buffer is too short for the result.

With the code following:

#include <string.h>
#include <locale.h>
#include <stdio.h>

int main() {
   char xbuf[5] = "";
   char *lc = setlocale(LC_ALL, "en_AU.utf8");
   if (!lc) {
     perror("setlocale");
     return 1;
   }
   size_t sza = strxfrm(xbuf, "alphabet", sizeof(xbuf));
   printf("sz: %zd\n", sza);
   size_t szb = strxfrm(NULL, "alphabet", 0);
   printf("sz: %zd\n", szb);

   return 0;
}

On cygwin:

tony@phobos ~
$ gcc -ostrxfrmtest strxfrmtest.c

tony@phobos ~
$ ./strxfrmtest
sz: 5
sz: 20

tony@phobos ~
$ uname -a
CYGWIN_NT-6.1-WOW phobos 2.5.0(0.297/5/3) 2016-04-11 09:55 i686 Cygwin

On Linux:

tony@mars:~$ gcc -ostrxfrmtest strxfrmtest.c
tony@mars:~$ ./strxfrmtest
sz: 26
sz: 26
tony@mars:~$ uname -a
Linux mars 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt20-1+deb8u3 (2016-01-17) x86_64 GNU/Linux

 From looking at the source:

https://cygwin.com/git/gitweb.cgi?p=newlib-cygwin.git;a=blob;f=winsup/cygwin/nlsfuncs.cc;h=9dbd9b16d53094c60aa835756c967c054ced8e62;hb=HEAD#l1286

It appears that strxfrm() is just returning the size of the output
buffer on an overflow error rather than calling LCMapString() again
with cchDest set to zero to get the required buffer length that
strxfrm() is meant to return on a short buffer.

This came out of the discussion in:

https://rt.perl.org/Ticket/Display.html?id=121734

(not that I've reproduced that issue.)

Tony


You should check the error output.
Both cygwin and Linux seem IMHO to report an insufficient buffer
and s1 is not guaranteed.

http://pubs.opengroup.org/onlinepubs/9699919799/functions/strxfrm.html

Upon successful completion, strxfrm() [CX] [Option Start] and strxfrm_l() [Option End] shall return the length of the transformed string (not including the terminating NUL character). If the value returned is n or more, the contents of the array pointed to by s1 are unspecified.

On error, strxfrm() [CX] [Option Start] and strxfrm_l() [Option End] may set errno but no return value is reserved to indicate an error.


--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]