From: SourceForge.net <no...@so...> - 2004-12-12 02:10:02
|
Bugs item #1083721, was opened at 2004-12-11 21:10 Message generated for change (Tracker Item Submitted) made by Item Submitter 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. ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=102435&aid=1083721&group_id=2435 |
From: SourceForge.net <no...@so...> - 2004-12-12 03:10:32
|
Bugs item #1083721, was opened at 2004-12-11 20:10 Message generated for change (Comment added) made by aaronwl 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: Aaron W. LaFramboise (aaronwl) Date: 2004-12-11 21: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 |
From: SourceForge.net <no...@so...> - 2004-12-12 06:06:25
|
Bugs item #1083721, was opened at 2004-12-12 10:10 Message generated for change (Comment added) made by infidel 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: Luke Dunstan (infidel) Date: 2004-12-12 14: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-12 11: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 |
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 |
From: SourceForge.net <no...@so...> - 2005-02-08 08:49:47
|
Bugs item #1083721, was opened at 2004-12-12 15:10 Message generated for change (Comment added) made by dannysmith 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: Danny Smith (dannysmith) Date: 2005-02-08 21:49 Message: Logged In: YES user_id=11494 I've attached an [v]snprintf wrapper for msvc _[v]snprint. Its not pretty and given Aaron's comment that the bug appears fixed in more recent versions of msvcrt.dll, I'll not do anything rash like commit to CVS. But its here, for the record. Maybe someone has time to make it more efficient. FWIW, my tests with msvcr70.dll and msvcr71.dll show same broken _snprintf behaviour as msvcrt.dll version 6.10.8924.0 Danny ---------------------------------------------------------------------- Comment By: William G. Davis (william_g_davis) Date: 2004-12-14 15: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 19: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-12 16: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 |
From: SourceForge.net <no...@so...> - 2007-02-02 02:34:28
|
Bugs item #1083721, was opened at 2004-12-12 13:10 Message generated for change (Comment added) made by pinniped You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=102435&aid=1083721&group_id=2435 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: None Group: None Status: Open Resolution: None Priority: 5 Private: No 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: Cirilo Bernardo (pinniped) Date: 2007-02-02 13:34 Message: Logged In: YES user_id=858758 Originator: NO Still broken... I have MinGW with gcc 4.0.2 and snprintf() is still broken. Basically, if the source string exceeds the specified length limit N, the first N characters of the source are copied to the destination; no terminating zero is written to the destination. ---------------------------------------------------------------------- Comment By: Danny Smith (dannysmith) Date: 2005-02-08 19:49 Message: Logged In: YES user_id=11494 I've attached an [v]snprintf wrapper for msvc _[v]snprint. Its not pretty and given Aaron's comment that the bug appears fixed in more recent versions of msvcrt.dll, I'll not do anything rash like commit to CVS. But its here, for the record. Maybe someone has time to make it more efficient. FWIW, my tests with msvcr70.dll and msvcr71.dll show same broken _snprintf behaviour as msvcrt.dll version 6.10.8924.0 Danny ---------------------------------------------------------------------- Comment By: William G. Davis (william_g_davis) Date: 2004-12-14 13: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 17: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-12 14: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 |
From: SourceForge.net <no...@so...> - 2007-09-18 11:38:04
|
Bugs item #1083721, was opened at 2004-12-12 02:10 Message generated for change (Comment added) made by keithmarshall You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=102435&aid=1083721&group_id=2435 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: None Group: None Status: Open >Resolution: Fixed Priority: 5 Private: No 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: Keith Marshall (keithmarshall) Date: 2007-09-18 11:38 Message: Logged In: YES user_id=823908 Originator: NO > Still broken ... Well, yes and no. Yes, in so far as it didn't match C99 expectations; no, since it worked exactly as specified by MSDN, for the _snprintf() function provided by MSVCRT, (to which snprintf() had been redirected). Anyway, the implementation in CVS is now C99 conformant, in most respects. ---------------------------------------------------------------------- Comment By: Cirilo Bernardo (pinniped) Date: 2007-02-02 02:34 Message: Logged In: YES user_id=858758 Originator: NO Still broken... I have MinGW with gcc 4.0.2 and snprintf() is still broken. Basically, if the source string exceeds the specified length limit N, the first N characters of the source are copied to the destination; no terminating zero is written to the destination. ---------------------------------------------------------------------- Comment By: Danny Smith (dannysmith) Date: 2005-02-08 08:49 Message: Logged In: YES user_id=11494 I've attached an [v]snprintf wrapper for msvc _[v]snprint. Its not pretty and given Aaron's comment that the bug appears fixed in more recent versions of msvcrt.dll, I'll not do anything rash like commit to CVS. But its here, for the record. Maybe someone has time to make it more efficient. FWIW, my tests with msvcr70.dll and msvcr71.dll show same broken _snprintf behaviour as msvcrt.dll version 6.10.8924.0 Danny ---------------------------------------------------------------------- Comment By: William G. Davis (william_g_davis) Date: 2004-12-14 02: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 06: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-12 03: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 |
From: SourceForge.net <no...@so...> - 2008-06-14 09:31:57
|
Bugs item #1083721, was opened at 2004-12-12 15:10 Message generated for change (Settings changed) made by dannysmith You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=102435&aid=1083721&group_id=2435 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: None Group: None >Status: Closed Resolution: Fixed Priority: 5 Private: No 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: Keith Marshall (keithmarshall) Date: 2007-09-18 23:38 Message: Logged In: YES user_id=823908 Originator: NO > Still broken ... Well, yes and no. Yes, in so far as it didn't match C99 expectations; no, since it worked exactly as specified by MSDN, for the _snprintf() function provided by MSVCRT, (to which snprintf() had been redirected). Anyway, the implementation in CVS is now C99 conformant, in most respects. ---------------------------------------------------------------------- Comment By: Cirilo Bernardo (pinniped) Date: 2007-02-02 15:34 Message: Logged In: YES user_id=858758 Originator: NO Still broken... I have MinGW with gcc 4.0.2 and snprintf() is still broken. Basically, if the source string exceeds the specified length limit N, the first N characters of the source are copied to the destination; no terminating zero is written to the destination. ---------------------------------------------------------------------- Comment By: Danny Smith (dannysmith) Date: 2005-02-08 21:49 Message: Logged In: YES user_id=11494 I've attached an [v]snprintf wrapper for msvc _[v]snprint. Its not pretty and given Aaron's comment that the bug appears fixed in more recent versions of msvcrt.dll, I'll not do anything rash like commit to CVS. But its here, for the record. Maybe someone has time to make it more efficient. FWIW, my tests with msvcr70.dll and msvcr71.dll show same broken _snprintf behaviour as msvcrt.dll version 6.10.8924.0 Danny ---------------------------------------------------------------------- Comment By: William G. Davis (william_g_davis) Date: 2004-12-14 15: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 19: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-12 16: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 |