From 78e02675abfcf1dc71344f16f8bb88990139de2d Mon Sep 17 00:00:00 2001 From: Matteo Bruni Date: Tue, 26 Aug 2014 18:07:17 +0200 Subject: [PATCH] d3dx9: Correctly handle out of memory conditions while reallocating children array. --- dlls/d3dx9_36/xfile.c | 75 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 60 insertions(+), 15 deletions(-) diff --git a/dlls/d3dx9_36/xfile.c b/dlls/d3dx9_36/xfile.c index f5f3bae7cad..7386ec905ba 100644 --- a/dlls/d3dx9_36/xfile.c +++ b/dlls/d3dx9_36/xfile.c @@ -298,6 +298,7 @@ static HRESULT d3dx9_file_data_create(IDirectXFileObject *dxfile_object, ID3DXFi { struct d3dx9_file_data *object; IDirectXFileObject *data_object; + unsigned int children_array_size = 0; HRESULT ret; TRACE("dxfile_object %p, ret_iface %p.\n", dxfile_object, ret_iface); @@ -338,14 +339,27 @@ static HRESULT d3dx9_file_data_create(IDirectXFileObject *dxfile_object, ID3DXFi while (SUCCEEDED(ret = IDirectXFileData_GetNextObject(object->dxfile_data, &data_object))) { - if (object->children) - object->children = HeapReAlloc(GetProcessHeap(), 0, object->children, sizeof(ID3DXFileData*) * (object->nb_children + 1)); - else - object->children = HeapAlloc(GetProcessHeap(), 0, sizeof(ID3DXFileData*)); - if (!object->children) + if (object->nb_children >= children_array_size) { - ret = E_OUTOFMEMORY; - break; + ID3DXFileData **new_children; + + if (object->children) + { + children_array_size *= 2; + new_children = HeapReAlloc(GetProcessHeap(), 0, object->children, + sizeof(*object->children) * children_array_size); + } + else + { + children_array_size = 4; + new_children = HeapAlloc(GetProcessHeap(), 0, sizeof(*object->children) * children_array_size); + } + if (!new_children) + { + ret = E_OUTOFMEMORY; + break; + } + object->children = new_children; } ret = d3dx9_file_data_create(data_object, &object->children[object->nb_children]); IUnknown_Release(data_object); @@ -353,12 +367,20 @@ static HRESULT d3dx9_file_data_create(IDirectXFileObject *dxfile_object, ID3DXFi break; object->nb_children++; } - if (ret != DXFILEERR_NOMOREOBJECTS) { (&object->ID3DXFileData_iface)->lpVtbl->Release(&object->ID3DXFileData_iface); return ret; } + if (object->children) + { + ID3DXFileData **new_children; + + new_children = HeapReAlloc(GetProcessHeap(), 0, object->children, + sizeof(*object->children) * object->nb_children); + if (new_children) + object->children = new_children; + } TRACE("Found %u children\n", object->nb_children); @@ -537,6 +559,7 @@ static HRESULT WINAPI d3dx9_file_CreateEnumObject(ID3DXFile *iface, const void * DXFILELOADRESOURCE dxfile_resource; DXFILELOADMEMORY dxfile_memory; IDirectXFileData *data_object; + unsigned children_array_size = 0; HRESULT ret; TRACE("iface %p, source %p, options %#x, enum_object %p.\n", iface, source, options, enum_object); @@ -594,14 +617,27 @@ static HRESULT WINAPI d3dx9_file_CreateEnumObject(ID3DXFile *iface, const void * /* Fill enum object with top level data objects */ while (SUCCEEDED(ret = IDirectXFileEnumObject_GetNextDataObject(dxfile_enum_object, &data_object))) { - if (object->children) - object->children = HeapReAlloc(GetProcessHeap(), 0, object->children, sizeof(*object->children) * (object->nb_children + 1)); - else - object->children = HeapAlloc(GetProcessHeap(), 0, sizeof(*object->children)); - if (!object->children) + if (object->nb_children >= children_array_size) { - ret = E_OUTOFMEMORY; - break; + ID3DXFileData **new_children; + + if (object->children) + { + children_array_size *= 2; + new_children = HeapReAlloc(GetProcessHeap(), 0, object->children, + sizeof(*object->children) * children_array_size); + } + else + { + children_array_size = 4; + new_children = HeapAlloc(GetProcessHeap(), 0, sizeof(*object->children) * children_array_size); + } + if (!new_children) + { + ret = E_OUTOFMEMORY; + break; + } + object->children = new_children; } ret = d3dx9_file_data_create((IDirectXFileObject*)data_object, &object->children[object->nb_children]); @@ -610,6 +646,15 @@ static HRESULT WINAPI d3dx9_file_CreateEnumObject(ID3DXFile *iface, const void * break; object->nb_children++; } + if (object->children) + { + ID3DXFileData **new_children; + + new_children = HeapReAlloc(GetProcessHeap(), 0, object->children, + sizeof(*object->children) * object->nb_children); + if (new_children) + object->children = new_children; + } IDirectXFileEnumObject_Release(dxfile_enum_object);