From: Norman Diamond on
"Joseph M. Newcomer" <newcomer(a)flounder.com> wrote in message
news:e57oc2lrr2nd1j0nt83h8e7h02ahjsbqih(a)4ax.com...

> Use CString::Format as the preferred choice.

On "real" Windows I agree. On Windows CE where extra libraries will occupy
the machine's RAM, it might not be a good idea.

> If you MUST use some form like _stprintf, use StringCchPrintf (I think
> that's the name, but search for strsafe.h on the MSDN) which at least will
> avoid any possibility of buffer overflow

As documented it will not have such a beneficial effect.

> StringCchPrintf(_T("%c"), B, sizeof(B) / sizeof(TCHAR), (BYTE)('a' + i));

Mihai N. addressed a problem with your cast to BYTE and you made an
adjustment which I'm still thinking about. Since arguments to
StringCchPrintf are either Unicode or ANSI, the last argument should be
either char or wchar_t, and I'm trying to figure out if WORD is guaranteed
to marshall a char value properly.

More importantly is that, as documented, buffer overflow can very easily
occur. Suppose we have an ANSI compilation and make B an array of 2 chars.
Then the buffer has enough space for 1 single-byte character plus a null
character. But if the last argument is a double-byte character then
StringCchPrintf is documented to copy both bytes plus a single-byte null
character, total 3 bytes.

From: Joseph M. Newcomer on
Yes, I agree that the character conversion is probably a bad idea; it makes a lot of
assumptions that probably won't hold when the code gets its first accented character. And
let's not hint at the problems of Unicode surrogates...
joe

On Mon, 31 Jul 2006 01:50:58 -0700, "Mihai N." <nmihai_year_2000(a)yahoo.com> wrote:

>> Homebrewed encryption is *always* a bad idea,
>I was trying to be mild :-)
>
>> but I suspect this is more likely trying to
>> do some kind of character conversion.
>This is probably also bad idea :-)
>Doing any kind of "math" on Unicode characters is very
>likely to result in a mess.
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
From: Joseph M. Newcomer on
The libraries are shared and there is already a copy of them loaded.

What is wrong with StringCchPrintf? It won't overflow the buffer, which is a good thing.

The char/wchar_t is what TCHAR means. But it is signed, which implies sign extension for
any Unicode character > 7FFFU. This will not produce a good result in most cases. WORD
will handle a char value because it won't sign extended.

I made B an array of two characters. not two bytes. I distinctly recall writing
TCHAR B[2];
which is two characters. This means in Unicode it is 4 bytes.

StringCchPrintf will format the string, which is one character plus a terminal null
character. Do not confuse "character" with "byte". StringCchPrintf will copy the single
character and add a NULL character, which the last I looked, was two characters, the size
of the array.
joe

On Mon, 31 Jul 2006 19:40:24 +0900, "Norman Diamond" <ndiamond(a)community.nospam> wrote:

