CFileFind::FindFile()にMAX_PATHより長いパスを渡すとアプリケーションエラーで落ちる(VC++6.0)

投稿日: 2006年05月16日 更新日: 2017年07月22日

Visual C++ 6.0 SP6で以下のコードを実行するとアプリケーションエラーで落ちる。

CFileFind finder;
CString path;

// 260文字(MAX_PATH定数)以上の文字列
//         1234567890123456789012345678901234567890
path = _T("C:\aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
          "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
          "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
          "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
          "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
          "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
          "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");


// ここで落ちる
finder.FindFile(path);

原因はMFCのソース(MFC/SRC/FILEFIND.CPP)の以下の部分で、lstrcpyがメモリを破壊してるから。

BOOL CFileFind::FindFile(LPCTSTR pstrName /* = NULL */,
    DWORD dwUnused /* = 0 */)
{
...
   if (pstrName == NULL)
       pstrName = _T("*.*");
   // WIN32_FIND_DATAのcFileNameは
   // TCHAR[MAX_PATH]で宣言されている
   lstrcpy(((WIN32_FIND_DATA*) m_pNextInfo)->cFileName, pstrName);
...
}

ちなみにVC.NET2003では次のように修正されているため落ちない。

BOOL CFileFind::FindFile(LPCTSTR pstrName /* = NULL */,
    DWORD dwUnused /* = 0 */)
{
...
   if (pstrName == NULL)
       pstrName = _T("*.*");
   else if (lstrlen(pstrName) >= (_countof(((WIN32_FIND_DATA*) m_pNextInfo)->cFileName)))
   {
       ::SetLastError(ERROR_BAD_ARGUMENTS);
       return FALSE;        
   }
...
}

名前:宮内 はじめ

Code for Nagoya名誉代表

E2D3名古屋支部長

プログラマーです。GISやデータビズが好きです。このサイトは宮内の個人的なメモです。

プロフィール

お問い合わせ