From: Norman Diamond on 31 Jul 2006 06:40 "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 31 Jul 2006 16:25 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 31 Jul 2006 16:30 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 31 Jul 2006 21:27 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 1 Aug 2006 02:02
> 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 |