> [..]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 Linux:
RET=6, SS='123456': TEST RESULT: OK
RET=7, SS='1234567': TEST RESULT: OK
RET=8, SS='1234567': TEST RESULT: OK <-- remains truncated even
though input len >= 8
RET=9, SS='1234567': TEST RESULT: OK <-- ditto
RET=10, SS='1234567': TEST RESULT: OK
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.
_______________________________________________
fltk-dev mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk-dev