Click here to Skip to main content
15,887,214 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I am working on changing our application to support unicode characteristics . Hence while doing the changes i had to convert all char to wchar_t and we had some wrapper stream classes which i converted to support wchar_t . Now my issue is while doing the change to the below code i encounter Run-Time Check Failure #2 - Stack around the variable 'length' was corrupted. though if i continue i get the proper values . Please let me know how to get rid of this error.

C++
FDIStream&  
FDIStream::
operator>>(std::wstring& data)
{
    if (CanReadData())
    {
        int length = -1;
        *this >> length;

        if (length >= 0)
        {
            // See if length is a valid value (not pass eof)
            if (length > GetLength()) {
                throw FDException("Corrupted file");
            }

            wchar_t* buffer = new wchar_t[length];

            try
            {
                ReadBytes(buffer, length);

                data = std::wstring(buffer,length); 
            } catch (...)
            {
                delete[] buffer;
                throw;
            }

            delete[] buffer;
        }
    }

    return *this;
}
Posted
Updated 5-Mar-15 1:35am
v3

Unicode chars are 2 bytes wide.
if length holds the count in bytes then you may read a shorter string and miss the ending null. Because of this other operations on string can runover the allocated space corrupting the stack. In this case change:
C++
ReadBytes(buffer, length);

to
C++
ReadBytes(buffer, length*sizeof(wchar_t));

If length hold the count of chars the same problem could happen because the string length and the number of bytes are no more coincident.
In this case maybe you want change:
C++
data = std::wstring(buffer,length);

With:
C++
data = std::wstring(buffer,length/sizeof(wchar_t));
 
Share this answer
 
v2
Comments
Member 11500796 5-Mar-15 10:19am    
void
FDMemObject::
ReadBytes(void* data, int size) const
{
int actualSizeToRead = std::min<int>(mLength - mPosition, size);
if (actualSizeToRead > 0) {
wchar_t* dataToCopy(const_cast <wchar_t*> (reinterpret_cast<wchar_t*>(data)));
std::wmemcpy(dataToCopy, mBuffer + mPosition, actualSizeToRead);
mPosition += actualSizeToRead;
}


FDIStream&
FDIStream::
operator>>(long& data)
{
if (CanReadData())
{
ReadBytes(&data, sizeof(data));

#if defined( __LITTLE_ENDIAN__)
data = FDCoreUtils::ConvertToFromBigEndianFormat(static_cast<int>(data));
#endif
}

return *this;
}
I am passing byte value only ... which is 4 .... and while i am copying data to buffer ... buffer has "NO Embed Code" which should be the string in it and length 13 .... and after copying when i check the value of data ... i see it has 15 as size and it has "NO Embed Core" written into it .... Please let me know what actually is wrong with that code ...

I have doubt about that
C#
data = FDCoreUtils::ConvertToFromBigEndianFormat(static_cast(data));

function as that has some byte manipluations it ...

inline char
FDLoByte(short value)
{
return static_cast<char>(value & 0x000000FF);
}

inline int
FDHiWord(int value)
{
return (value >> 16) & 0x0000FFFF;
}

inline int
FDLoWord(int value)
{
return value & 0x0000FFFF;
}

I am very new to unicode and string conversions please let me know what i should look for and where i should look for to resolve this issue .
 
Share this answer
 
Comments
Frankie-C 6-Mar-15 7:28am    
What I see is a big mess. First of all the functions above are converting from double word (32 bits), unicode chars are word wide (16 bits).
Now please answer these questions:
1) You are reading on byte basis, and the number of bytes read is only dependent on the buffer size that you specify?
2) Your input stream is in big endian format and you need to converti it to little endian (INTEL)?
3) Your buffer size is always even?
Please post a comment not other solutions.
Member 11500796 6-Mar-15 10:19am    
We are reading on Byte Basis and the number of bytes read is only dependent on the buffer size we specify.

And our Input stream is Big endian format and we need to convert it to Little Endian.
and our Buffer size as far as what i am seeing while debugging is its always odd.
Frankie-C 7-Mar-15 11:00am    
If you read unicode chars you have to be sure to read complete wide chars (2 bytes) this could be accomplished by allocating buffer as wchar_t or an even number of bytes.
The conversion from big endian to little endian must be the simple swap of high order byte and low order byte of the wchar_t. Something as:
wchar_t SwapWchar(wchar_t wc)
{
wchar_t u = wc >> 8;
return (wc << 8) & u;
}
Using the former conversion that used 32 bits vars on the last conversion would have swapped up to 2 bytes not belonging to the buffer yet the stack corruption.
If this solves your problem please accept the solution.
Member 11500796 9-Mar-15 2:58am    
Thank you sooo much Frankie .... It did solve my issue ... I fixed the runtime error. I also rolled the stream code back to write out byte count and individual bytes. The wide string streams now read in the byte count and adjust their character count using the byte count. Streams need to have a consistent way of representing data, and character count would not work for wide strings since character count is not byte count.
Member 11500796 9-Mar-15 2:58am    
Thanks all for ur kind support and patience

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900