Bruce MacDonald
2005-02-27 12:03:31 UTC
ACE VERSION: 5.4.4
HOST MACHINE and OPERATING SYSTEM:
Windows 2000
TARGET MACHINE and OPERATING SYSTEM, if different from HOST: Same
COMPILER NAME AND VERSION (AND PATCHLEVEL): Visual Studio .NET 2003
(7.1.3088)
CONTENTS OF $ACE_ROOT/ace/config.h:
#define ACE_HAS_STANDARD_CPP_LIBRARY 1
#include "ace/config-win32.h"
CONTENTS OF $ACE_ROOT/include/makeinclude/platform_macros.GNU (unless
this isn't used in this case, e.g., with Microsoft Visual C++): n/a
CONTENTS OF $ACE_ROOT/bin/MakeProjectCreator/config/default.features
(used by MPC when you generate your own makefiles):
ssl=0
qos=1
cidl=0
rwho=0
sctp=0
AREA/CLASS/EXAMPLE AFFECTED:
ACE_OS::snprintf
DOES THE PROBLEM AFFECT:
COMPILATION? No
LINKING? No
EXECUTION? Yes
OTHER? No
All appications using snprintf.
SYNOPSIS:
ACE_OS::snprintf does not terminate the string with a null char if it is
*exactly* the same length as the buffer.
DESCRIPTION:
The code in OS_NS_stdio.cpp, line 285 checks the return value from
_vsnprintf to determine whether to set a null terminator in the last
character of the buffer. This return value, as that of _snprintf, is broken
and it returns failure only if the string won't fit in the buffer, not if it
fits exactly.
REPEAT BY:
This code demonstrates the problem:
int main(int argc, char *argv[])
{
char sz[2];
ACE_OS::snprintf(sz,sizeof(sz),"%s","A"); // ['A','\0'] Ok
ACE_OS::snprintf(sz,sizeof(sz),"%s","BCD"); // ['B','\0'] Ok
ACE_OS::snprintf(sz,sizeof(sz),"%s","EF"); // ['E', 'F'] Not terminated!
return 0;
}
SAMPLE FIX/WORKAROUND:
Change lines 284-286 from:
// Win32 doesn't 0-terminate the string if it overruns maxlen.
if (result == -1)
buf[maxlen-1] = '\0';
to:
// Win32 doesn't regard a full buffer with no 0-terminate as an overrun.
if (result == maxlen)
result = -1;
// Win32 doesn't 0-terminate the string if it overruns maxlen.
if (result == -1)
buf[maxlen-1] = '\0';
Bruce MacDonald
HOST MACHINE and OPERATING SYSTEM:
Windows 2000
TARGET MACHINE and OPERATING SYSTEM, if different from HOST: Same
COMPILER NAME AND VERSION (AND PATCHLEVEL): Visual Studio .NET 2003
(7.1.3088)
CONTENTS OF $ACE_ROOT/ace/config.h:
#define ACE_HAS_STANDARD_CPP_LIBRARY 1
#include "ace/config-win32.h"
CONTENTS OF $ACE_ROOT/include/makeinclude/platform_macros.GNU (unless
this isn't used in this case, e.g., with Microsoft Visual C++): n/a
CONTENTS OF $ACE_ROOT/bin/MakeProjectCreator/config/default.features
(used by MPC when you generate your own makefiles):
ssl=0
qos=1
cidl=0
rwho=0
sctp=0
AREA/CLASS/EXAMPLE AFFECTED:
ACE_OS::snprintf
DOES THE PROBLEM AFFECT:
COMPILATION? No
LINKING? No
EXECUTION? Yes
OTHER? No
All appications using snprintf.
SYNOPSIS:
ACE_OS::snprintf does not terminate the string with a null char if it is
*exactly* the same length as the buffer.
DESCRIPTION:
The code in OS_NS_stdio.cpp, line 285 checks the return value from
_vsnprintf to determine whether to set a null terminator in the last
character of the buffer. This return value, as that of _snprintf, is broken
and it returns failure only if the string won't fit in the buffer, not if it
fits exactly.
REPEAT BY:
This code demonstrates the problem:
int main(int argc, char *argv[])
{
char sz[2];
ACE_OS::snprintf(sz,sizeof(sz),"%s","A"); // ['A','\0'] Ok
ACE_OS::snprintf(sz,sizeof(sz),"%s","BCD"); // ['B','\0'] Ok
ACE_OS::snprintf(sz,sizeof(sz),"%s","EF"); // ['E', 'F'] Not terminated!
return 0;
}
SAMPLE FIX/WORKAROUND:
Change lines 284-286 from:
// Win32 doesn't 0-terminate the string if it overruns maxlen.
if (result == -1)
buf[maxlen-1] = '\0';
to:
// Win32 doesn't regard a full buffer with no 0-terminate as an overrun.
if (result == maxlen)
result = -1;
// Win32 doesn't 0-terminate the string if it overruns maxlen.
if (result == -1)
buf[maxlen-1] = '\0';
Bruce MacDonald