Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Bug in CStringT operator=

Bug in CStringT operator=

Scheduled Pinned Locked Moved C / C++ / MFC
helpc++performanceannouncement
3 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • K Offline
    K Offline
    Konrad Windszus
    wrote on last edited by
    #1

    I think I found a bug in the MFC 7.1. There is an error during assignment of a LPWSTR to a CString in an MBCS or ANSI application. If you have something like this LPWSTR pWStr; // contains an WideString CString str; str = pWStr; // <- here is the bug In the third line the following member of CString is called: CStringT& operator=( PCYSTR pszSrc ) [cstringt.h, line 988] which calls GetBaseTypeLength [cstringt.h, line 429] This member returns the size of the pWStr (via WideCharToMultiByte) - 1. That means that the terminating NULL-character is not counted. So the reserved memory is too small to contain the whole pWStr including terminating NULL! In the following call of StringTraits::ConvertToBaseType( pszBuffer, nDestLength, pszSrc ) in line 995 the destLengh doesn't include the NULL character. But ConvertToBaseType implicitly calls WideCharToMultiByte with the following parameters: ::WideCharToMultiByte( _AtlGetConversionACP(), 0, pszSrc, -1, pszDest, nDestLength, NULL, NULL ); This function returns the error code 0, because the reserved memory in pszDest is one byte to small. To my mind this is an error in the MFCs. I only checked this in MFC 7.1. Please tell me, if you can reproduce the problem perhaps in other MFC version, too. Thanks in advance Konrad

    J B 2 Replies Last reply
    0
    • K Konrad Windszus

      I think I found a bug in the MFC 7.1. There is an error during assignment of a LPWSTR to a CString in an MBCS or ANSI application. If you have something like this LPWSTR pWStr; // contains an WideString CString str; str = pWStr; // <- here is the bug In the third line the following member of CString is called: CStringT& operator=( PCYSTR pszSrc ) [cstringt.h, line 988] which calls GetBaseTypeLength [cstringt.h, line 429] This member returns the size of the pWStr (via WideCharToMultiByte) - 1. That means that the terminating NULL-character is not counted. So the reserved memory is too small to contain the whole pWStr including terminating NULL! In the following call of StringTraits::ConvertToBaseType( pszBuffer, nDestLength, pszSrc ) in line 995 the destLengh doesn't include the NULL character. But ConvertToBaseType implicitly calls WideCharToMultiByte with the following parameters: ::WideCharToMultiByte( _AtlGetConversionACP(), 0, pszSrc, -1, pszDest, nDestLength, NULL, NULL ); This function returns the error code 0, because the reserved memory in pszDest is one byte to small. To my mind this is an error in the MFCs. I only checked this in MFC 7.1. Please tell me, if you can reproduce the problem perhaps in other MFC version, too. Thanks in advance Konrad

      J Offline
      J Offline
      Joe Woodbury
      wrote on last edited by
      #2

      This isn't really a bug, just the developers leveraging how the API works. The string will come out correctly since WideCharToMultiByte will convert characters until the destination buffer fills up. This behavior is actually desired since the length passed for the source string may be shorter than the string. The developers could have resolved nSrcLength before making the call, but chose not to since the failure is quite irrelevant. The terminating null is taken care off by the GetBuffer() call, which reserves space for a terminating null. Anyone who thinks he has a better idea of what's good for people than people do is a swine. - P.J. O'Rourke

      1 Reply Last reply
      0
      • K Konrad Windszus

        I think I found a bug in the MFC 7.1. There is an error during assignment of a LPWSTR to a CString in an MBCS or ANSI application. If you have something like this LPWSTR pWStr; // contains an WideString CString str; str = pWStr; // <- here is the bug In the third line the following member of CString is called: CStringT& operator=( PCYSTR pszSrc ) [cstringt.h, line 988] which calls GetBaseTypeLength [cstringt.h, line 429] This member returns the size of the pWStr (via WideCharToMultiByte) - 1. That means that the terminating NULL-character is not counted. So the reserved memory is too small to contain the whole pWStr including terminating NULL! In the following call of StringTraits::ConvertToBaseType( pszBuffer, nDestLength, pszSrc ) in line 995 the destLengh doesn't include the NULL character. But ConvertToBaseType implicitly calls WideCharToMultiByte with the following parameters: ::WideCharToMultiByte( _AtlGetConversionACP(), 0, pszSrc, -1, pszDest, nDestLength, NULL, NULL ); This function returns the error code 0, because the reserved memory in pszDest is one byte to small. To my mind this is an error in the MFCs. I only checked this in MFC 7.1. Please tell me, if you can reproduce the problem perhaps in other MFC version, too. Thanks in advance Konrad

        B Offline
        B Offline
        Brian Shifrin
        wrote on last edited by
        #3

        The same code was VC6.. It causes read out of bound warning in BoundChecker & Purify, but also pretty harmless. Also note, if you change (via WideCharToMultiByte) - 1 to (via WideCharToMultiByte) you will break ATL CComBSTR, and may be some others.

        1 Reply Last reply
        0
        Reply
        • Reply as topic
        Log in to reply
        • Oldest to Newest
        • Newest to Oldest
        • Most Votes


        • Login

        • Don't have an account? Register

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • World
        • Users
        • Groups