On 30 Dec 2009, at 19:24, Greg Ercolano wrote:

>>     [..]it seems [the Microsoft] _snprintf() doesn't follow the  
>> C99 spec,
>>     so the function apparently works incorrectly [or at least  
>> unexpectedly
>>     if you're used to the C99 spec version) on the very
>>     boundary conditions it's supposed to protect us from. eg:
>
>    The following is a possibly clearer example of the problem; test  
> code:
>
> ---- snip
> #include <stdio.h>
> #include <string.h>
> #ifdef _WIN32
> #define snprintf _snprintf
> #endif /*MICROSOFT*/
> int main() {
>     int ret;
>     char ss[20];
>     strcpy(ss, "12345678XY");         // 'X' and 'Y' should never be  
> touched or seen in the following
>     ret=snprintf(ss, 8, "1234%s","56");     fprintf(stderr,"RET=%d,  
> SS='%s': TEST RESULT: %s\n", ret, ss, (ss[8]=='X'&&ss[9] 
> =='Y'&&strlen(ss)<8)?"OK":"FAIL!");
>     ret=snprintf(ss, 8, "1234%s","567");    fprintf(stderr,"RET=%d,  
> SS='%s': TEST RESULT: %s\n", ret, ss, (ss[8]=='X'&&ss[9] 
> =='Y'&&strlen(ss)<8)?"OK":"FAIL!");
>     ret=snprintf(ss, 8, "1234%s","5678");   fprintf(stderr,"RET=%d,  
> SS='%s': TEST RESULT: %s\n", ret, ss, (ss[8]=='X'&&ss[9] 
> =='Y'&&strlen(ss)<8)?"OK":"FAIL!");
>     ret=snprintf(ss, 8, "1234%s","56789");  fprintf(stderr,"RET=%d,  
> SS='%s': TEST RESULT: %s\n", ret, ss, (ss[8]=='X'&&ss[9] 
> =='Y'&&strlen(ss)<8)?"OK":"FAIL!");
>     ret=snprintf(ss, 8, "1234%s","567890"); fprintf(stderr,"RET=%d,  
> SS='%s': TEST RESULT: %s\n", ret, ss, (ss[8]=='X'&&ss[9] 
> =='Y'&&strlen(ss)<8)?"OK":"FAIL!");
>     return(0);
> }
> ---- snip

>       Output on Win32:
>
> RET=6, SS='123456': TEST RESULT: OK
> RET=7, SS='1234567': TEST RESULT: OK
> RET=8, SS='12345678XY': TEST RESULT: FAIL!    <-- Yikes --  
> unterminated; the 'XY' shouldn't show up
> RET=-1, SS='12345678XY': TEST RESULT: FAIL!   <-- ditto
> RET=-1, SS='12345678XY': TEST RESULT: FAIL!
>
>       Solution on win32 is to change _snprintf() to _snprintf_s()
>       with the _TRUNCATE macro as the third argument. But there's no
>       clear way to use a macro shortcut to do this (since this is a
>       varargs function), so a cross platform solution is tricky at best.

Just tested this on Vista with mingw, and it fails exactly as Greg's  
VS example fails (because mingw mainly just wraps the native system  
libs in general.)

However, the workaround of using _snprintf_s(...) doesn't look like  
it will fly either, since neither _snprintf_s nor the _TRUNCATE macro  
are defined in mingw...



_______________________________________________
fltk-dev mailing list
fltk-dev@easysw.com
http://lists.easysw.com/mailman/listinfo/fltk-dev

Reply via email to