From: SourceForge.net <no...@so...> - 2004-12-14 02:08:42
|
Bugs item #1083721, was opened at 2004-12-11 21:10 Message generated for change (Comment added) made by william_g_davis You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=102435&aid=1083721&group_id=2435 Category: None Group: None Status: Open Resolution: None Priority: 5 Submitted By: William G. Davis (william_g_davis) Assigned to: Nobody/Anonymous (nobody) Summary: Broken snprintf(). Initial Comment: Hi guys. This was brough to my attention by a few people. It looks like snpritnf() is slightly broken. Here's a few examples along with the output they produced: -------------------- #include <stdio.h> int main(void) { char string[10]; char string2[10]; char string3[12]; int rv; rv = snprintf(string, sizeof(string), "%s", "longer than ten"); printf("[%s] (%d)\n", string, rv); rv = snprintf(string2, sizeof(string2), "%s", "shorter"); printf("[%s] (%d)\n", string2, rv); rv = snprintf( string3, sizeof(string3), "%s%d%s", "longer", 7777, "than ten" ); printf("[%s] (%d)\n", string3, rv); return 0; } -------------------- [longer tha] (-1) [shorter] (7) [longer7777th_²s] (-1) -------------------- Here's what C99 has to say about snprintf(): "Description "The snprintf function is equivalent to fprintf, except that the output is written into an array (specified by arguments) rather than to a stream. If n is zero, nothing is written, and s may be a null pointer. Otherwise, output characters beyond the n-1st are discarded rather than being written to the array, and a null character is written at the end of the characters actually written into the array. If copying takes place between objects that overlap, the behavior is undefined. "Returns "The snprintf function returns the number of characters that would have been written had n been sufficiently large, not counting the terminating null character, or a negative value if an encoding error occurred. Thus, the null-terminated output has been completely written if and only if the returned value is nonnegative and less than n." Which means that if the input is larger than the size argument, then only size-1 characters should be written, and regardless, a NULL terminator should *always* be written to the end of the destination buffer. Here's the version infomration: Configured with: ../gcc/configure --with-gcc --with-gnu-ld --with-gnu-as --host mingw32 --target=mingw32 --prefix=/mingw --enable-threads --disable-nls --enabl -languages=c,c++,f77,objc,ada,java --disable-win32-registry --disable-shared -- nable-sjlj-exceptions --enable-libgcj --disable-java-awt --without-x --enable-j va-gc=boehm --disable-libgcj-debug --enable-interpreter --enable-hash-synchroni ation Thread model: win32 gcc version 3.3.1 (mingw special 20030804-1) Thanks. ---------------------------------------------------------------------- >Comment By: William G. Davis (william_g_davis) Date: 2004-12-13 21:08 Message: Logged In: YES user_id=755462 The machine I checked (WinME) has version 6.1.8637.0 of MSVCRT.DLL, which I guess explains the different behavior. Would you guys be open to a different version of snprintf()? Google quickly turned up this implementation from a port of OpenSSH: http://darwinsource.opendarwin.org/10.3.6/OpenSSH-42/openssh/openbsd-compat/bsd-snprintf.c It needs the following includes/defines to work: #include <sys/types.h> #include <stdio.h> #include <ctype.h> #include <stdlib.h> #include <string.h> #include <stdarg.h> #define MAX(a, b) ((a) < (b) ? (b) : (a)) Here's the resulting output after running the example code again with OpenSSH's snprintf(): [longer th] (9) [shorter] (7) [longer7777t] (11) The return value still isn't right, though. ---------------------------------------------------------------------- Comment By: Luke Dunstan (infidel) Date: 2004-12-12 01:06 Message: Logged In: YES user_id=30442 When you call snprintf() it is actually mapped to _snprintf() in msvcrt.dll, which is a Microsoft-specific function that works as documented in MSDN. Arguably this mapping should not be done since the behaviour is different. ---------------------------------------------------------------------- Comment By: Aaron W. LaFramboise (aaronwl) Date: 2004-12-11 22:10 Message: Logged In: YES user_id=1040098 For comparison, here is the output on my machine, using msvcrt 7.0.2600.2180. [longer th] (15) [shorter] (7) [longer7777t] (18) Find msvcrt.dll in windows\system32 and check its version on the property tab. I would suspect this difference comes from an older version of this runtime using a pre-standard snprintf implementation. (Historical UNIX implementations also disagree with regards to this function.) ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=102435&aid=1083721&group_id=2435 |