_sntprintf and _sntprintf_s
- From: "Norman Diamond" <ndiamond@xxxxxxxxxxxxxxxx>
- Date: Mon, 29 May 2006 19:30:15 +0900
I was really surprised when Visual Studio 2005 gave a warning that function
_snwprintf was declared with old syntax. I couldn't quite figure out what
syntax _snwprintf was declared with. However, some investigation revealed
that Microsoft declared _snwprintf to be deprecated for security reasons.
There is some difference between a VC++ built-in header declaring a function
with old syntax and a company declaring a function to be deprecated.
Perhaps the maker of Visual Studio 2005 could be informed of the difference?
On figuring out that _sntprintf should be replaced by _sntprintf_s, I tried
to find it in MSDN. The search function of MSDN library United States found
the page for _snwprintf_s in MSDN library Korea but not in MSDN library
United States. Some manual searching found it in MSDN library United
States.
Now for some strange looking statements in page
http://msdn2.microsoft.com/en-us/library/f30dzcf6.aspx
First are two important statements which are only a bit strange:
sizeOfBuffer
The size of the storage location for output. Size in bytes for
_snprintf_s or size in words for _snwprintf_s.
Count
Maximum number of characters to store, or _TRUNCATE.
OK, the sizeOfBuffer parameter is the same as the count parameter of the old
_snwprintf function. This really specifies the size of the buffer. The new
Count parameter specifies a maximum number of characters. I suppose the
dual limit is a convenience, but I don't understand how the level of
security improves. The size of the buffer is still specified the same way
even though the parameter name has changed, and the new Count parameter
specifies a different alternative limit instead of the size of the buffer.
_snprintf_s returns the number of characters stored in buffer, not
counting the terminating null character. _snwprintf_s returns the number
of wide characters stored in buffer, not counting the terminating null
wide character.
This looks terrible. Actually _snwprintf_s looks mostly OK, since the
programmer wants to do calculations on the number of wide characters and
keep track of how much space remains in the buffer. But why does
_snprintf_s return the number of characters instead of the number of bytes?
If a programmer is using the ANSI version then the programmer wants to do
calculations on the number of bytes in order to keep track of how much space
remains in the buffer. I also hope that _snwprintf_s doesn't have a split
personality on the treatment of surrogate pairs.
In C++, using these functions is simplified by template overloads; the
overloads can infer buffer length automatically (eliminating the need to
specify a size argument) and they can automatically replace older,
non-secure functions with their newer, secure counterparts. For more
information, see Secure Template Overloads.
I'm not sure how Secure Template Overloads can infer buffer length
automatically, but maybe they call some undocumented memory management
functions, so OK, I read that page too.
http://msdn2.microsoft.com/en-us/library/ms175759.aspx
To enable template overloads for the count functions, define
_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT to be 1. Before doing so,
however, make sure that your code passes the count of characters, not the
size of the buffer (a common mistake).
Um, no wonder it's common for my code to pass the size of the buffer instead
of the count of characters. Look again at the sizeOfBuffer parameter to
_sntprintf_s and the count parameter to the old _sntprintf function. In the
Unicode version it's supposed to be the size in WCHAR_Ts and in the ANSI
version it's supposed to be the size in bytes. In both cases it should be
the size in TCHARs. In the ANSI version it would be pretty hard to predict
a size in characters. Now, even though my code commonly specified the
buffer size in known units, was this a common mistake or a common accuracy?
Who is really making mistakes here, and will the mistakes be fixed?
.
- Follow-Ups:
- Re: _sntprintf and _sntprintf_s
- From: John Carson
- Re: _sntprintf and _sntprintf_s
- From: Alexander Grigoriev
- Re: _sntprintf and _sntprintf_s
- Prev by Date: Re: Quick question!
- Next by Date: Help regarding executing Sql script
- Previous by thread: Where do get the ODBC headers/libraries from ?
- Next by thread: Re: _sntprintf and _sntprintf_s
- Index(es):
Relevant Pages
|