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:
shaver%netscape.com
1999-09-10 02:48:32 +00:00
parent 5e1a8f8bd6
commit 4eb0eaf7ef
2 changed files with 41 additions and 24 deletions

View File

@@ -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);

View File

@@ -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)
{