Christian Costa : d3dxof: Remove limitation on data buffer size.

Alexandre Julliard julliard at winehq.org
Wed Mar 25 10:31:29 CDT 2009


Module: wine
Branch: master
Commit: 30140d0186ec570857bbcaff6d428753aa3e2b38
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=30140d0186ec570857bbcaff6d428753aa3e2b38

Author: Christian Costa <titan.costa at wanadoo.fr>
Date:   Tue Mar 24 23:59:37 2009 +0100

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 f46a82c..6f9b266 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 9cbd0e2..13c5f54 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 85c66cb..1205e48 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;




More information about the wine-cvs mailing list