From 30140d0186ec570857bbcaff6d428753aa3e2b38 Mon Sep 17 00:00:00 2001 From: Christian Costa Date: Tue, 24 Mar 2009 23:59:37 +0100 Subject: [PATCH] d3dxof: Remove limitation on data buffer size. --- dlls/d3dxof/d3dxof.c | 22 +++++++--------------- dlls/d3dxof/d3dxof_private.h | 4 +--- dlls/d3dxof/parsing.c | 36 ++++++++++++++++++++++-------------- 3 files changed, 30 insertions(+), 32 deletions(-) diff --git a/dlls/d3dxof/d3dxof.c b/dlls/d3dxof/d3dxof.c index f46a82c91b3..6f9b266c782 100644 --- a/dlls/d3dxof/d3dxof.c +++ b/dlls/d3dxof/d3dxof.c @@ -628,10 +628,11 @@ static ULONG WINAPI IDirectXFileDataImpl_Release(IDirectXFileData* iface) if (!ref) { - if (!This->level) + if (!This->level && !This->from_ref) { - HeapFree(GetProcessHeap(), 0, This->pdata); HeapFree(GetProcessHeap(), 0, This->pstrings); + HeapFree(GetProcessHeap(), 0, This->pobj->pdata); + HeapFree(GetProcessHeap(), 0, This->pobj); } HeapFree(GetProcessHeap(), 0, This); } @@ -1000,10 +1001,7 @@ static ULONG WINAPI IDirectXFileEnumObjectImpl_Release(IDirectXFileEnumObject* i { int i; for (i = 0; i < This->nb_xobjects; i++) - { IDirectXFileData_Release(This->pRefObjects[i]); - HeapFree(GetProcessHeap(), 0, This->xobjects[i]); - } if (This->source == DXFILELOAD_FROMFILE) { UnmapViewOfFile(This->buffer); @@ -1024,7 +1022,6 @@ static HRESULT WINAPI IDirectXFileEnumObjectImpl_GetNextDataObject(IDirectXFileE IDirectXFileEnumObjectImpl *This = (IDirectXFileEnumObjectImpl *)iface; IDirectXFileDataImpl* object; HRESULT hr; - LPBYTE pdata = NULL; LPBYTE pstrings = NULL; TRACE("(%p/%p)->(%p)\n", This, iface, ppDataObj); @@ -1056,14 +1053,8 @@ static HRESULT WINAPI IDirectXFileEnumObjectImpl_GetNextDataObject(IDirectXFileE } This->buf.pxo = This->xobjects[This->nb_xobjects] = This->buf.pxo_tab; - pdata = HeapAlloc(GetProcessHeap(), 0, MAX_DATA_SIZE); - if (!pdata) - { - ERR("Out of memory\n"); - hr = DXFILEERR_BADALLOC; - goto error; - } - This->buf.pxo->pdata = This->buf.pdata = object->pdata = pdata; + This->buf.pxo->pdata = This->buf.pdata = NULL; + This->buf.capacity = 0; This->buf.cur_pos_data = 0; pstrings = HeapAlloc(GetProcessHeap(), 0, MAX_STRINGS_BUFFER); @@ -1109,8 +1100,9 @@ static HRESULT WINAPI IDirectXFileEnumObjectImpl_GetNextDataObject(IDirectXFileE error: HeapFree(GetProcessHeap(), 0, This->buf.pxo_tab); - HeapFree(GetProcessHeap(), 0, pdata); HeapFree(GetProcessHeap(), 0, pstrings); + if (This->buf.pxo->pdata) + HeapFree(GetProcessHeap(), 0, This->buf.pxo->pdata); return hr; } diff --git a/dlls/d3dxof/d3dxof_private.h b/dlls/d3dxof/d3dxof_private.h index 9cbd0e2c14f..13c5f547f64 100644 --- a/dlls/d3dxof/d3dxof_private.h +++ b/dlls/d3dxof/d3dxof_private.h @@ -42,8 +42,6 @@ #define MAX_SUBOBJECTS 500 #define MAX_STRINGS_BUFFER 10000 -#define MAX_DATA_SIZE 400000 - typedef struct { DWORD type; LONG idx_template; @@ -108,7 +106,6 @@ typedef struct { int cur_enum_object; BOOL from_ref; ULONG level; - LPBYTE pdata; LPBYTE pstrings; } IDirectXFileDataImpl; @@ -143,6 +140,7 @@ typedef struct { xtemplate* pxt[MAX_SUBOBJECTS]; ULONG level; LPBYTE pdata; + ULONG capacity; LPBYTE pstrings; } parse_buffer; diff --git a/dlls/d3dxof/parsing.c b/dlls/d3dxof/parsing.c index 85c66cbad4a..1205e48cbb2 100644 --- a/dlls/d3dxof/parsing.c +++ b/dlls/d3dxof/parsing.c @@ -995,6 +995,25 @@ BOOL parse_template(parse_buffer * buf) return TRUE; } +static BOOL check_buffer(parse_buffer * buf, ULONG size) +{ + if ((buf->cur_pos_data + size) > buf->capacity) + { + LPBYTE pdata; + ULONG new_capacity = buf->capacity ? 2 * buf->capacity : 100000; + + pdata = HeapAlloc(GetProcessHeap(), 0, new_capacity); + if (!pdata) + return FALSE; + memcpy(pdata, buf->pdata, buf->cur_pos_data); + HeapFree(GetProcessHeap(), 0, buf->pdata); + buf->capacity = new_capacity; + buf->pdata = pdata; + buf->pxo->root->pdata = pdata; + } + return TRUE; +} + static BOOL parse_object_parts(parse_buffer * buf, BOOL allow_optional); static BOOL parse_object_members_list(parse_buffer * buf) { @@ -1076,11 +1095,8 @@ static BOOL parse_object_members_list(parse_buffer * buf) last_dword = *(DWORD*)buf->value; TRACE("%s = %d\n", pt->members[i].name, *(DWORD*)buf->value); /* Assume larger size */ - if ((buf->cur_pos_data + 4) > MAX_DATA_SIZE) - { - FIXME("Buffer too small\n"); + if (!check_buffer(buf, 4)) return FALSE; - } if (pt->members[i].type == TOKEN_WORD) { *(((WORD*)(buf->cur_pos_data + buf->pdata))) = (WORD)(*(DWORD*)buf->value); @@ -1101,12 +1117,8 @@ static BOOL parse_object_members_list(parse_buffer * buf) { get_TOKEN(buf); TRACE("%s = %f\n", pt->members[i].name, *(float*)buf->value); - /* Assume larger size */ - if ((buf->cur_pos_data + 4) > MAX_DATA_SIZE) - { - FIXME("Buffer too small\n"); + if (!check_buffer(buf, 4)) return FALSE; - } if (pt->members[i].type == TOKEN_FLOAT) { *(((float*)(buf->cur_pos_data + buf->pdata))) = (float)(*(float*)buf->value); @@ -1122,12 +1134,8 @@ static BOOL parse_object_members_list(parse_buffer * buf) { get_TOKEN(buf); TRACE("%s = %s\n", pt->members[i].name, (char*)buf->value); - /* Assume larger size */ - if ((buf->cur_pos_data + 4) > MAX_DATA_SIZE) - { - FIXME("Buffer too small\n"); + if (!check_buffer(buf, 4)) return FALSE; - } if (pt->members[i].type == TOKEN_LPSTR) { int len = strlen((char*)buf->value) + 1;