Search code examples
c++cmbstring

mbstowcs_s function retsize sometimes return input length + 1


I'm using VisualStdio 2010 on Windows 7.

I want to decrypt password using function and display result of decryption as TCHAR*.

Implementation here,

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

char* _decrypt_password_v1(const char* strPassword);
char Hash_v1(const char chhash, int nIndex);

#define VIT_PASSWORD _decrypt_password_v1("OOWIEJFOISJDFNPPAJ")

char* _decrypt_password_v1(const char* strPassword)
{
    unsigned int i = 0;
    char* strDecrypt = (char*)malloc(strlen(strPassword) + 1);
    memset(strDecrypt, 0x00, strlen(strPassword) + 1);
    int nLen = strlen(strPassword) -1;
    for (int i = 0; i < nLen; i++)
    {
        strDecrypt[i] = Hash_v1(strPassword[nLen - i], nLen - 1);
    }

    strDecrypt[i] = NULL;

    return strDecrypt;
}

int _tmain(int argc, _TCHAR* argv[])
{
    TCHAR szPassword[MAX_PATH] = {0};
    int nLen = strlen(VIT_PASSWORD);
    _tprintf(_T("Input Password Len : %d\n"), nLen);

    size_t outSize;
    mbstowcs_s(&outSize, szPassword, strlen(VIT_PASSWORD), VIT_PASSWORD, strlen(VIT_PASSWORD));

    _tprintf(_T("Password : %s\n"), szPassword);

    return 0;
}

If I run this code, I will get an error

Debug Assertion Failed!

File: f:\dd\vctools\crt_bld\self_x86\crt\src\mbstowcs.c

Line: 283

Expression: retsize <= sizeInWords

So, I increased parameter 3 of mbstowcs_s tostrlen(VIT_PASSWORD) + 1.

Corrected code:

mbstowcs_s(&outSize, szPassword, strlen(VIT_PASSWORD) + 1, VIT_PASSWORD, strlen(VIT_PASSWORD));

Then no crash and run correctly, but sizeInWords is strlen(VIT_PASSWORD), not strlen(VIT_PASSWORD) + 1.

If I use mbstowcs instead, there's no error. like this mbstowcs(szPassword, VIT_PASSWORD, strlen(VIT_PASSWORD));

Why this happens? If the answer is not clear, I have to modify this part of my entire code in this way.

I need concrete answers.


Solution

  • The third parameter to mbtowcs_s should be the size of the buffer pointed to by the second parameter in wchar_ts, so in your case it should be MAX_PATH.

    The point of mbtowcs_s is to make sure you don't write more characters to the destination than you have space for. That's what the third parameter is for: to tell it how much space you have. In this case, if VIT_PASSWORD has no non-ASCII characters in it, the destination will need the same number of wchar_ts to hold the converted string. So if VIT_PASSWORD is 4 characters long, plus the nul terminator, then mbtowcs_s's third parameter will need to be at least 5 to successfully convert the string (4 characters plus the nul-terminator). The problem is that strlen(VIT_PASSWORD) will return 4, not 5 since it doesn't count the nul-terminator.