diff --git a/mozilla/xpcom/typelib/xpt/src/xpt_struct.c b/mozilla/xpcom/typelib/xpt/src/xpt_struct.c index f1dfe9496c1..4cef2d8a810 100644 --- a/mozilla/xpcom/typelib/xpt/src/xpt_struct.c +++ b/mozilla/xpcom/typelib/xpt/src/xpt_struct.c @@ -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); diff --git a/mozilla/xpcom/typelib/xpt/src/xpt_xdr.c b/mozilla/xpcom/typelib/xpt/src/xpt_xdr.c index 48a30e2f85a..15b6dfce3d6 100644 --- a/mozilla/xpcom/typelib/xpt/src/xpt_xdr.c +++ b/mozilla/xpcom/typelib/xpt/src/xpt_xdr.c @@ -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) {