Commit 117d5326 authored by Rolf Kalbermatter's avatar Rolf Kalbermatter Committed by Alexandre Julliard

Fix a possible memory leak when extracting from an ICO file.

Fix some signed/unsigned warnings showing up in MSVC with default warning level. Fix possible problem with short PIMAGE_NT_HEADERS.
parent ea1ca9c7
...@@ -254,7 +254,7 @@ static UINT ICO_ExtractIconExW( ...@@ -254,7 +254,7 @@ static UINT ICO_ExtractIconExW(
UINT *pIconId, UINT *pIconId,
UINT flags) UINT flags)
{ {
UINT ret = 0xFFFFFFFF; UINT ret = 0;
UINT cx1, cx2, cy1, cy2; UINT cx1, cx2, cy1, cy2;
LPBYTE pData; LPBYTE pData;
DWORD sig; DWORD sig;
...@@ -267,29 +267,26 @@ static UINT ICO_ExtractIconExW( ...@@ -267,29 +267,26 @@ static UINT ICO_ExtractIconExW(
TRACE("%s, %d, %d %p 0x%08x\n", debugstr_w(lpszExeFileName), nIconIndex, nIcons, pIconId, flags); TRACE("%s, %d, %d %p 0x%08x\n", debugstr_w(lpszExeFileName), nIconIndex, nIcons, pIconId, flags);
hFile = CreateFileW( lpszExeFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 ); hFile = CreateFileW(lpszExeFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
if (hFile == INVALID_HANDLE_VALUE) return ret; if (hFile == INVALID_HANDLE_VALUE) return ret;
fsizel = GetFileSize(hFile,&fsizeh); fsizel = GetFileSize(hFile,&fsizeh);
/* Map the file */ /* Map the file */
fmapping = CreateFileMappingW( hFile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL ); fmapping = CreateFileMappingW(hFile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL);
CloseHandle( hFile ); CloseHandle(hFile);
if (!fmapping) if (!fmapping)
{ {
WARN("CreateFileMapping error %ld\n", GetLastError() ); WARN("CreateFileMapping error %ld\n", GetLastError() );
return ret; return 0xFFFFFFFF;
} }
if ( !(peimage = MapViewOfFile(fmapping,FILE_MAP_READ,0,0,0))) if (!(peimage = MapViewOfFile(fmapping, FILE_MAP_READ, 0, 0, 0)))
{ {
WARN("MapViewOfFile error %ld\n", GetLastError() ); WARN("MapViewOfFile error %ld\n", GetLastError() );
CloseHandle( fmapping ); CloseHandle(fmapping);
return ret; return 0xFFFFFFFF;
} }
CloseHandle( fmapping ); CloseHandle(fmapping);
/* Initialize return value to 0 to indicate extraction error */
ret = 0;
cx1 = LOWORD(cxDesired); cx1 = LOWORD(cxDesired);
cx2 = HIWORD(cxDesired) ? HIWORD(cxDesired) : cx1; cx2 = HIWORD(cxDesired) ? HIWORD(cxDesired) : cx1;
...@@ -302,10 +299,10 @@ static UINT ICO_ExtractIconExW( ...@@ -302,10 +299,10 @@ static UINT ICO_ExtractIconExW(
if (!pIconId) /* if no icon identifier array present use the icon handle array as intermediate storage */ if (!pIconId) /* if no icon identifier array present use the icon handle array as intermediate storage */
pIconId = (UINT*)RetPtr; pIconId = (UINT*)RetPtr;
sig = USER32_GetResourceTable(peimage,fsizel,&pData); sig = USER32_GetResourceTable(peimage, fsizel, &pData);
/* ico file */ /* ico file or NE exe/dll*/
if( sig==IMAGE_OS2_SIGNATURE || sig==1 ) /* .ICO file */ if (sig==IMAGE_OS2_SIGNATURE || sig==1) /* .ICO file */
{ {
BYTE *pCIDir = 0; BYTE *pCIDir = 0;
NE_TYPEINFO *pTInfo = (NE_TYPEINFO*)(pData + 2); NE_TYPEINFO *pTInfo = (NE_TYPEINFO*)(pData + 2);
...@@ -315,25 +312,24 @@ static UINT ICO_ExtractIconExW( ...@@ -315,25 +312,24 @@ static UINT ICO_ExtractIconExW(
TRACE("-- OS2/icon Signature (0x%08lx)\n", sig); TRACE("-- OS2/icon Signature (0x%08lx)\n", sig);
if( pData == (BYTE*)-1 ) if (pData == (BYTE*)-1)
{ {
/* FIXME: pCIDir is allocated on the heap - memory leak */
pCIDir = ICO_GetIconDirectory(peimage, &lpiID, &uSize); /* check for .ICO file */ pCIDir = ICO_GetIconDirectory(peimage, &lpiID, &uSize); /* check for .ICO file */
if( pCIDir ) if (pCIDir)
{ {
iconDirCount = 1; iconCount = lpiID->idCount; iconDirCount = 1; iconCount = lpiID->idCount;
TRACE("-- icon found %p 0x%08lx 0x%08x 0x%08x\n", pCIDir, uSize, iconDirCount, iconCount); TRACE("-- icon found %p 0x%08lx 0x%08x 0x%08x\n", pCIDir, uSize, iconDirCount, iconCount);
} }
} }
else while( pTInfo->type_id && !(pIconStorage && pIconDir) ) else while (pTInfo->type_id && !(pIconStorage && pIconDir))
{ {
if( pTInfo->type_id == NE_RSCTYPE_GROUP_ICON ) /* find icon directory and icon repository */ if (pTInfo->type_id == NE_RSCTYPE_GROUP_ICON) /* find icon directory and icon repository */
{ {
iconDirCount = pTInfo->count; iconDirCount = pTInfo->count;
pIconDir = ((NE_NAMEINFO*)(pTInfo + 1)); pIconDir = ((NE_NAMEINFO*)(pTInfo + 1));
TRACE("\tfound directory - %i icon families\n", iconDirCount); TRACE("\tfound directory - %i icon families\n", iconDirCount);
} }
if( pTInfo->type_id == NE_RSCTYPE_ICON ) if (pTInfo->type_id == NE_RSCTYPE_ICON)
{ {
iconCount = pTInfo->count; iconCount = pTInfo->count;
pIconStorage = ((NE_NAMEINFO*)(pTInfo + 1)); pIconStorage = ((NE_NAMEINFO*)(pTInfo + 1));
...@@ -342,37 +338,41 @@ static UINT ICO_ExtractIconExW( ...@@ -342,37 +338,41 @@ static UINT ICO_ExtractIconExW(
pTInfo = (NE_TYPEINFO *)((char*)(pTInfo+1)+pTInfo->count*sizeof(NE_NAMEINFO)); pTInfo = (NE_TYPEINFO *)((char*)(pTInfo+1)+pTInfo->count*sizeof(NE_NAMEINFO));
} }
if( (pIconStorage && pIconDir) || lpiID ) /* load resources and create icons */ if ((pIconStorage && pIconDir) || lpiID) /* load resources and create icons */
{ {
if( nIcons == 0 ) if (nIcons == 0)
{ {
ret = iconDirCount; ret = iconDirCount;
if (lpiID && pCIDir) /* *.ico file, deallocate heap pointer*/
HeapFree(GetProcessHeap(), 0, pCIDir);
} }
else if( nIconIndex < iconDirCount ) else if (nIconIndex < iconDirCount)
{ {
UINT16 i, icon; UINT16 i, icon;
if( nIcons > iconDirCount - nIconIndex ) if (nIcons > iconDirCount - nIconIndex)
nIcons = iconDirCount - nIconIndex; nIcons = iconDirCount - nIconIndex;
for (i = 0; i < nIcons; i++) for (i = 0; i < nIcons; i++)
{ {
/* .ICO files have only one icon directory */ /* .ICO files have only one icon directory */
if( lpiID == NULL ) /* *.ico */ if (lpiID == NULL) /* not *.ico */
pCIDir = USER32_LoadResource(peimage, pIconDir + i + nIconIndex , *(WORD*)pData, &uSize); pCIDir = USER32_LoadResource(peimage, pIconDir + i + nIconIndex, *(WORD*)pData, &uSize);
pIconId[i] = LookupIconIdFromDirectoryEx(pCIDir, TRUE, (i & 1) ? cx2 : cx1, (i & 1) ? cy2 : cy1, flags); pIconId[i] = LookupIconIdFromDirectoryEx(pCIDir, TRUE, (i & 1) ? cx2 : cx1, (i & 1) ? cy2 : cy1, flags);
} }
if (lpiID && pCIDir) /* *.ico file, deallocate heap pointer*/
HeapFree(GetProcessHeap(), 0, pCIDir);
for (icon = 0; icon < nIcons; icon++) for (icon = 0; icon < nIcons; icon++)
{ {
pCIDir = NULL; pCIDir = NULL;
if( lpiID ) if (lpiID)
pCIDir = ICO_LoadIcon(peimage, lpiID->idEntries + (int)pIconId[icon], &uSize); pCIDir = ICO_LoadIcon(peimage, lpiID->idEntries + (int)pIconId[icon], &uSize);
else else
for (i = 0; i < iconCount; i++) for (i = 0; i < iconCount; i++)
if (pIconStorage[i].id == ((int)pIconId[icon] | 0x8000) ) if (pIconStorage[i].id == ((int)pIconId[icon] | 0x8000) )
pCIDir = USER32_LoadResource(peimage, pIconStorage + i, *(WORD*)pData, &uSize); pCIDir = USER32_LoadResource(peimage, pIconStorage + i, *(WORD*)pData, &uSize);
if( pCIDir ) if (pCIDir)
RetPtr[icon] = (HICON)CreateIconFromResourceEx(pCIDir, uSize, TRUE, 0x00030000, RetPtr[icon] = (HICON)CreateIconFromResourceEx(pCIDir, uSize, TRUE, 0x00030000,
(icon & 1) ? cx2 : cx1, (icon & 1) ? cy2 : cy1, flags); (icon & 1) ? cx2 : cx1, (icon & 1) ? cy2 : cy1, flags);
else else
...@@ -394,11 +394,12 @@ static UINT ICO_ExtractIconExW( ...@@ -394,11 +394,12 @@ static UINT ICO_ExtractIconExW(
const IMAGE_RESOURCE_DIRECTORY *rootresdir,*iconresdir,*icongroupresdir; const IMAGE_RESOURCE_DIRECTORY *rootresdir,*iconresdir,*icongroupresdir;
const IMAGE_RESOURCE_DATA_ENTRY *idataent,*igdataent; const IMAGE_RESOURCE_DATA_ENTRY *idataent,*igdataent;
const IMAGE_RESOURCE_DIRECTORY_ENTRY *xresent; const IMAGE_RESOURCE_DIRECTORY_ENTRY *xresent;
int i,j; UINT i, j;
dheader = (PIMAGE_DOS_HEADER)peimage; dheader = (PIMAGE_DOS_HEADER)peimage;
pe_header = (PIMAGE_NT_HEADERS)(peimage+dheader->e_lfanew); /* it is a pe header, USER32_GetResourceTable checked that */ pe_header = (PIMAGE_NT_HEADERS)(peimage+dheader->e_lfanew); /* it is a pe header, USER32_GetResourceTable checked that */
pe_sections = (PIMAGE_SECTION_HEADER)(((char*)pe_header)+sizeof(*pe_header)); /* probably makes problems with short PE headers...*/ pe_sections = (PIMAGE_SECTION_HEADER)(((char*)pe_header) + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER)
+ pe_header->FileHeader.SizeOfOptionalHeader);
rootresdir = NULL; rootresdir = NULL;
/* search for the root resource directory */ /* search for the root resource directory */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment