From af67e5022bc0fc0a889b8402fa930408b9b77548 Mon Sep 17 00:00:00 2001 From: "nelsonb%netscape.com" Date: Sat, 17 May 2003 01:18:53 +0000 Subject: [PATCH] Correct offset arithmetic for "choice" templates. Bug 161580. Patch by wtc@netscape.com --- security/nss/lib/util/secasn1d.c | 10 +++++++--- security/nss/lib/util/secasn1e.c | 9 +++++---- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/security/nss/lib/util/secasn1d.c b/security/nss/lib/util/secasn1d.c index b842b23d868c..ddbf1396ca0a 100644 --- a/security/nss/lib/util/secasn1d.c +++ b/security/nss/lib/util/secasn1d.c @@ -35,7 +35,7 @@ * Support for DEcoding ASN.1 data based on BER/DER (Basic/Distinguished * Encoding Rules). * - * $Id: secasn1d.c,v 1.24 2003/05/03 06:54:48 nelsonb%netscape.com Exp $ + * $Id: secasn1d.c,v 1.25 2003/05/17 01:18:52 nelsonb%netscape.com Exp $ */ /* #define DEBUG_ASN1D_STATES 1 */ @@ -2298,7 +2298,8 @@ sec_asn1d_before_choice (sec_asn1d_state *state) } child = sec_asn1d_push_state(state->top, state->theTemplate + 1, - state->dest, PR_FALSE); + (char *)state->dest - state->theTemplate->offset, + PR_FALSE); if ((sec_asn1d_state *)NULL == child) { return (sec_asn1d_state *)NULL; } @@ -2326,6 +2327,7 @@ sec_asn1d_during_choice (sec_asn1d_state *state) if (child->missing) { unsigned char child_found_tag_modifiers = 0; unsigned long child_found_tag_number = 0; + void * dest; state->consumed += child->consumed; @@ -2347,6 +2349,7 @@ sec_asn1d_during_choice (sec_asn1d_state *state) return NULL; } + dest = (char *)child->dest - child->theTemplate->offset; child->theTemplate++; if (0 == child->theTemplate->kind) { @@ -2355,6 +2358,7 @@ sec_asn1d_during_choice (sec_asn1d_state *state) state->top->status = decodeError; return (sec_asn1d_state *)NULL; } + child->dest = (char *)dest + child->theTemplate->offset; /* cargo'd from next_in_sequence innards */ if (state->pending) { @@ -2400,7 +2404,7 @@ sec_asn1d_during_choice (sec_asn1d_state *state) } if ((void *)NULL != state->dest) { /* Store the enum */ - int *which = (int *)((char *)state->dest + state->theTemplate->offset); + int *which = (int *)state->dest; *which = (int)child->theTemplate->size; } diff --git a/security/nss/lib/util/secasn1e.c b/security/nss/lib/util/secasn1e.c index 107ff787f2dc..331031bd72c8 100644 --- a/security/nss/lib/util/secasn1e.c +++ b/security/nss/lib/util/secasn1e.c @@ -35,7 +35,7 @@ * Support for ENcoding ASN.1 data based on BER/DER (Basic/Distinguished * Encoding Rules). * - * $Id: secasn1e.c,v 1.10 2003/03/11 02:31:16 wtc%netscape.com Exp $ + * $Id: secasn1e.c,v 1.11 2003/05/17 01:18:53 nelsonb%netscape.com Exp $ */ #include "secasn1.h" @@ -466,7 +466,7 @@ sec_asn1e_which_choice ) { int rv; - unsigned int which = *(unsigned int *)((char *)src + theTemplate->offset); + unsigned int which = *(unsigned int *)src; for( rv = 1, theTemplate++; theTemplate->kind != 0; rv++, theTemplate++ ) { if( which == theTemplate->size ) { @@ -529,7 +529,7 @@ sec_asn1e_contents_length (const SEC_ASN1Template *theTemplate, void *src, return 0; } - src2 = (void *)((char *)src + theTemplate[indx].offset); + src2 = (void *)((char *)src - theTemplate->offset + theTemplate[indx].offset); return sec_asn1e_contents_length(&theTemplate[indx], src2, PR_FALSE, noheaderp); @@ -756,7 +756,8 @@ sec_asn1e_write_header (sec_asn1e_state *state) state->place = afterChoice; state = sec_asn1e_push_state(state->top, &state->theTemplate[indx], - state->src, PR_TRUE); + (char *)state->src - state->theTemplate->offset, + PR_TRUE); if( (sec_asn1e_state *)NULL != state ) { /*