Microsoft KB Archive/241857

= The CComBSTR constructor does not always allocate sufficient space in ATL =

Article ID: 241857

Article Last Modified on 6/2/2005

-

APPLIES TO

 Microsoft ActiveX Template Library 3.0, when used with:  Microsoft Visual C++ 6.0 Enterprise Edition

 Microsoft Visual C++ 6.0 Professional Edition

 Microsoft Visual C++ 6.0 Standard Edition 

-

<div class="notice_section">

This article was previously published under Q241857

<div class="symptoms_section">

SYMPTOMS
The following fragment of code produces different results with ATL version 2.1 and ATL version 3.0: char rawStr[128] = "01234567839"; CComBSTR bstr (4, rawStr); In ATL 2.1, the new bstr is L"0123"; however, in ATL 3.0, the new bstr is L"012".

<div class="cause_section">

CAUSE
This problem is due to a bug in the A2WBSTR function in the Atlconv.h file: inline BSTR A2WBSTR(LPCSTR lp, int nLen = -1) { USES_CONVERSION; BSTR str = NULL; int nConvertedLen= MultiByteToWideChar(_acp, 0, lp, nLen, NULL, NULL)-1; str = ::SysAllocStringLen(NULL, nConvertedLen); if (str != NULL) { MultiByteToWideChar(_acp, 0, lp, -1,   str, nConvertedLen); } return str; } If the MultiByteToWideChar function's fourth argument is -1, the string is assumed to be NULL-terminated and the number of bytes returned will include the NULL character. The result of this function should not subtract 1 (one) if nLen does not equal -1; it should only do this if nLen is equal to -1.

<div class="resolution_section">

RESOLUTION
There are two ways to correct this problem:

Method 1
Use one of the conversion macros to wrap the string passed into the constructor: CComBSTR bstr(5, T2OLE(buf));

-or-

CComBSTR bstr(5, OLESTR("01234"); This method uses the CComBSTR(int nSize, LPCOLESTR sz) constructor, which calls ::SysAllocStringLen, and then returns a BSTR with the number of characters equal to nSize.

Method 2
Change the incorrect code in Atlconv.h for the A2WBSTR function: <ol>  Change the code in Atlconv.h for the A2WBSTR function from the following: inline BSTR A2WBSTR(LPCSTR lp, int nLen = -1) { USES_CONVERSION; BSTR str = NULL; int nConvertedLen = MultiByteToWideChar(_acp, 0, lp, nLen, NULL, NULL)-1; str = ::SysAllocStringLen(NULL, nConvertedLen); if (str != NULL) {   MultiByteToWideChar(_acp, 0, lp, -1, str, nConvertedLen); } return str; } to the following: inline BSTR A2WBSTR(LPCSTR lp, int nLen = -1) {  USES_CONVERSION; BSTR str = NULL; int nConvertedLen = MultiByteToWideChar(_acp, 0, lp,    nLen, NULL, NULL); // BUG FIX #1 (from Q241857): only subtract 1 from // the length if the source data is nul-terminated if (nLen == -1) nConvertedLen--; str = ::SysAllocStringLen(NULL, nConvertedLen); if (str != NULL) {    MultiByteToWideChar(_acp, 0, lp, nLen, str, nConvertedLen); }  return str; }                       </li> Save Atlconv.h.</li> On the Build menu, click Rebuild All. You need to do this on a Debug or ReleaseMinDependency build so that the modified code above is linked into your code.</li></ol>

<div class="status_section">

STATUS
Microsoft has confirmed that this is a bug in the Microsoft products that are listed in the "Applies to" section.

Additional query words: A2WBSTR A2BSTR A2W BSTR SysAllocString

Keywords: kbtshoot kbbug kbstring KB241857

-

[mailto:TECHNET@MICROSOFT.COM Send feedback to Microsoft]

© Microsoft Corporation. All rights reserved.