>"Joseph M. Newcomer" <newcomer(a)flounder.com> wrote in message
>news:e57oc2lrr2nd1j0nt83h8e7h02ahjsbqih(a)4ax.com...
>
>> Use CString::Format as the preferred choice.
>
>On "real" Windows I agree. On Windows CE where extra libraries will occupy
>the machine's RAM, it might not be a good idea.
>
>> If you MUST use some form like _stprintf, use StringCchPrintf (I think
>> that's the name, but search for strsafe.h on the MSDN) which at least will
>> avoid any possibility of buffer overflow
>
>As documented it will not have such a beneficial effect.
>
>> StringCchPrintf(_T("%c"), B, sizeof(B) / sizeof(TCHAR), (BYTE)('a' + i));
>
>Mihai N. addressed a problem with your cast to BYTE and you made an
>adjustment which I'm still thinking about. Since arguments to
>StringCchPrintf are either Unicode or ANSI, the last argument should be
>either char or wchar_t, and I'm trying to figure out if WORD is guaranteed
>to marshall a char value properly.
>
>More importantly is that, as documented, buffer overflow can very easily
>occur. Suppose we have an ANSI compilation and make B an array of 2 chars.
>Then the buffer has enough space for 1 single-byte character plus a null
>character. But if the last argument is a double-byte character then
>StringCchPrintf is documented to copy both bytes plus a single-byte null
>character, total 3 bytes.
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
From: Norman Diamond on
The documentation for StringCchPrintf talks about counts of characters. In
an ANSI compilation each character occupies one or two TCHARs depending on
the actual character. The documentation for StringCchPrintf doesn't say
that TCHARs are counted where it does say that characters are counted.

Dr. Newcomer, you KNOW how, in an ANSI compilation, one 2-TCHAR character
will overflow a buffer which has enough space for only one 1-TCHAR
character.

"Joseph M. Newcomer" <newcomer(a)flounder.com> wrote in message
news:tppsc21810onsurc601ligkkiivh5pui77(a)4ax.com...
> The libraries are shared and there is already a copy of them loaded.
>
> What is wrong with StringCchPrintf? It won't overflow the buffer, which
> is a good thing.
>
> The char/wchar_t is what TCHAR means. But it is signed, which implies
> sign extension for
> any Unicode character > 7FFFU. This will not produce a good result in
> most cases. WORD
> will handle a char value because it won't sign extended.
>
> I made B an array of two characters. not two bytes. I distinctly recall
> writing
> TCHAR B[2];
> which is two characters. This means in Unicode it is 4 bytes.
>
> StringCchPrintf will format the string, which is one character plus a
> terminal null
> character. Do not confuse "character" with "byte". StringCchPrintf will
> copy the single
> character and add a NULL character, which the last I looked, was two
> characters, the size
> of the array.
> joe
>
> On Mon, 31 Jul 2006 19:40:24 +0900, "Norman Diamond"
> <ndiamond(a)community.nospam> wrote:
>
>>"Joseph M. Newcomer" <newcomer(a)flounder.com> wrote in message
>>news:e57oc2lrr2nd1j0nt83h8e7h02ahjsbqih(a)4ax.com...
>>
>>> Use CString::Format as the preferred choice.
>>
>>On "real" Windows I agree. On Windows CE where extra libraries will
>>occupy
>>the machine's RAM, it might not be a good idea.
>>
>>> If you MUST use some form like _stprintf, use StringCchPrintf (I think
>>> that's the name, but search for strsafe.h on the MSDN) which at least
>>> will
>>> avoid any possibility of buffer overflow
>>
>>As documented it will not have such a beneficial effect.
>>
>>> StringCchPrintf(_T("%c"), B, sizeof(B) / sizeof(TCHAR), (BYTE)('a' +
>>> i));
>>
>>Mihai N. addressed a problem with your cast to BYTE and you made an
>>adjustment which I'm still thinking about. Since arguments to
>>StringCchPrintf are either Unicode or ANSI, the last argument should be
>>either char or wchar_t, and I'm trying to figure out if WORD is guaranteed
>>to marshall a char value properly.
>>
>>More importantly is that, as documented, buffer overflow can very easily
>>occur. Suppose we have an ANSI compilation and make B an array of 2
>>chars.
>>Then the buffer has enough space for 1 single-byte character plus a null
>>character. But if the last argument is a double-byte character then
>>StringCchPrintf is documented to copy both bytes plus a single-byte null
>>character, total 3 bytes.
> Joseph M. Newcomer [MVP]
> email: newcomer(a)flounder.com
> Web: http://www.flounder.com
> MVP Tips: http://www.flounder.com/mvp_tips.htm

From: Mihai N. on
> The documentation for StringCchPrintf talks about counts of characters. In
> an ANSI compilation each character occupies one or two TCHARs depending on
> the actual character. The documentation for StringCchPrintf doesn't say
> that TCHARs are counted where it does say that characters are counted.
....
> Dr. Newcomer, you KNOW how, in an ANSI compilation, one 2-TCHAR character
> will overflow a buffer which has enough space for only one 1-TCHAR
> character.

I suspect it is the typical MSDN confusion when talking about characters.
Since in strsafe.h I can find both StringCchPrintfA and StringCchPrintfW,
I assume it works like all the Win32 API with regard to buffer lengths.
Meaning that when they say "character" in ANSI context, one should really
understand char. So 2 TCHAR character in a 1 TCHAR buffer will trigger
a "not enough space" error (not tested, but I am quite sure).
If this is not the case, it is definitely a bug.
When the documentation talks about character, then is a char in ANSI and
wchar_t/WCHAT in Unicode, totaly unaware of DBCS, surrogates, combining
chars.
There are in fact very few APIs that deal with what the "user character"


--
Mihai Nita [Microsoft MVP, Windows - SDK]
http://www.mihai-nita.net
------------------------------------------
Replace _year_ with _ to get the real email