Переполнение буфера при объявлении массива Char - PullRequest
1 голос
/ 12 февраля 2012

Я никогда раньше не работал на C ++ / COM, поэтому я пытаюсь угнать существующее решение и просто изменить его в соответствии со своими потребностями. Проект был написан и успешно скомпилирован с VC 6, и я пытаюсь работать с ним сейчас в 2010 году. Мне пришлось изменить несколько ссылок, чтобы заставить его скомпилироваться, но по какой-то причине генерируемая мной dll вызывает исключение моя система (оригинал отлично работает). Проводя некоторое исследование ошибки, похоже, что я получаю переполнение буфера при попытке объявить массив символов.

bool CFile::simpleWrite(char* cData)
{
    try{

        // temp result variable
        BOOL bResult = 0;

        // file handle
        HANDLE hFile = INVALID_HANDLE_VALUE;

        // get the CMain singleton
        CMain* m_pMain = CMain::GetInstance();

        // this point gets synchronization to ensure we get unique file name...
        char cDirFilename[MAX_PATH + 1];
        GetLogFileName(cDirFilename, MAX_PATH);

        // sanity check
        if(strcmp(cDirFilename, "c:\\") == 0)   assert(0);

        // try and create a file
        hFile = CreateFile( cDirFilename, GENERIC_WRITE, FILE_SHARE_READ,NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );

        // if have a good file handle
        if(hFile != INVALID_HANDLE_VALUE){

            size_t lenFileData = strlen(cData) + 72;
            char* cFileData = new char[lenFileData];
            _snprintf(cFileData, lenFileData, "<?xml version=\"1.0\"?>\r\n<RootElement>\r\n%s</RootElement>\r\n\0", cData);
...

Вот объявление / назначение для cData (cXML в вызывающем методе).

char cXML[EVENT_LOG_MAX_MESSAGE];
// get the CMain singleton
CMain* pMain = CMain::GetInstance();

long lThreadID = GetCurrentThreadId();

// put the parameters into XML format
pMain->BuildXML(cXML, EVENT_LOG_MAX_MESSAGE,errLogLevel,userActivityID,methodName,lineNumber,className,AppID,errorDescription,errorID,lThreadID);

// write the data to file
if(!simpleWrite(cXML))
...

BuildXML выполняет _snprintf в cXML и возвращает его.

Вот трассировка стека, идущая от моего вызова в некоторые файлы VC.

Test.dll!_heap_alloc_base(unsigned int size)  Line 55   C
Test.dll!_heap_alloc_dbg_impl(unsigned int nSize, int nBlockUse, const char * szFileName, int nLine, int * errno_tmp)  Line 431 + 0x9 bytes C++
Test.dll!_nh_malloc_dbg_impl(unsigned int nSize, int nhFlag, int nBlockUse, const char * szFileName, int nLine, int * errno_tmp)  Line 239 + 0x19 bytes C++
Test.dll!_nh_malloc_dbg(unsigned int nSize, int nhFlag, int nBlockUse, const char * szFileName, int nLine)  Line 302 + 0x1d bytes   C++
Test.dll!malloc(unsigned int nSize)  Line 56 + 0x15 bytes   C++
Test.dll!operator new(unsigned int size)  Line 59 + 0x9 bytes   C++
Test.dll!operator new[](unsigned int count)  Line 6 + 0x9 bytes C++
Test.dll!CFile::simpleWrite(char * cData)  Line 87 + 0xc bytes  C++

Я уверен, что есть какая-то глупая базовая ошибка, но я не могу понять ее.

Ответы [ 2 ]

0 голосов
/ 13 февраля 2012

Как я и подозревал, это была моя собственная глупость. У этого COM-приложения была зависимость, о которой я не знал. Никогда не видел ничего, что пыталось найти его в мониторе процесса, и проект имел локальную копию файла для целей компиляции. Спасибо за вклад, хотя.

0 голосов
/ 12 февраля 2012

Ваша ошибка, скорее всего, где-то еще, где вы в конечном итоге повреждают кучу. Я заметил, что вы используете здесь strlen, не добавляя один для конечного нуля. Посмотрите в своем коде, чтобы увидеть, используете ли вы strlen для выделения памяти и копирования где-нибудь, потому что я думаю, что вы повреждаете кучу, выделяя один байт слишком мало, а затем strcpy'ing ему.

...