From 8b3bb91e93390f84e597138e9c388f7205717dab Mon Sep 17 00:00:00 2001 From: Hallvard Furuseth Date: Wed, 29 Jul 2009 22:38:19 +0000 Subject: [PATCH] More ITS#6215: Fix ber_scanf(,"mMvVW",) cleanup on error: Parse args correctly and free up memory. Also set some lengths=0 and remove unneeded ptr==NULL tests before frees. --- libraries/liblber/decode.c | 65 ++++++++++++++++++++++++-------------- 1 file changed, 41 insertions(+), 24 deletions(-) diff --git a/libraries/liblber/decode.c b/libraries/liblber/decode.c index bf12181698..a256c521e6 100644 --- a/libraries/liblber/decode.c +++ b/libraries/liblber/decode.c @@ -686,8 +686,8 @@ ber_scanf ( BerElement *ber, { va_list ap; LDAP_CONST char *fmt_reset; - char *s, **ss; - struct berval **bvp, *bval; + char *s, **ss, ***sss; + struct berval *bval, **bvp, ***bvpp; ber_int_t *i; ber_len_t *l; ber_tag_t *t; @@ -893,10 +893,8 @@ ber_scanf ( BerElement *ber, case 'a': /* octet string - allocate storage as needed */ case 'A': ss = va_arg( ap, char ** ); - if ( *ss ) { - ber_memfree_x( *ss, ber->ber_memctx ); - *ss = NULL; - } + ber_memfree_x( *ss, ber->ber_memctx ); + *ss = NULL; break; case 'b': /* boolean */ @@ -906,29 +904,37 @@ ber_scanf ( BerElement *ber, break; case 'l': /* length of next item */ - (void) va_arg( ap, ber_len_t * ); + *(va_arg( ap, ber_len_t * )) = 0; + break; + + case 'm': /* berval in-place */ + bval = va_arg( ap, struct berval * ); + BER_BVZERO( bval ); + break; + + case 'M': /* BVoff array in-place */ + bvp = va_arg( ap, struct berval ** ); + ber_memfree_x( bvp, ber->ber_memctx ); + *bvp = NULL; + *(va_arg( ap, ber_len_t * )) = 0; + (void) va_arg( ap, ber_len_t ); break; case 'o': /* octet string in a supplied berval */ bval = va_arg( ap, struct berval * ); - if ( bval->bv_val != NULL ) { - ber_memfree_x( bval->bv_val, ber->ber_memctx ); - bval->bv_val = NULL; - } - bval->bv_len = 0; + ber_memfree_x( bval->bv_val, ber->ber_memctx ); + BER_BVZERO( bval ); break; case 'O': /* octet string - allocate & include length */ bvp = va_arg( ap, struct berval ** ); - if ( *bvp ) { - ber_bvfree( *bvp ); - *bvp = NULL; - } + ber_bvfree_x( *bvp, ber->ber_memctx ); + *bvp = NULL; break; case 's': /* octet string - in a buffer */ (void) va_arg( ap, char * ); - (void) va_arg( ap, ber_len_t * ); + *(va_arg( ap, ber_len_t * )) = 0; break; case 't': /* tag of next item */ @@ -938,19 +944,30 @@ ber_scanf ( BerElement *ber, case 'B': /* bit string - allocate storage as needed */ ss = va_arg( ap, char ** ); - if ( *ss ) { - ber_memfree_x( *ss, ber->ber_memctx ); - *ss = NULL; - } + ber_memfree_x( *ss, ber->ber_memctx ); + *ss = NULL; *(va_arg( ap, ber_len_t * )) = 0; /* for length, in bits */ break; - case 'm': /* berval in-place */ - case 'M': /* BVoff array in-place */ - case 'n': /* null */ case 'v': /* sequence of strings */ + sss = va_arg( ap, char *** ); + ber_memvfree_x( (void **) *sss, ber->ber_memctx ); + *sss = NULL; + break; + case 'V': /* sequence of strings + lengths */ + bvpp = va_arg( ap, struct berval *** ); + ber_bvecfree_x( *bvpp, ber->ber_memctx ); + *bvpp = NULL; + break; + case 'W': /* BerVarray */ + bvp = va_arg( ap, struct berval ** ); + ber_bvarray_free_x( *bvp, ber->ber_memctx ); + *bvp = NULL; + break; + + case 'n': /* null */ case 'x': /* skip the next element - whatever it is */ case '{': /* begin sequence */ case '[': /* begin set */