oleaut32: olepicture - Support multiple redundant headers before picture data.
This commit is contained in:
parent
2b06143031
commit
a7128fbc4d
|
@ -1400,6 +1400,7 @@ static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface,IStream*pStm) {
|
|||
BOOL headerisdata = FALSE;
|
||||
BOOL statfailed = FALSE;
|
||||
ULONG xread, toread;
|
||||
ULONG headerread;
|
||||
BYTE *xbuf;
|
||||
DWORD header[2];
|
||||
WORD magic;
|
||||
|
@ -1431,31 +1432,43 @@ static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface,IStream*pStm) {
|
|||
/* we will read at least 8 byte ... just right below */
|
||||
statstg.cbSize.QuadPart = 8;
|
||||
}
|
||||
|
||||
toread = 0;
|
||||
headerread = 0;
|
||||
headerisdata = FALSE;
|
||||
do {
|
||||
hr=IStream_Read(pStm,header,8,&xread);
|
||||
if (hr || xread!=8) {
|
||||
FIXME("Failure while reading picture header (hr is %x, nread is %d).\n",hr,xread);
|
||||
return hr;
|
||||
}
|
||||
|
||||
headerisdata = FALSE;
|
||||
headerread += xread;
|
||||
xread = 0;
|
||||
if (!memcmp(&(header[0]),"lt\0\0", 4) && (header[1] <= statstg.cbSize.QuadPart-8)) {
|
||||
|
||||
if (!memcmp(&(header[0]),"lt\0\0", 4) && (statfailed || (header[1] + headerread <= statstg.cbSize.QuadPart))) {
|
||||
if (toread != 0 && toread != header[1])
|
||||
FIXME("varying lengths of image data (prev=%u curr=%u), only last one will be used\n",
|
||||
toread, header[1]);
|
||||
toread = header[1];
|
||||
if (toread == 0) break;
|
||||
} else {
|
||||
if (!memcmp(&(header[0]), "GIF8", 4) || /* GIF header */
|
||||
!memcmp(&(header[0]), "BM", 2) || /* BMP header */
|
||||
!memcmp(&(header[0]), "\xff\xd8", 2) || /* JPEG header */
|
||||
(header[1] > statstg.cbSize.QuadPart)|| /* invalid size */
|
||||
(header[1]==0)
|
||||
) {/* Incorrect header, assume none. */
|
||||
) {/* Found start of bitmap data */
|
||||
headerisdata = TRUE;
|
||||
if (toread == 0)
|
||||
toread = statstg.cbSize.QuadPart-8;
|
||||
else toread -= 8;
|
||||
xread = 8;
|
||||
} else {
|
||||
FIXME("Unknown stream header magic: %08x\n", header[0]);
|
||||
toread = header[1];
|
||||
}
|
||||
}
|
||||
} while (!headerisdata);
|
||||
|
||||
if (statfailed) { /* we don't know the size ... read all we get */
|
||||
int sizeinc = 4096;
|
||||
|
|
|
@ -190,6 +190,8 @@ test_pic(const unsigned char *imgdata, unsigned int imgsize)
|
|||
HRESULT hres;
|
||||
LARGE_INTEGER seekto;
|
||||
ULARGE_INTEGER newpos1;
|
||||
DWORD * header;
|
||||
unsigned int i;
|
||||
|
||||
/* Let the fun begin */
|
||||
hglob = GlobalAlloc (0, imgsize);
|
||||
|
@ -204,9 +206,54 @@ test_pic(const unsigned char *imgdata, unsigned int imgsize)
|
|||
ok (hres == S_OK, "istream seek failed? doubt it... hres 0x%08x\n", hres);
|
||||
test_pic_with_stream(stream, imgsize);
|
||||
|
||||
IStream_Release(stream);
|
||||
|
||||
/* again with Non Statable and Non Seekable stream */
|
||||
stream = (LPSTREAM)NoStatStreamImpl_Construct(hglob);
|
||||
test_pic_with_stream(stream, 0);
|
||||
|
||||
IStream_Release(stream);
|
||||
|
||||
/* free memory */
|
||||
GlobalUnlock(hglob);
|
||||
GlobalFree(hglob);
|
||||
|
||||
/* more fun!!! */
|
||||
hglob = GlobalAlloc (0, imgsize + 8 * (2 * sizeof(DWORD)));
|
||||
data = GlobalLock (hglob);
|
||||
header = (DWORD *)data;
|
||||
|
||||
/* multiple copies of header */
|
||||
memcpy(data,"lt\0\0",4);
|
||||
header[1] = imgsize;
|
||||
memcpy(&(header[2]), header, 2 * sizeof(DWORD));
|
||||
memcpy(&(header[4]), header, 4 * sizeof(DWORD));
|
||||
memcpy(&(header[8]), header, 8 * sizeof(DWORD));
|
||||
|
||||
memcpy(data + 8 * (2 * sizeof(DWORD)), imgdata, imgsize);
|
||||
|
||||
for (i = 1; i <= 8; i++) {
|
||||
hres = CreateStreamOnHGlobal (hglob, FALSE, &stream);
|
||||
ok (hres == S_OK, "createstreamonhglobal failed? doubt it... hres 0x%08x\n", hres);
|
||||
|
||||
memset(&seekto,0,sizeof(seekto));
|
||||
seekto.u.LowPart = (8 - i) * (2 * sizeof(DWORD));
|
||||
hres = IStream_Seek(stream,seekto,SEEK_CUR,&newpos1);
|
||||
ok (hres == S_OK, "istream seek failed? doubt it... hres 0x%08x\n", hres);
|
||||
test_pic_with_stream(stream, imgsize);
|
||||
|
||||
IStream_Release(stream);
|
||||
|
||||
/* again with Non Statable and Non Seekable stream */
|
||||
stream = (LPSTREAM)NoStatStreamImpl_Construct(hglob);
|
||||
test_pic_with_stream(stream, 0);
|
||||
|
||||
IStream_Release(stream);
|
||||
}
|
||||
|
||||
/* free memory */
|
||||
GlobalUnlock(hglob);
|
||||
GlobalFree(hglob);
|
||||
}
|
||||
|
||||
static void test_empty_image(void) {
|
||||
|
|
Loading…
Reference in New Issue