fix for 8060 and switch to iterative annotation processing to reduce stack suck, a=mcafee, r=mccabe
git-svn-id: svn://10.0.0.236/trunk@46693 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -128,6 +128,8 @@ XPT_DoHeader(XPTCursor *cursor, XPTHeader **headerp)
|
||||
XPTHeader *header;
|
||||
PRUint32 ide_offset;
|
||||
int i;
|
||||
XPTAnnotation *ann, *next, **annp;
|
||||
|
||||
if (mode == XPT_DECODE) {
|
||||
header = XPT_NEWZAP(XPTHeader);
|
||||
if (!header)
|
||||
@@ -184,8 +186,27 @@ XPT_DoHeader(XPTCursor *cursor, XPTHeader **headerp)
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!DoAnnotation(cursor, &header->annotations))
|
||||
goto error;
|
||||
/*
|
||||
* Iterate through the annotations rather than recurring, to avoid blowing
|
||||
* the stack on large xpt files.
|
||||
*/
|
||||
ann = next = header->annotations;
|
||||
annp = &header->annotations;
|
||||
do {
|
||||
ann = next;
|
||||
if (!DoAnnotation(cursor, &ann))
|
||||
goto error;
|
||||
if (mode == XPT_DECODE) {
|
||||
/*
|
||||
* Make sure that we store the address of the newly allocated
|
||||
* annotation in the previous annotation's ``next'' slot, or
|
||||
* header->annotations for the first one.
|
||||
*/
|
||||
*annp = ann;
|
||||
annp = &ann->next;
|
||||
}
|
||||
next = ann->next;
|
||||
} while (!XPT_ANN_IS_LAST(ann->flags));
|
||||
|
||||
/* shouldn't be necessary now, but maybe later */
|
||||
XPT_SeekTo(cursor, ide_offset);
|
||||
@@ -563,7 +584,7 @@ DoConstDescriptor(XPTCursor *cursor, XPTConstDescriptor *cd)
|
||||
ok = XPT_Do32(cursor, &cd->value.ui32);
|
||||
break;
|
||||
case TD_UINT64:
|
||||
ok = XPT_Do64(cursor, &cd->value.ui64);
|
||||
ok = XPT_Do64(cursor, (PRInt64 *)&cd->value.ui64);
|
||||
break;
|
||||
case TD_CHAR:
|
||||
ok = XPT_Do8(cursor, (PRUint8*) &cd->value.ch);
|
||||
@@ -736,20 +757,9 @@ DoAnnotation(XPTCursor *cursor, XPTAnnotation **annp)
|
||||
!XPT_DoStringInline(cursor, &ann->private_data))
|
||||
goto error_2;
|
||||
}
|
||||
|
||||
/*
|
||||
* If a subsequent Annotation fails, what to do?
|
||||
* - free all annotations, return PR_FALSE? (current behaviour)
|
||||
* - free failed annotation only, return PR_FALSE (caller can check for
|
||||
* non-NULL *annp on PR_FALSE return to detect partial annotation
|
||||
* decoding)?
|
||||
*/
|
||||
if (!XPT_ANN_IS_LAST(ann->flags) &&
|
||||
!DoAnnotation(cursor, &ann->next))
|
||||
goto error_2;
|
||||
|
||||
return PR_TRUE;
|
||||
|
||||
|
||||
error_2:
|
||||
if (ann && XPT_ANN_IS_PRIVATE(ann->flags)) {
|
||||
XPT_FREEIF(ann->creator);
|
||||
|
||||
@@ -61,7 +61,7 @@ CheckForRepeat(XPTCursor *cursor, void **addrp, XPTPool pool, PRUint32 len,
|
||||
/* if we're in the data area and we're about to exceed the allocation */ \
|
||||
(CURS_POOL_OFFSET(cursor) + (space) > (cursor)->state->pool->allocated ? \
|
||||
/* then grow if we're in ENCODE mode */ \
|
||||
(ENCODING(cursor) ? GrowPool((cursor)->state->pool) \
|
||||
(ENCODING(cursor) ? GrowPool((cursor)->state->pool, 0) \
|
||||
/* and fail if we're in DECODE mode */ \
|
||||
: (DBG(("can't extend in DECODE")) && PR_FALSE)) \
|
||||
/* otherwise we're OK */ \
|
||||
@@ -220,16 +220,12 @@ XPT_DataOffset(XPTState *state, PRUint32 *data_offsetp)
|
||||
*data_offsetp = state->data_offset;
|
||||
}
|
||||
|
||||
XPT_PUBLIC_API(void)
|
||||
XPT_SetDataOffset(XPTState *state, PRUint32 data_offset)
|
||||
{
|
||||
state->data_offset = data_offset;
|
||||
}
|
||||
|
||||
/* if new_size is 0, just grow by the next chunk */
|
||||
static PRBool
|
||||
GrowPool(XPTDatapool *pool)
|
||||
GrowPool(XPTDatapool *pool, PRInt32 new_size)
|
||||
{
|
||||
char *newdata = realloc(pool->data, pool->allocated + XPT_GROW_CHUNK);
|
||||
char *newdata = realloc(pool->data, new_size ? new_size :
|
||||
pool->allocated + XPT_GROW_CHUNK);
|
||||
if (!newdata)
|
||||
return PR_FALSE;
|
||||
pool->data = newdata;
|
||||
@@ -237,6 +233,17 @@ GrowPool(XPTDatapool *pool)
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
XPT_PUBLIC_API(void)
|
||||
XPT_SetDataOffset(XPTState *state, PRUint32 data_offset)
|
||||
{
|
||||
state->data_offset = data_offset;
|
||||
/* make sure we've allocated enough space for the header */
|
||||
if (state->mode == XPT_ENCODE &&
|
||||
data_offset > state->pool->allocated) {
|
||||
(void)GrowPool(state->pool, data_offset);
|
||||
}
|
||||
}
|
||||
|
||||
XPT_PUBLIC_API(PRBool)
|
||||
XPT_MakeCursor(XPTState *state, XPTPool pool, PRUint32 len, XPTCursor *cursor)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user