Commit a7128fbc authored by Alex Villacís Lasso's avatar Alex Villacís Lasso Committed by Alexandre Julliard

oleaut32: olepicture - Support multiple redundant headers before picture data.

parent 2b061430
...@@ -1400,6 +1400,7 @@ static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface,IStream*pStm) { ...@@ -1400,6 +1400,7 @@ static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface,IStream*pStm) {
BOOL headerisdata = FALSE; BOOL headerisdata = FALSE;
BOOL statfailed = FALSE; BOOL statfailed = FALSE;
ULONG xread, toread; ULONG xread, toread;
ULONG headerread;
BYTE *xbuf; BYTE *xbuf;
DWORD header[2]; DWORD header[2];
WORD magic; WORD magic;
...@@ -1431,31 +1432,43 @@ static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface,IStream*pStm) { ...@@ -1431,31 +1432,43 @@ static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface,IStream*pStm) {
/* we will read at least 8 byte ... just right below */ /* we will read at least 8 byte ... just right below */
statstg.cbSize.QuadPart = 8; statstg.cbSize.QuadPart = 8;
} }
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;
}
toread = 0;
headerread = 0;
headerisdata = FALSE; headerisdata = FALSE;
xread = 0; do {
if (!memcmp(&(header[0]),"lt\0\0", 4) && (header[1] <= statstg.cbSize.QuadPart-8)) { hr=IStream_Read(pStm,header,8,&xread);
toread = header[1]; if (hr || xread!=8) {
} else { FIXME("Failure while reading picture header (hr is %x, nread is %d).\n",hr,xread);
if (!memcmp(&(header[0]), "GIF8", 4) || /* GIF header */ return hr;
!memcmp(&(header[0]), "BM", 2) || /* BMP header */ }
!memcmp(&(header[0]), "\xff\xd8", 2) || /* JPEG header */ headerread += xread;
(header[1] > statstg.cbSize.QuadPart)|| /* invalid size */ xread = 0;
(header[1]==0)
) {/* Incorrect header, assume none. */ if (!memcmp(&(header[0]),"lt\0\0", 4) && (statfailed || (header[1] + headerread <= statstg.cbSize.QuadPart))) {
headerisdata = TRUE; if (toread != 0 && toread != header[1])
toread = statstg.cbSize.QuadPart-8; FIXME("varying lengths of image data (prev=%u curr=%u), only last one will be used\n",
xread = 8; toread, header[1]);
} else {
FIXME("Unknown stream header magic: %08x\n", header[0]);
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)
) {/* 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 */ if (statfailed) { /* we don't know the size ... read all we get */
int sizeinc = 4096; int sizeinc = 4096;
......
...@@ -190,6 +190,8 @@ test_pic(const unsigned char *imgdata, unsigned int imgsize) ...@@ -190,6 +190,8 @@ test_pic(const unsigned char *imgdata, unsigned int imgsize)
HRESULT hres; HRESULT hres;
LARGE_INTEGER seekto; LARGE_INTEGER seekto;
ULARGE_INTEGER newpos1; ULARGE_INTEGER newpos1;
DWORD * header;
unsigned int i;
/* Let the fun begin */ /* Let the fun begin */
hglob = GlobalAlloc (0, imgsize); hglob = GlobalAlloc (0, imgsize);
...@@ -203,10 +205,55 @@ test_pic(const unsigned char *imgdata, unsigned int imgsize) ...@@ -203,10 +205,55 @@ test_pic(const unsigned char *imgdata, unsigned int imgsize)
hres = IStream_Seek(stream,seekto,SEEK_CUR,&newpos1); hres = IStream_Seek(stream,seekto,SEEK_CUR,&newpos1);
ok (hres == S_OK, "istream seek failed? doubt it... hres 0x%08x\n", hres); ok (hres == S_OK, "istream seek failed? doubt it... hres 0x%08x\n", hres);
test_pic_with_stream(stream, imgsize); test_pic_with_stream(stream, imgsize);
IStream_Release(stream);
/* again with Non Statable and Non Seekable stream */ /* again with Non Statable and Non Seekable stream */
stream = (LPSTREAM)NoStatStreamImpl_Construct(hglob); stream = (LPSTREAM)NoStatStreamImpl_Construct(hglob);
test_pic_with_stream(stream, 0); 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) { static void test_empty_image(void) {
......
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