d3dxof: Remove limitation on data buffer size.

oldstable
Christian Costa 2009-03-24 23:59:37 +01:00 committed by Alexandre Julliard
parent 60507cc651
commit 30140d0186
3 changed files with 30 additions and 32 deletions

View File

@ -628,10 +628,11 @@ static ULONG WINAPI IDirectXFileDataImpl_Release(IDirectXFileData* iface)
if (!ref) 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->pstrings);
HeapFree(GetProcessHeap(), 0, This->pobj->pdata);
HeapFree(GetProcessHeap(), 0, This->pobj);
} }
HeapFree(GetProcessHeap(), 0, This); HeapFree(GetProcessHeap(), 0, This);
} }
@ -1000,10 +1001,7 @@ static ULONG WINAPI IDirectXFileEnumObjectImpl_Release(IDirectXFileEnumObject* i
{ {
int i; int i;
for (i = 0; i < This->nb_xobjects; i++) for (i = 0; i < This->nb_xobjects; i++)
{
IDirectXFileData_Release(This->pRefObjects[i]); IDirectXFileData_Release(This->pRefObjects[i]);
HeapFree(GetProcessHeap(), 0, This->xobjects[i]);
}
if (This->source == DXFILELOAD_FROMFILE) if (This->source == DXFILELOAD_FROMFILE)
{ {
UnmapViewOfFile(This->buffer); UnmapViewOfFile(This->buffer);
@ -1024,7 +1022,6 @@ static HRESULT WINAPI IDirectXFileEnumObjectImpl_GetNextDataObject(IDirectXFileE
IDirectXFileEnumObjectImpl *This = (IDirectXFileEnumObjectImpl *)iface; IDirectXFileEnumObjectImpl *This = (IDirectXFileEnumObjectImpl *)iface;
IDirectXFileDataImpl* object; IDirectXFileDataImpl* object;
HRESULT hr; HRESULT hr;
LPBYTE pdata = NULL;
LPBYTE pstrings = NULL; LPBYTE pstrings = NULL;
TRACE("(%p/%p)->(%p)\n", This, iface, ppDataObj); 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; This->buf.pxo = This->xobjects[This->nb_xobjects] = This->buf.pxo_tab;
pdata = HeapAlloc(GetProcessHeap(), 0, MAX_DATA_SIZE); This->buf.pxo->pdata = This->buf.pdata = NULL;
if (!pdata) This->buf.capacity = 0;
{
ERR("Out of memory\n");
hr = DXFILEERR_BADALLOC;
goto error;
}
This->buf.pxo->pdata = This->buf.pdata = object->pdata = pdata;
This->buf.cur_pos_data = 0; This->buf.cur_pos_data = 0;
pstrings = HeapAlloc(GetProcessHeap(), 0, MAX_STRINGS_BUFFER); pstrings = HeapAlloc(GetProcessHeap(), 0, MAX_STRINGS_BUFFER);
@ -1109,8 +1100,9 @@ static HRESULT WINAPI IDirectXFileEnumObjectImpl_GetNextDataObject(IDirectXFileE
error: error:
HeapFree(GetProcessHeap(), 0, This->buf.pxo_tab); HeapFree(GetProcessHeap(), 0, This->buf.pxo_tab);
HeapFree(GetProcessHeap(), 0, pdata);
HeapFree(GetProcessHeap(), 0, pstrings); HeapFree(GetProcessHeap(), 0, pstrings);
if (This->buf.pxo->pdata)
HeapFree(GetProcessHeap(), 0, This->buf.pxo->pdata);
return hr; return hr;
} }

View File

@ -42,8 +42,6 @@
#define MAX_SUBOBJECTS 500 #define MAX_SUBOBJECTS 500
#define MAX_STRINGS_BUFFER 10000 #define MAX_STRINGS_BUFFER 10000
#define MAX_DATA_SIZE 400000
typedef struct { typedef struct {
DWORD type; DWORD type;
LONG idx_template; LONG idx_template;
@ -108,7 +106,6 @@ typedef struct {
int cur_enum_object; int cur_enum_object;
BOOL from_ref; BOOL from_ref;
ULONG level; ULONG level;
LPBYTE pdata;
LPBYTE pstrings; LPBYTE pstrings;
} IDirectXFileDataImpl; } IDirectXFileDataImpl;
@ -143,6 +140,7 @@ typedef struct {
xtemplate* pxt[MAX_SUBOBJECTS]; xtemplate* pxt[MAX_SUBOBJECTS];
ULONG level; ULONG level;
LPBYTE pdata; LPBYTE pdata;
ULONG capacity;
LPBYTE pstrings; LPBYTE pstrings;
} parse_buffer; } parse_buffer;

View File

@ -995,6 +995,25 @@ BOOL parse_template(parse_buffer * buf)
return TRUE; 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_parts(parse_buffer * buf, BOOL allow_optional);
static BOOL parse_object_members_list(parse_buffer * buf) 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; last_dword = *(DWORD*)buf->value;
TRACE("%s = %d\n", pt->members[i].name, *(DWORD*)buf->value); TRACE("%s = %d\n", pt->members[i].name, *(DWORD*)buf->value);
/* Assume larger size */ /* Assume larger size */
if ((buf->cur_pos_data + 4) > MAX_DATA_SIZE) if (!check_buffer(buf, 4))
{
FIXME("Buffer too small\n");
return FALSE; return FALSE;
}
if (pt->members[i].type == TOKEN_WORD) if (pt->members[i].type == TOKEN_WORD)
{ {
*(((WORD*)(buf->cur_pos_data + buf->pdata))) = (WORD)(*(DWORD*)buf->value); *(((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); get_TOKEN(buf);
TRACE("%s = %f\n", pt->members[i].name, *(float*)buf->value); TRACE("%s = %f\n", pt->members[i].name, *(float*)buf->value);
/* Assume larger size */ if (!check_buffer(buf, 4))
if ((buf->cur_pos_data + 4) > MAX_DATA_SIZE)
{
FIXME("Buffer too small\n");
return FALSE; return FALSE;
}
if (pt->members[i].type == TOKEN_FLOAT) if (pt->members[i].type == TOKEN_FLOAT)
{ {
*(((float*)(buf->cur_pos_data + buf->pdata))) = (float)(*(float*)buf->value); *(((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); get_TOKEN(buf);
TRACE("%s = %s\n", pt->members[i].name, (char*)buf->value); TRACE("%s = %s\n", pt->members[i].name, (char*)buf->value);
/* Assume larger size */ if (!check_buffer(buf, 4))
if ((buf->cur_pos_data + 4) > MAX_DATA_SIZE)
{
FIXME("Buffer too small\n");
return FALSE; return FALSE;
}
if (pt->members[i].type == TOKEN_LPSTR) if (pt->members[i].type == TOKEN_LPSTR)
{ {
int len = strlen((char*)buf->value) + 1; int len = strlen((char*)buf->value) + 1;