From 8e48978fab82ddf03bf80cde19495a528e1f82ae Mon Sep 17 00:00:00 2001
From: Dmitry Timoshkov <dmitry@baikal.ru>
Date: Fri, 16 Dec 2016 18:08:51 +0800
Subject: windowscodecs: Tolerate partial reads in the IFD metadata loader.

---
 dlls/windowscodecs/metadatahandler.c | 47 +++++++++++++++---------------------
 1 file changed, 20 insertions(+), 27 deletions(-)

diff --git a/dlls/windowscodecs/metadatahandler.c b/dlls/windowscodecs/metadatahandler.c
index 571f8b5..d066306 100644
--- a/dlls/windowscodecs/metadatahandler.c
+++ b/dlls/windowscodecs/metadatahandler.c
@@ -777,7 +777,7 @@ static int tag_to_vt(SHORT tag)
 static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry,
                               MetadataItem *item, BOOL native_byte_order)
 {
-    ULONG count, value, i, bytesread;
+    ULONG count, value, i;
     SHORT type;
     LARGE_INTEGER pos;
     HRESULT hr;
@@ -819,7 +819,7 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry,
 
         item->value.vt |= VT_VECTOR;
         item->value.u.caub.cElems = count;
-        item->value.u.caub.pElems = HeapAlloc(GetProcessHeap(), 0, count);
+        item->value.u.caub.pElems = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, count);
         if (!item->value.u.caub.pElems) return E_OUTOFMEMORY;
 
         pos.QuadPart = value;
@@ -829,9 +829,8 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry,
             HeapFree(GetProcessHeap(), 0, item->value.u.caub.pElems);
             return hr;
         }
-        hr = IStream_Read(input, item->value.u.caub.pElems, count, &bytesread);
-        if (bytesread != count) hr = E_FAIL;
-        if (hr != S_OK)
+        hr = IStream_Read(input, item->value.u.caub.pElems, count, NULL);
+        if (FAILED(hr))
         {
             HeapFree(GetProcessHeap(), 0, item->value.u.caub.pElems);
             return hr;
@@ -864,7 +863,7 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry,
 
         item->value.vt |= VT_VECTOR;
         item->value.u.caui.cElems = count;
-        item->value.u.caui.pElems = HeapAlloc(GetProcessHeap(), 0, count * 2);
+        item->value.u.caui.pElems = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, count * 2);
         if (!item->value.u.caui.pElems) return E_OUTOFMEMORY;
 
         pos.QuadPart = value;
@@ -874,9 +873,8 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry,
             HeapFree(GetProcessHeap(), 0, item->value.u.caui.pElems);
             return hr;
         }
-        hr = IStream_Read(input, item->value.u.caui.pElems, count * 2, &bytesread);
-        if (bytesread != count * 2) hr = E_FAIL;
-        if (hr != S_OK)
+        hr = IStream_Read(input, item->value.u.caui.pElems, count * 2, NULL);
+        if (FAILED(hr))
         {
             HeapFree(GetProcessHeap(), 0, item->value.u.caui.pElems);
             return hr;
@@ -897,7 +895,7 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry,
 
         item->value.vt |= VT_VECTOR;
         item->value.u.caul.cElems = count;
-        item->value.u.caul.pElems = HeapAlloc(GetProcessHeap(), 0, count * 4);
+        item->value.u.caul.pElems = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, count * 4);
         if (!item->value.u.caul.pElems) return E_OUTOFMEMORY;
 
         pos.QuadPart = value;
@@ -907,9 +905,8 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry,
             HeapFree(GetProcessHeap(), 0, item->value.u.caul.pElems);
             return hr;
         }
-        hr = IStream_Read(input, item->value.u.caul.pElems, count * 4, &bytesread);
-        if (bytesread != count * 4) hr = E_FAIL;
-        if (hr != S_OK)
+        hr = IStream_Read(input, item->value.u.caul.pElems, count * 4, NULL);
+        if (FAILED(hr))
         {
             HeapFree(GetProcessHeap(), 0, item->value.u.caul.pElems);
             return hr;
@@ -935,8 +932,7 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry,
             hr = IStream_Seek(input, pos, SEEK_SET, NULL);
             if (FAILED(hr)) return hr;
 
-            hr = IStream_Read(input, &ull, sizeof(ull), &bytesread);
-            if (bytesread != sizeof(ull)) hr = E_FAIL;
+            hr = IStream_Read(input, &ull, sizeof(ull), NULL);
             if (hr != S_OK) return hr;
 
             item->value.u.uhVal.QuadPart = ull;
@@ -954,7 +950,7 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry,
         {
             item->value.vt |= VT_VECTOR;
             item->value.u.cauh.cElems = count;
-            item->value.u.cauh.pElems = HeapAlloc(GetProcessHeap(), 0, count * 8);
+            item->value.u.cauh.pElems = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, count * 8);
             if (!item->value.u.cauh.pElems) return E_OUTOFMEMORY;
 
             pos.QuadPart = value;
@@ -964,9 +960,8 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry,
                 HeapFree(GetProcessHeap(), 0, item->value.u.cauh.pElems);
                 return hr;
             }
-            hr = IStream_Read(input, item->value.u.cauh.pElems, count * 8, &bytesread);
-            if (bytesread != count * 8) hr = E_FAIL;
-            if (hr != S_OK)
+            hr = IStream_Read(input, item->value.u.cauh.pElems, count * 8, NULL);
+            if (FAILED(hr))
             {
                 HeapFree(GetProcessHeap(), 0, item->value.u.cauh.pElems);
                 return hr;
@@ -984,7 +979,7 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry,
         }
         break;
     case IFD_ASCII:
-        item->value.u.pszVal = HeapAlloc(GetProcessHeap(), 0, count + 1);
+        item->value.u.pszVal = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, count + 1);
         if (!item->value.u.pszVal) return E_OUTOFMEMORY;
 
         if (count <= 4)
@@ -1002,9 +997,8 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry,
             HeapFree(GetProcessHeap(), 0, item->value.u.pszVal);
             return hr;
         }
-        hr = IStream_Read(input, item->value.u.pszVal, count, &bytesread);
-        if (bytesread != count) hr = E_FAIL;
-        if (hr != S_OK)
+        hr = IStream_Read(input, item->value.u.pszVal, count, NULL);
+        if (FAILED(hr))
         {
             HeapFree(GetProcessHeap(), 0, item->value.u.pszVal);
             return hr;
@@ -1019,7 +1013,7 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry,
             break;
         }
 
-        item->value.u.blob.pBlobData = HeapAlloc(GetProcessHeap(), 0, count);
+        item->value.u.blob.pBlobData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, count);
         if (!item->value.u.blob.pBlobData) return E_OUTOFMEMORY;
 
         item->value.u.blob.cbSize = count;
@@ -1038,9 +1032,8 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry,
             HeapFree(GetProcessHeap(), 0, item->value.u.blob.pBlobData);
             return hr;
         }
-        hr = IStream_Read(input, item->value.u.blob.pBlobData, count, &bytesread);
-        if (bytesread != count) hr = E_FAIL;
-        if (hr != S_OK)
+        hr = IStream_Read(input, item->value.u.blob.pBlobData, count, NULL);
+        if (FAILED(hr))
         {
             HeapFree(GetProcessHeap(), 0, item->value.u.blob.pBlobData);
             return hr;
-- 
2.9.0

