windowscodecs: Handle short reads in the metadata handler.
This commit is contained in:
parent
e3f0d40840
commit
5f4b8f5916
|
@ -681,7 +681,8 @@ static HRESULT LoadUnknownMetadata(IStream *input, const GUID *preferred_vendor,
|
||||||
if (!data) return E_OUTOFMEMORY;
|
if (!data) return E_OUTOFMEMORY;
|
||||||
|
|
||||||
hr = IStream_Read(input, data, stat.cbSize.QuadPart, &bytesread);
|
hr = IStream_Read(input, data, stat.cbSize.QuadPart, &bytesread);
|
||||||
if (FAILED(hr))
|
if (bytesread != stat.cbSize.QuadPart) hr = E_FAIL;
|
||||||
|
if (hr != S_OK)
|
||||||
{
|
{
|
||||||
HeapFree(GetProcessHeap(), 0, data);
|
HeapFree(GetProcessHeap(), 0, data);
|
||||||
return hr;
|
return hr;
|
||||||
|
@ -770,7 +771,7 @@ static int tag_to_vt(SHORT tag)
|
||||||
static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry,
|
static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry,
|
||||||
MetadataItem *item, BOOL native_byte_order)
|
MetadataItem *item, BOOL native_byte_order)
|
||||||
{
|
{
|
||||||
ULONG count, value, i;
|
ULONG count, value, i, bytesread;
|
||||||
SHORT type;
|
SHORT type;
|
||||||
LARGE_INTEGER pos;
|
LARGE_INTEGER pos;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
@ -822,8 +823,9 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry,
|
||||||
HeapFree(GetProcessHeap(), 0, item->value.u.caub.pElems);
|
HeapFree(GetProcessHeap(), 0, item->value.u.caub.pElems);
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
hr = IStream_Read(input, item->value.u.caub.pElems, count, NULL);
|
hr = IStream_Read(input, item->value.u.caub.pElems, count, &bytesread);
|
||||||
if (FAILED(hr))
|
if (bytesread != count) hr = E_FAIL;
|
||||||
|
if (hr != S_OK)
|
||||||
{
|
{
|
||||||
HeapFree(GetProcessHeap(), 0, item->value.u.caub.pElems);
|
HeapFree(GetProcessHeap(), 0, item->value.u.caub.pElems);
|
||||||
return hr;
|
return hr;
|
||||||
|
@ -866,8 +868,9 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry,
|
||||||
HeapFree(GetProcessHeap(), 0, item->value.u.caui.pElems);
|
HeapFree(GetProcessHeap(), 0, item->value.u.caui.pElems);
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
hr = IStream_Read(input, item->value.u.caui.pElems, count * 2, NULL);
|
hr = IStream_Read(input, item->value.u.caui.pElems, count * 2, &bytesread);
|
||||||
if (FAILED(hr))
|
if (bytesread != count * 2) hr = E_FAIL;
|
||||||
|
if (hr != S_OK)
|
||||||
{
|
{
|
||||||
HeapFree(GetProcessHeap(), 0, item->value.u.caui.pElems);
|
HeapFree(GetProcessHeap(), 0, item->value.u.caui.pElems);
|
||||||
return hr;
|
return hr;
|
||||||
|
@ -898,8 +901,9 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry,
|
||||||
HeapFree(GetProcessHeap(), 0, item->value.u.caul.pElems);
|
HeapFree(GetProcessHeap(), 0, item->value.u.caul.pElems);
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
hr = IStream_Read(input, item->value.u.caul.pElems, count * 4, NULL);
|
hr = IStream_Read(input, item->value.u.caul.pElems, count * 4, &bytesread);
|
||||||
if (FAILED(hr))
|
if (bytesread != count * 4) hr = E_FAIL;
|
||||||
|
if (hr != S_OK)
|
||||||
{
|
{
|
||||||
HeapFree(GetProcessHeap(), 0, item->value.u.caul.pElems);
|
HeapFree(GetProcessHeap(), 0, item->value.u.caul.pElems);
|
||||||
return hr;
|
return hr;
|
||||||
|
@ -925,8 +929,9 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry,
|
||||||
hr = IStream_Seek(input, pos, SEEK_SET, NULL);
|
hr = IStream_Seek(input, pos, SEEK_SET, NULL);
|
||||||
if (FAILED(hr)) return hr;
|
if (FAILED(hr)) return hr;
|
||||||
|
|
||||||
hr = IStream_Read(input, &ull, sizeof(ull), NULL);
|
hr = IStream_Read(input, &ull, sizeof(ull), &bytesread);
|
||||||
if (FAILED(hr)) return hr;
|
if (bytesread != sizeof(ull)) hr = E_FAIL;
|
||||||
|
if (hr != S_OK) return hr;
|
||||||
|
|
||||||
item->value.u.uhVal.QuadPart = ull;
|
item->value.u.uhVal.QuadPart = ull;
|
||||||
|
|
||||||
|
@ -953,8 +958,9 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry,
|
||||||
HeapFree(GetProcessHeap(), 0, item->value.u.cauh.pElems);
|
HeapFree(GetProcessHeap(), 0, item->value.u.cauh.pElems);
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
hr = IStream_Read(input, item->value.u.cauh.pElems, count * 8, NULL);
|
hr = IStream_Read(input, item->value.u.cauh.pElems, count * 8, &bytesread);
|
||||||
if (FAILED(hr))
|
if (bytesread != count * 8) hr = E_FAIL;
|
||||||
|
if (hr != S_OK)
|
||||||
{
|
{
|
||||||
HeapFree(GetProcessHeap(), 0, item->value.u.cauh.pElems);
|
HeapFree(GetProcessHeap(), 0, item->value.u.cauh.pElems);
|
||||||
return hr;
|
return hr;
|
||||||
|
@ -990,8 +996,9 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry,
|
||||||
HeapFree(GetProcessHeap(), 0, item->value.u.pszVal);
|
HeapFree(GetProcessHeap(), 0, item->value.u.pszVal);
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
hr = IStream_Read(input, item->value.u.pszVal, count, NULL);
|
hr = IStream_Read(input, item->value.u.pszVal, count, &bytesread);
|
||||||
if (FAILED(hr))
|
if (bytesread != count) hr = E_FAIL;
|
||||||
|
if (hr != S_OK)
|
||||||
{
|
{
|
||||||
HeapFree(GetProcessHeap(), 0, item->value.u.pszVal);
|
HeapFree(GetProcessHeap(), 0, item->value.u.pszVal);
|
||||||
return hr;
|
return hr;
|
||||||
|
@ -1025,8 +1032,9 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry,
|
||||||
HeapFree(GetProcessHeap(), 0, item->value.u.blob.pBlobData);
|
HeapFree(GetProcessHeap(), 0, item->value.u.blob.pBlobData);
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
hr = IStream_Read(input, item->value.u.blob.pBlobData, count, NULL);
|
hr = IStream_Read(input, item->value.u.blob.pBlobData, count, &bytesread);
|
||||||
if (FAILED(hr))
|
if (bytesread != count) hr = E_FAIL;
|
||||||
|
if (hr != S_OK)
|
||||||
{
|
{
|
||||||
HeapFree(GetProcessHeap(), 0, item->value.u.blob.pBlobData);
|
HeapFree(GetProcessHeap(), 0, item->value.u.blob.pBlobData);
|
||||||
return hr;
|
return hr;
|
||||||
|
@ -1047,6 +1055,7 @@ static HRESULT LoadIfdMetadata(IStream *input, const GUID *preferred_vendor,
|
||||||
USHORT count, i;
|
USHORT count, i;
|
||||||
struct IFD_entry *entry;
|
struct IFD_entry *entry;
|
||||||
BOOL native_byte_order = TRUE;
|
BOOL native_byte_order = TRUE;
|
||||||
|
ULONG bytesread;
|
||||||
|
|
||||||
TRACE("\n");
|
TRACE("\n");
|
||||||
|
|
||||||
|
@ -1057,16 +1066,18 @@ static HRESULT LoadIfdMetadata(IStream *input, const GUID *preferred_vendor,
|
||||||
#endif
|
#endif
|
||||||
native_byte_order = FALSE;
|
native_byte_order = FALSE;
|
||||||
|
|
||||||
hr = IStream_Read(input, &count, sizeof(count), NULL);
|
hr = IStream_Read(input, &count, sizeof(count), &bytesread);
|
||||||
if (FAILED(hr)) return hr;
|
if (bytesread != sizeof(count)) hr = E_FAIL;
|
||||||
|
if (hr != S_OK) return hr;
|
||||||
|
|
||||||
SWAP_USHORT(count);
|
SWAP_USHORT(count);
|
||||||
|
|
||||||
entry = HeapAlloc(GetProcessHeap(), 0, count * sizeof(*entry));
|
entry = HeapAlloc(GetProcessHeap(), 0, count * sizeof(*entry));
|
||||||
if (!entry) return E_OUTOFMEMORY;
|
if (!entry) return E_OUTOFMEMORY;
|
||||||
|
|
||||||
hr = IStream_Read(input, entry, count * sizeof(*entry), NULL);
|
hr = IStream_Read(input, entry, count * sizeof(*entry), &bytesread);
|
||||||
if (FAILED(hr))
|
if (bytesread != count * sizeof(*entry)) hr = E_FAIL;
|
||||||
|
if (hr != S_OK)
|
||||||
{
|
{
|
||||||
HeapFree(GetProcessHeap(), 0, entry);
|
HeapFree(GetProcessHeap(), 0, entry);
|
||||||
return hr;
|
return hr;
|
||||||
|
@ -1079,8 +1090,9 @@ static HRESULT LoadIfdMetadata(IStream *input, const GUID *preferred_vendor,
|
||||||
LARGE_INTEGER pos;
|
LARGE_INTEGER pos;
|
||||||
USHORT next_ifd_count;
|
USHORT next_ifd_count;
|
||||||
|
|
||||||
hr = IStream_Read(input, &next_ifd_offset, sizeof(next_ifd_offset), NULL);
|
hr = IStream_Read(input, &next_ifd_offset, sizeof(next_ifd_offset), &bytesread);
|
||||||
if (FAILED(hr)) break;
|
if (bytesread != sizeof(next_ifd_offset)) hr = E_FAIL;
|
||||||
|
if (hr != S_OK) break;
|
||||||
|
|
||||||
SWAP_ULONG(next_ifd_offset);
|
SWAP_ULONG(next_ifd_offset);
|
||||||
if (!next_ifd_offset) break;
|
if (!next_ifd_offset) break;
|
||||||
|
@ -1089,8 +1101,9 @@ static HRESULT LoadIfdMetadata(IStream *input, const GUID *preferred_vendor,
|
||||||
hr = IStream_Seek(input, pos, SEEK_SET, NULL);
|
hr = IStream_Seek(input, pos, SEEK_SET, NULL);
|
||||||
if (FAILED(hr)) break;
|
if (FAILED(hr)) break;
|
||||||
|
|
||||||
hr = IStream_Read(input, &next_ifd_count, sizeof(next_ifd_count), NULL);
|
hr = IStream_Read(input, &next_ifd_count, sizeof(next_ifd_count), &bytesread);
|
||||||
if (FAILED(hr)) break;
|
if (bytesread != sizeof(next_ifd_count)) hr = E_FAIL;
|
||||||
|
if (hr != S_OK) break;
|
||||||
|
|
||||||
SWAP_USHORT(next_ifd_count);
|
SWAP_USHORT(next_ifd_count);
|
||||||
|
|
||||||
|
@ -1099,7 +1112,7 @@ static HRESULT LoadIfdMetadata(IStream *input, const GUID *preferred_vendor,
|
||||||
if (FAILED(hr)) break;
|
if (FAILED(hr)) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FAILED(hr) || i == 4096)
|
if (hr != S_OK || i == 4096)
|
||||||
{
|
{
|
||||||
HeapFree(GetProcessHeap(), 0, entry);
|
HeapFree(GetProcessHeap(), 0, entry);
|
||||||
return WINCODEC_ERR_BADMETADATAHEADER;
|
return WINCODEC_ERR_BADMETADATAHEADER;
|
||||||
|
|
Loading…
Reference in New Issue