Module: wine Branch: stable Commit: e2546a64c6f94d8ab1708f7950a787771804bf13 URL: https://source.winehq.org/git/wine.git/?a=commit;h=e2546a64c6f94d8ab1708f795...
Author: Vincent Povirk vincent@codeweavers.com Date: Tue May 8 12:46:19 2018 -0500
gdi32: Check for truncated EMF files.
Signed-off-by: Vincent Povirk vincent@codeweavers.com Signed-off-by: Huw Davies huw@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org (cherry picked from commit 8d2676fd14f130f9e8f06744743423168bf8d18d) Signed-off-by: Michael Stefaniuc mstefani@winehq.org
---
dlls/gdi32/enhmetafile.c | 25 +++++++++++++++++++------ dlls/gdi32/enhmfdrv/init.c | 2 +- dlls/gdi32/gdi_private.h | 2 +- 3 files changed, 21 insertions(+), 8 deletions(-)
diff --git a/dlls/gdi32/enhmetafile.c b/dlls/gdi32/enhmetafile.c index 111fa43..045015f 100644 --- a/dlls/gdi32/enhmetafile.c +++ b/dlls/gdi32/enhmetafile.c @@ -246,11 +246,16 @@ static inline BOOL is_dib_monochrome( const BITMAPINFO* info ) /**************************************************************************** * EMF_Create_HENHMETAFILE */ -HENHMETAFILE EMF_Create_HENHMETAFILE(ENHMETAHEADER *emh, BOOL on_disk ) +HENHMETAFILE EMF_Create_HENHMETAFILE(ENHMETAHEADER *emh, DWORD filesize, BOOL on_disk ) { HENHMETAFILE hmf; ENHMETAFILEOBJ *metaObj;
+ if (filesize < sizeof(*emh)) + { + WARN("File too small for emf header\n"); + return 0; + } if (emh->iType != EMR_HEADER) { SetLastError(ERROR_INVALID_DATA); @@ -263,6 +268,11 @@ HENHMETAFILE EMF_Create_HENHMETAFILE(ENHMETAHEADER *emh, BOOL on_disk ) emh->iType, emh->dSignature); return 0; } + if (filesize < emh->nBytes) + { + WARN("File truncated (got %u bytes, header says %u)\n", emh->nBytes, filesize); + return 0; + }
if (!(metaObj = HeapAlloc( GetProcessHeap(), 0, sizeof(*metaObj) ))) return 0;
@@ -317,14 +327,17 @@ static HENHMETAFILE EMF_GetEnhMetaFile( HANDLE hFile ) ENHMETAHEADER *emh; HANDLE hMapping; HENHMETAFILE hemf; + DWORD filesize; + + filesize = GetFileSize( hFile, NULL );
hMapping = CreateFileMappingA( hFile, NULL, PAGE_READONLY, 0, 0, NULL ); - emh = MapViewOfFile( hMapping, FILE_MAP_READ, 0, 0, 0 ); + emh = MapViewOfFile( hMapping, FILE_MAP_READ, 0, 0, filesize ); CloseHandle( hMapping );
if (!emh) return 0;
- hemf = EMF_Create_HENHMETAFILE( emh, TRUE ); + hemf = EMF_Create_HENHMETAFILE( emh, filesize, TRUE ); if (!hemf) UnmapViewOfFile( emh ); return hemf; @@ -467,7 +480,7 @@ HENHMETAFILE WINAPI SetEnhMetaFileBits(UINT bufsize, const BYTE *buf) ENHMETAHEADER *emh = HeapAlloc( GetProcessHeap(), 0, bufsize ); HENHMETAFILE hmf; memmove(emh, buf, bufsize); - hmf = EMF_Create_HENHMETAFILE( emh, FALSE ); + hmf = EMF_Create_HENHMETAFILE( emh, bufsize, FALSE ); if (!hmf) HeapFree( GetProcessHeap(), 0, emh ); return hmf; @@ -2561,7 +2574,7 @@ HENHMETAFILE WINAPI CopyEnhMetaFileA( if (!file) { emrDst = HeapAlloc( GetProcessHeap(), 0, emrSrc->nBytes ); memcpy( emrDst, emrSrc, emrSrc->nBytes ); - hmfDst = EMF_Create_HENHMETAFILE( emrDst, FALSE ); + hmfDst = EMF_Create_HENHMETAFILE( emrDst, emrSrc->nBytes, FALSE ); if (!hmfDst) HeapFree( GetProcessHeap(), 0, emrDst ); } else { @@ -2603,7 +2616,7 @@ HENHMETAFILE WINAPI CopyEnhMetaFileW( if (!file) { emrDst = HeapAlloc( GetProcessHeap(), 0, emrSrc->nBytes ); memcpy( emrDst, emrSrc, emrSrc->nBytes ); - hmfDst = EMF_Create_HENHMETAFILE( emrDst, FALSE ); + hmfDst = EMF_Create_HENHMETAFILE( emrDst, emrSrc->nBytes, FALSE ); if (!hmfDst) HeapFree( GetProcessHeap(), 0, emrDst ); } else { diff --git a/dlls/gdi32/enhmfdrv/init.c b/dlls/gdi32/enhmfdrv/init.c index 6f9a956..4872efd 100644 --- a/dlls/gdi32/enhmfdrv/init.c +++ b/dlls/gdi32/enhmfdrv/init.c @@ -528,7 +528,7 @@ HENHMETAFILE WINAPI CloseEnhMetaFile(HDC hdc) /* [in] metafile DC */ CloseHandle( physDev->hFile ); }
- hmf = EMF_Create_HENHMETAFILE( physDev->emh, (physDev->hFile != 0) ); + hmf = EMF_Create_HENHMETAFILE( physDev->emh, physDev->emh->nBytes, (physDev->hFile != 0) ); physDev->emh = NULL; /* So it won't be deleted */ free_dc_ptr( dc ); return hmf; diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h index 4236aa3..fc2dc91 100644 --- a/dlls/gdi32/gdi_private.h +++ b/dlls/gdi32/gdi_private.h @@ -268,7 +268,7 @@ extern const struct gdi_dc_funcs *DRIVER_load_driver( LPCWSTR name ) DECLSPEC_HI extern BOOL DRIVER_GetDriverName( LPCWSTR device, LPWSTR driver, DWORD size ) DECLSPEC_HIDDEN;
/* enhmetafile.c */ -extern HENHMETAFILE EMF_Create_HENHMETAFILE(ENHMETAHEADER *emh, BOOL on_disk ) DECLSPEC_HIDDEN; +extern HENHMETAFILE EMF_Create_HENHMETAFILE(ENHMETAHEADER *emh, DWORD filesize, BOOL on_disk ) DECLSPEC_HIDDEN;
/* freetype.c */