strtok_s возвращает неверные данные внутри windbg - PullRequest
0 голосов
/ 12 октября 2019

(Привет всем) У меня есть проблема с strtok_s. Я написал этот код (x64).

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


    BOOL TestMD5(CONST WCHAR* MD5_DATABASE_FILE)
    {
    HANDLE  hFile = INVALID_HANDLE_VALUE;
    DWORD   FileSize = 0;
    DWORD   dwReaded = 0;
    PBYTE   pData = NULL;
    BOOL    bRead = FALSE;
    PCHAR   token_string = NULL;
    PCHAR   context = NULL;
    CONST   PCHAR delimeter = "\r\n";

    hFile = CreateFileW(
        MD5_DATABASE_FILE,
        GENERIC_READ,
        FILE_SHARE_READ,
        NULL,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
        NULL
    );

    if (hFile == INVALID_HANDLE_VALUE)
    {
        wprintf(L"Can't open md5 database file: ");
        return FALSE;
    }

    FileSize = GetFileSize(hFile, NULL);
    if (FileSize == 0 || FileSize == INVALID_FILE_SIZE)
    {

        CloseHandle(hFile);
        return FALSE;
    }

    pData = (PBYTE)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (SIZE_T)FileSize);
    if (pData == NULL)
    {

        CloseHandle(hFile);
        return FALSE;
    }

    bRead = ReadFile(hFile, pData, FileSize, &dwReaded, NULL);
    if (bRead != TRUE || dwReaded != FileSize)
    {

        HeapFree(GetProcessHeap(), 0, pData);
        CloseHandle(hFile);
        return FALSE;
    }


    token_string = (PCHAR)strtok_s(pData, delimeter, &context);
    if (token_string == NULL)
    {

        HeapFree(GetProcessHeap(), 0, pData);
        CloseHandle(hFile);
    return FALSE;
    }

    do {

        printf("%s\n", token_string);

    } while (token_string = (PCHAR)strtok_s(NULL, delimeter, &context));


    HeapFree(GetProcessHeap(), 0, pData);
    CloseHandle(hFile);
    return TRUE;
    }

    int main(void)
    {
    WCHAR* MD5_DATABASE_FILE = L"c:\\md5.txt";

    TestMD5(MD5_DATABASE_FILE);


    }

Когда я запускаю exe, это дает мне неверные данные. Содержимое md5.txt (DC288E0B39EA16B4E9455F82FF265A67: 1213: TestDBG + (\ r \ n)

вывод:

D: \ repos \ TestWindbg \ x64 \ Debug> TestWindbg.exe DC288E0FFBB6767B5685B5685155F5706155F5506165156105159106109105109115152F1507155159F1508159F5159505159509159119119159159159159159609609609609609609605605605605605605505506: 5TestDBG ááááááááááááá

Я открываю exe в windbg и вижу, что (token_string) не NULL после первого раза. Но так ли это?

WinDbg image: "https://i.ibb.co/60nHk5S/Untitled.png"

В чем проблема? Спасибо за чтение

Ответы [ 2 ]

0 голосов
/ 14 октября 2019

Джеффри Шао - MSFT: Спасибо за ответ, но это не решение (но я изменил свой код PBYTE TO PCHAR). Проблема в том, что strtok_s является строковой функцией, поэтому вы должны добавить NULL байт после положительного эффекта. Например, HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(SIZE_T)FileSize + 1) # 1 для символа NULL. HeapAlloc выделяет размер буфера: FileSize и +1 для Null ...

Спасибо за блабб и Даниэль Сенк:

0 голосов
/ 14 октября 2019

Я просто изменяю некоторые типы pData и token_string.

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


BOOL TestMD5(CONST WCHAR* MD5_DATABASE_FILE)
{
    HANDLE  hFile = INVALID_HANDLE_VALUE;
    DWORD   FileSize = 0;
    DWORD   dwReaded = 0;
    char*   pData = NULL;
    BOOL    bRead = FALSE;
    char*   token_string = NULL;
    PCHAR   context = NULL;
    CONST   PCHAR delimeter = "\r\n";

    hFile = CreateFileW(
        MD5_DATABASE_FILE,
        GENERIC_READ,
        FILE_SHARE_READ,
        NULL,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
        NULL
    );

    if (hFile == INVALID_HANDLE_VALUE)
    {
        wprintf(L"Can't open md5 database file: ");
        return FALSE;
    }

    FileSize = GetFileSize(hFile, NULL);
    if (FileSize == 0 || FileSize == INVALID_FILE_SIZE)
    {

        CloseHandle(hFile);
        return FALSE;
    }

    pData = (char*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(SIZE_T)FileSize + 1);
    if (pData == NULL)
    {

        CloseHandle(hFile);
        return FALSE;
    }

    bRead = ReadFile(hFile, pData, FileSize, &dwReaded, NULL);
    if (bRead != TRUE || dwReaded != FileSize)
    {
        HeapFree(GetProcessHeap(), 0, pData);
        CloseHandle(hFile);
        return FALSE;
    }


    token_string = strtok_s(pData, delimeter, &context);
    if (token_string == NULL)
    {

        HeapFree(GetProcessHeap(), 0, pData);
        CloseHandle(hFile);
        return FALSE;
    }

    do {

        printf("%s\n", token_string);

    } while (token_string = strtok_s(NULL, delimeter, &context));


    HeapFree(GetProcessHeap(), 0, pData);
    CloseHandle(hFile);
    return TRUE;
}

int main(void)
{
    WCHAR* MD5_DATABASE_FILE = L"c:\\md5.txt";

    TestMD5(MD5_DATABASE_FILE);

}

Выход: DC288E0B39EA16B4E9455F82FF265A67: 1213: TestDBG + (\ r \ n)

...