Функция mbstowcs_s retsize иногда возвращает длину ввода + 1

Я использую VisualStdio 2010 в Windows 7.

Я хочу расшифровать пароль с помощью функции и отобразить результат расшифровки как TCHAR*.

Реализация здесь

#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;
}

Если я запущу этот код, я получу ошибку

Ошибка утверждения отладки!

Файл: f:\dd\vctools\crt_bld\self_x86\crt\src\mbstowcs.c

Линия: 283

Выражение: resize ‹= sizeInWords

Итак, я увеличил параметр 3 из mbstowcs_s до strlen(VIT_PASSWORD) + 1.

Исправленный код:

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

Тогда никаких сбоев и работает правильно, но sizeInWords это strlen(VIT_PASSWORD), а не strlen(VIT_PASSWORD) + 1.

Если вместо этого я использую mbstowcs, ошибки не будет. вот так mbstowcs(szPassword, VIT_PASSWORD, strlen(VIT_PASSWORD));

Почему это происходит? Если ответ не ясен, я должен изменить эту часть всего моего кода таким образом.

Мне нужны конкретные ответы.


person G.Alexander    schedule 02.08.2017    source источник


Ответы (1)


Третий параметр mbtowcs_s должен быть размером буфера, на который указывает вторым параметром в wchar_ts, поэтому в вашем случае это должно быть MAX_PATH.

Смысл mbtowcs_s в том, чтобы убедиться, что вы не записываете в пункт назначения больше символов, чем у вас есть место. Вот для чего нужен третий параметр: чтобы указать, сколько места у вас есть. В этом случае, если в VIT_PASSWORD нет символов, отличных от ASCII, получателю потребуется такое же количество wchar_t для хранения преобразованной строки. Таким образом, если VIT_PASSWORD имеет длину 4 символа плюс терминатор nul, то для успешного преобразования строки третий параметр mbtowcs_s должен быть не менее 5 (4 символа плюс терминатор nul). Проблема в том, что strlen(VIT_PASSWORD) вернет 4, а не 5, так как не учитывает терминатор nul.

person Miles Budnek    schedule 02.08.2017
comment
Спасибо. проблема была не в ASCII. - person G.Alexander; 02.08.2017