PORT_SetError (SEC_ERROR_BAD_DER);
sec_asn1d_prepare_for_contents (sec_asn1d_state *state){    SECItem *item;    PRArenaPool *poolp;    unsigned long alloc_len;#ifdef DEBUG_ASN1D_STATES    {        printf("Found Length %d %s\n", state->contents_length,               state->indefinite ? "indefinite" : "");    }#endif    /*     * XXX I cannot decide if this allocation should exclude the case     *     where state->endofcontents is true -- figure it out!     */    if (state->allocate) {	void *dest;	PORT_Assert (state->dest == NULL);	/*	 * We are handling a POINTER or a member of a GROUP, and need to	 * allocate for the data structure.	 */	dest = sec_asn1d_zalloc (state->top->their_pool,				 state->theTemplate->size);	if (dest == NULL) {	    state->top->status = decodeError;	    return;	}	state->dest = (char *)dest + state->theTemplate->offset;	/*	 * For a member of a GROUP, our parent will later put the	 * pointer wherever it belongs.  But for a POINTER, we need	 * to record the destination now, in case notify or filter	 * procs need access to it -- they cannot find it otherwise,	 * until it is too late (for one-pass processing).	 */	if (state->parent->place == afterPointer) {	    void **placep;	    placep = state->parent->dest;	    *placep = dest;	}    }    /*     * Remember, length may be indefinite here!  In that case,     * both contents_length and pending will be zero.     */    state->pending = state->contents_length;    /* If this item has definite length encoding, and     ** is enclosed by a definite length constructed type,    ** make sure it isn't longer than the remaining space in that     ** constructed type.      */    if (state->contents_length > 0) {	sec_asn1d_state *parent = sec_asn1d_get_enclosing_construct(state);	if (parent && !parent->indefinite && 	    state->consumed + state->contents_length > parent->pending) {	    state->top->status = decodeError;	    return;	}    }    /*     * An EXPLICIT is nothing but an outer header, which we have     * already parsed and accepted.  Now we need to do the inner     * header and its contents.     */    if (state->explicit) {	state->place = afterExplicit;	state = sec_asn1d_push_state (state->top,				      SEC_ASN1GetSubtemplate(state->theTemplate,							     state->dest,							     PR_FALSE),				      state->dest, PR_TRUE);	if (state != NULL)	    state = sec_asn1d_init_state_based_on_template (state);	return;    }    /*     * For GROUP (SET OF, SEQUENCE OF), even if we know the length here     * we cannot tell how many items we will end up with ... so push a     * state that can keep track of "children" (the individual members     * of the group; we will allocate as we go and put them all together     * at the end.     */    if (state->underlying_kind & SEC_ASN1_GROUP) {	/* XXX If this assertion holds (should be able to confirm it via	 * inspection, too) then move this code into the switch statement	 * below under cases SET_OF and SEQUENCE_OF; it will be cleaner.	 */	PORT_Assert (state->underlying_kind == SEC_ASN1_SET_OF	   || state->underlying_kind == SEC_ASN1_SEQUENCE_OF	   || state->underlying_kind == (SEC_ASN1_SEQUENCE_OF|SEC_ASN1_DYNAMIC)	   || state->underlying_kind == (SEC_ASN1_SEQUENCE_OF|SEC_ASN1_DYNAMIC)		     );	if (state->contents_length != 0 || state->indefinite) {	    const SEC_ASN1Template *subt;	    state->place = duringGroup;	    subt = SEC_ASN1GetSubtemplate (state->theTemplate, state->dest,					   PR_FALSE);	    state = sec_asn1d_push_state (state->top, subt, NULL, PR_TRUE);	    if (state != NULL) {		if (!state->top->filter_only)		    state->allocate = PR_TRUE;	/* XXX propogate this? */		/*		 * Do the "before" field notification for next in group.		 */		sec_asn1d_notify_before (state->top, state->dest, state->depth);		state = sec_asn1d_init_state_based_on_template (state);	    }	} else {	    /*	     * A group of zero; we are done.	     * Set state to afterGroup and let that code plant the NULL.	     */	    state->place = afterGroup;	}	return;    }    switch (state->underlying_kind) {      case SEC_ASN1_SEQUENCE:	/*	 * We need to push a child to handle the individual fields.	 */	state->place = duringSequence;	state = sec_asn1d_push_state (state->top, state->theTemplate + 1,				      state->dest, PR_TRUE);	if (state != NULL) {	    /*	     * Do the "before" field notification.	     */	    sec_asn1d_notify_before (state->top, state->dest, state->depth);	    state = sec_asn1d_init_state_based_on_template (state);	}	break;      case SEC_ASN1_SET:	/* XXX SET is not really implemented */	/*	 * XXX A plain SET requires special handling; scanning of a	 * template to see where a field should go (because by definition,	 * they are not in any particular order, and you have to look at	 * each tag to disambiguate what the field is).  We may never	 * implement this because in practice, it seems to be unused.	 */	PORT_Assert(0);	state->top->status = decodeError;	break;      case SEC_ASN1_NULL:	/*	 * The NULL type, by definition, is "nothing", content length of zero.	 * An indefinite-length encoding is not alloweed.	 */	if (state->contents_length || state->indefinite) {	    state->top->status = decodeError;	    break;	}	if (state->dest != NULL) {	    item = (SECItem *)(state->dest);	    item->data = NULL;	    item->len = 0;	}	state->place = afterEndOfContents;	break;      case SEC_ASN1_BMP_STRING:	/* Error if length is not divisable by 2 */	if (state->contents_length % 2) {	   state->top->status = decodeError;	   break;	}   	/* otherwise, handle as other string types */	goto regular_string_type;      case SEC_ASN1_UNIVERSAL_STRING:	/* Error if length is not divisable by 4 */	if (state->contents_length % 4) {	   state->top->status = decodeError;	   break;	}   	/* otherwise, handle as other string types */	goto regular_string_type;      case SEC_ASN1_SKIP:      case SEC_ASN1_ANY:      case SEC_ASN1_ANY_CONTENTS:	/*	 * These are not (necessarily) strings, but they need nearly	 * identical handling (especially when we need to deal with	 * constructed sub-pieces), so we pretend they are.	 */	/* fallthru */regular_string_type:      case SEC_ASN1_BIT_STRING:      case SEC_ASN1_IA5_STRING:      case SEC_ASN1_OCTET_STRING:      case SEC_ASN1_PRINTABLE_STRING:      case SEC_ASN1_T61_STRING:      case SEC_ASN1_UTC_TIME:      case SEC_ASN1_UTF8_STRING:      case SEC_ASN1_VISIBLE_STRING:	/*	 * We are allocating for a primitive or a constructed string.	 * If it is a constructed string, it may also be indefinite-length.	 * If it is primitive, the length can (legally) be zero.	 * Our first order of business is to allocate the memory for	 * the string, if we can (if we know the length).	 */	item = (SECItem *)(state->dest);	/*	 * If the item is a definite-length constructed string, then	 * the contents_length is actually larger than what we need	 * (because it also counts each intermediate header which we	 * will be throwing away as we go), but it is a perfectly good	 * upper bound that we just allocate anyway, and then concat	 * as we go; we end up wasting a few extra bytes but save a	 * whole other copy.	 */	alloc_len = state->contents_length;	poolp = NULL;	/* quiet compiler warnings about unused... */	if (item == NULL || state->top->filter_only) {	    if (item != NULL) {		item->data = NULL;		item->len = 0;	    }	    alloc_len = 0;	} else if (state->substring) {	    /*	     * If we are a substring of a constructed string, then we may	     * not have to allocate anything (because our parent, the	     * actual constructed string, did it for us).  If we are a	     * substring and we *do* have to allocate, that means our	     * parent is an indefinite-length, so we allocate from our pool;	     * later our parent will copy our string into the aggregated	     * whole and free our pool allocation.	     */	    if (item->data == NULL) {		PORT_Assert (item->len == 0);		poolp = state->top->our_pool;	    } else {		alloc_len = 0;	    }	} else {	    item->len = 0;	    item->data = NULL;	    poolp = state->top->their_pool;	}	if (alloc_len || ((! state->indefinite)			  && (state->subitems_head != NULL))) {	    struct subitem *subitem;	    int len;	    PORT_Assert (item->len == 0 && item->data == NULL);	    /*	     * Check for and handle an ANY which has stashed aside the	     * header (identifier and length) bytes for us to include	     * in the saved contents.	     */	    if (state->subitems_head != NULL) {		PORT_Assert (state->underlying_kind == SEC_ASN1_ANY);		for (subitem = state->subitems_head;		     subitem != NULL; subitem = subitem->next)		    alloc_len += subitem->len;	    }	    item->data = (unsigned char*)sec_asn1d_zalloc (poolp, alloc_len);	    if (item->data == NULL) {		state->top->status = decodeError;		break;	    }	    len = 0;	    for (subitem = state->subitems_head;		 subitem != NULL; subitem = subitem->next) {		PORT_Memcpy (item->data + len, subitem->data, subitem->len);		len += subitem->len;	    }	    item->len = len;	    /*	     * Because we use arenas and have a mark set, we later free	     * everything we have allocated, so this does *not* present	     * a memory leak (it is just temporarily left dangling).	     */	    state->subitems_head = state->subitems_tail = NULL;	}	if (state->contents_length == 0 && (! state->indefinite)) {	    /*	     * A zero-length simple or constructed string; we are done.	     */	    state->place = afterEndOfContents;	} else if (state->found_tag_modifiers & SEC_ASN1_CONSTRUCTED) {	    const SEC_ASN1Template *sub;	    switch (state->underlying_kind) {	      case SEC_ASN1_ANY:	      case SEC_ASN1_ANY_CONTENTS:		sub = SEC_AnyTemplate;		break;	      case SEC_ASN1_BIT_STRING:		sub = SEC_BitStringTemplate;		break;	      case SEC_ASN1_BMP_STRING:		sub = SEC_BMPStringTemplate;		break;	      case SEC_ASN1_GENERALIZED_TIME:		sub = SEC_GeneralizedTimeTemplate;		break;	      case SEC_ASN1_IA5_STRING:		sub = SEC_IA5StringTemplate;		break;	      case SEC_ASN1_OCTET_STRING:		sub = SEC_OctetStringTemplate;		break;	      case SEC_ASN1_PRINTABLE_STRING:		sub = SEC_PrintableStringTemplate;		break;	      case SEC_ASN1_T61_STRING:		sub = SEC_T61StringTemplate;		break;	      case SEC_ASN1_UNIVERSAL_STRING:		sub = SEC_UniversalStringTemplate;		break;	      case SEC_ASN1_UTC_TIME:		sub = SEC_UTCTimeTemplate;		break;	      case SEC_ASN1_UTF8_STRING:		sub = SEC_UTF8StringTemplate;		break;	      case SEC_ASN1_VISIBLE_STRING:		sub = SEC_VisibleStringTemplate;		break;	      case SEC_ASN1_SKIP:		sub = SEC_SkipTemplate;		break;	      default:		/* redundant given outer switch cases, but */		PORT_Assert(0);	/* the compiler does not seem to know that, */		sub = NULL;	/* so just do enough to quiet it. */		break;	    }	    state->place = duringConstructedString;	    state = sec_asn1d_push_state (state->top, sub, item, PR_TRUE);	    if (state != NULL) {		state->substring = PR_TRUE;	/* XXX propogate? */		state = sec_asn1d_init_state_based_on_template (state);	    }	} else if (state->indefinite) {	    /*	     * An indefinite-length string *must* be constructed!	     */	    PORT_SetError (SEC_ERROR_BAD_DER);	    state->top->status = decodeError;	} else {	    /*	     * A non-zero-length simple string.	     */	    if (state->underlying_kind == SEC_ASN1_BIT_STRING)		state->place = beforeBitString;	    else		state->place = duringLeaf;	}	break;      default:	/*	 * We are allocating for a simple leaf item.	 */	if (state->contents_length) {	    if (state->dest != NULL) {		item = (SECItem *)(state->dest);		item->len = 0;		if (state->top->filter_only) {		    item->data = NULL;		} else {		    item->data = (unsigned char*)		                  sec_asn1d_zalloc (state->top->their_pool,						   state->contents_length);		    if (item->data == NULL) {			state->top->status = decodeError;			return;		    }		}	    }	    state->place = duringLeaf;	} else {	    /*	     * An indefinite-length or zero-length item is not allowed.	     * (All legal cases of such were handled above.)	     */	    PORT_SetError (SEC_ERROR_BAD_DER);	    state->top->status = decodeError;	}    }}