| [ Return to Bugs & Features | Post Text | Post File | Prev | Next ]
STR #2306
Application: | FLTK Library |
Status: | 5 - New |
Priority: | 3 - Moderate, e.g. unable to compile the software |
Scope: | 2 - Specific to an operating system |
Subsystem: | Core Library |
Summary: | fltk's use of snprintf() should be hardened -- recommend alternatives |
Version: | 1.4-feature |
Created By: | greg.ercolano |
Assigned To: | Unassigned |
Fix Version: | Unassigned |
Update Notification: | |
Trouble Report Files:
[ Post File ]
Trouble Report Comments:
[ Post Text ]
|
#1 | greg.ercolano 09:30 Jan 05, 2010 |
| The following is a redux of the thread on fltk.development: "Subject: snprintf() warnings under win32"
snprintf() is supposed to protect against overruns, but the behavior varies across platforms due to some problem/disagreement in the C standards. In short, depending on the platform, on a potential overrun, the resulting string can be left /without/ a NULL termination, which is often unexpected.
1) The GNU snprintf() does what one expects; on an overrun, leaves a NULL terminated string behind.
2) The VS snprintf() leaves an UN-TERMINATED string behind on an overrun. Some other compilers do this too. The microsoft compiler warns about use of this function, and we should heed it. Their docs recommend the use of _snprintf_s(), which has slightly different calling semantics than normal snprintf(), so a "simple" macro redefinition won't solve it.
What has been suggested:
a) Create a "complex" C99 compliant macro redefinition for VS builds: #ifdef WIN32 // might need to be more VS specific #define SNPRINTF(SS, CC, ...) _snprintf_s(SS, CC, _TRUNCATE, __VA_ARGS__) #else #define SNPRINTF snprintf // or some such #endif
b) Have FLTK use its own built-in fl_snprintf() code, which works on all platforms because the function is implemented completely as code (ie. is /not/ a wrapper function)
I'd definitely lean on the side of (b), since /for sure/ that will work consistently regardless of the platform.
However, fl_snprintf() does need some docs; it's unclear what it guarantees in the way of the returned string, and which format characters it supports. Empirical evidence shows it acts similarly to the GNU snprintf(); on overrun, leaves a terminated string.
Also: fl_snprintf() is only accessible to FLTK source code; the #include needed is flstring.h, which lives in the src dir, and NOT the "FL" dir. It might be handy to have this be a public global, and have it fully doxygen'ed.
Finally, fl_snprintf() needs to cite the source for the implemented code. If taken from GNU, we should know which version so potential bugs can be tracked. Or if one of our guys wrote it, who?
Attached "erco-snprintf-test.cxx" demonstrates if the local snprintf() function leaves an unterminated string or not.
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 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! RET=-1, SS='12345678XY': TEST RESULT: FAIL! | |
|
#2 | matt 13:33 Feb 26, 2010 |
| Can we just implement fl_snprintf using vsnprintf? It does exist on our three main platforms. Assuming that the MSWindows version has the same bug, we can simply replace the last character with a NUL character. | |
|
#3 | greg.ercolano 22:23 Nov 02, 2017 |
| Related: STR #3413. | |
[ Return to Bugs & Features | Post Text | Post File ]
|
| |