Diff for /libraries/liblber/decode.c between versions 1.121 and 1.124

version 1.121, 2009/07/29 20:38:19 version 1.124, 2009/08/07 14:04:25
Line 1 Line 1
 /* decode.c - ber input decoding routines */  /* decode.c - ber input decoding routines */
 /* $OpenLDAP: pkg/ldap/libraries/liblber/decode.c,v 1.120 2009/07/29 20:10:45 hallvard Exp $ */  /* $OpenLDAP: pkg/ldap/libraries/liblber/decode.c,v 1.123 2009/08/04 19:11:38 hallvard Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.  /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *   *
  * Copyright 1998-2009 The OpenLDAP Foundation.   * Copyright 1998-2009 The OpenLDAP Foundation.
Line 320  enum bgbvc { ChArray, BvArray, BvVec, Bv Line 320  enum bgbvc { ChArray, BvArray, BvVec, Bv
  * stack use to the absolute minimum.   * stack use to the absolute minimum.
  */   */
 typedef struct bgbvr {  typedef struct bgbvr {
         enum bgbvc choice;          const enum bgbvc choice;
         BerElement *ber;          const int alloc;        /* choice == BvOff ? 0 : LBER_ALLOC */
         int alloc;          ber_len_t siz;          /* input array element size, output count */
         ber_len_t siz;          ber_len_t off;          /* BvOff offset to the struct berval */
         ber_len_t off;          void *result;
         union {  
                 char ***c;  
                 BerVarray *ba;  
                 struct berval ***bv;  
         } res;  
 } bgbvr;  } bgbvr;
   
 static ber_tag_t  static ber_tag_t
 ber_get_stringbvl( bgbvr *b, ber_len_t *rlen )  ber_get_stringbvl( BerElement *ber, bgbvr *b )
 {  {
         int i = 0, n;          int i = 0, n;
         ber_tag_t tag;          ber_tag_t tag;
         ber_len_t len;          ber_len_t len, tot_size = 0, siz = b->siz;
         char *last, *orig;          char *last, *orig;
         struct berval bv, *bvp = NULL;          struct berval bv, *bvp = NULL;
           union stringbvl_u {
                   char **ca;                              /* ChArray */
                   BerVarray ba;                   /* BvArray */
                   struct berval **bv;             /* BvVec */
                   char *bo;                               /* BvOff */
           } res;
   
         /* For rewinding, just like ber_peek_tag() */          /* For rewinding, just like ber_peek_tag() */
         orig = b->ber->ber_ptr;          orig = ber->ber_ptr;
         tag = b->ber->ber_tag;          tag = ber->ber_tag;
   
         if ( ber_first_element( b->ber, &len, &last ) != LBER_DEFAULT ) {          if ( ber_first_element( ber, &len, &last ) != LBER_DEFAULT ) {
                 for ( ; b->ber->ber_ptr < last; i++ ) {                  for ( ; ber->ber_ptr < last; i++, tot_size += siz ) {
                         if (ber_skip_tag( b->ber, &len ) == LBER_DEFAULT) break;                          if ( ber_skip_tag( ber, &len ) == LBER_DEFAULT ) break;
                         b->ber->ber_ptr += len;                          ber->ber_ptr += len;
                         b->ber->ber_tag = *(unsigned char *)b->ber->ber_ptr;                          ber->ber_tag = *(unsigned char *) ber->ber_ptr;
                 }                  }
         }          }
   
         if ( rlen ) *rlen = i;          b->siz = i;
   
         if ( i == 0 ) {          if ( i == 0 ) {
                 *b->res.c = NULL;  
                 return 0;                  return 0;
         }          }
   
         n = i;          /* Allocate and NULL-terminate the result vector */
           b->result = ber_memalloc_x( tot_size + siz, ber->ber_memctx );
         /* Allocate the result vector */          if ( b->result == NULL ) {
                   return LBER_DEFAULT;
           }
         switch (b->choice) {          switch (b->choice) {
         case ChArray:          case ChArray:
                 *b->res.c = ber_memalloc_x( (n+1)*sizeof( char * ),                  res.ca = b->result;
                         b->ber->ber_memctx);                  res.ca[i] = NULL;
                 if ( *b->res.c == NULL ) return LBER_DEFAULT;  
                 (*b->res.c)[n] = NULL;  
                 break;                  break;
         case BvArray:          case BvArray:
                 *b->res.ba = ber_memalloc_x( (n+1)*sizeof( struct berval ),                  res.ba = b->result;
                         b->ber->ber_memctx);                  res.ba[i].bv_val = NULL;
                 if ( *b->res.ba == NULL ) return LBER_DEFAULT;  
                 (*b->res.ba)[n].bv_val = NULL;  
                 break;                  break;
         case BvVec:          case BvVec:
                 *b->res.bv = ber_memalloc_x( (n+1)*sizeof( struct berval *),                  res.bv = b->result;
                         b->ber->ber_memctx);                  res.bv[i] = NULL;
                 if ( *b->res.bv == NULL ) return LBER_DEFAULT;  
                 (*b->res.bv)[n] = NULL;  
                 break;                  break;
         case BvOff:          case BvOff:
                 *b->res.ba = ber_memalloc_x( (n+1) * b->siz, b->ber->ber_memctx );                  res.bo = (char *) b->result + b->off;
                 if ( *b->res.ba == NULL ) return LBER_DEFAULT;                  ((struct berval *) (res.bo + tot_size))->bv_val = NULL;
                 ((struct berval *)((char *)(*b->res.ba) + n*b->siz +  
                         b->off))->bv_val = NULL;  
                 break;                  break;
         }          }
         b->ber->ber_ptr = orig;          ber->ber_ptr = orig;
         b->ber->ber_tag = tag;          ber->ber_tag = tag;
         ber_skip_tag( b->ber, &len );          ber_skip_tag( ber, &len );
           
         for (n=0; n<i; n++)          tot_size = 0;
         {          n = 0;
                 tag = ber_next_element( b->ber, &len, last );          do {
                 if ( ber_get_stringbv( b->ber, &bv, b->alloc ) == LBER_DEFAULT ) {                  tag = ber_next_element( ber, &len, last );
                   if ( ber_get_stringbv( ber, &bv, b->alloc ) == LBER_DEFAULT ) {
                         goto nomem;                          goto nomem;
                 }                  }
   
                 /* store my result */                  /* store my result */
                 switch (b->choice) {                  switch (b->choice) {
                 case ChArray:                  case ChArray:
                         (*b->res.c)[n] = bv.bv_val;                          res.ca[n] = bv.bv_val;
                         break;                          break;
                 case BvArray:                  case BvArray:
                         (*b->res.ba)[n] = bv;                          res.ba[n] = bv;
                         break;                          break;
                 case BvVec:                  case BvVec:
                         bvp = ber_memalloc_x( sizeof( struct berval ), b->ber->ber_memctx);                          bvp = ber_memalloc_x( sizeof( struct berval ),
                                   ber->ber_memctx );
                         if ( !bvp ) {                          if ( !bvp ) {
                                 ber_memfree_x( bv.bv_val, b->ber->ber_memctx );                                  ber_memfree_x( bv.bv_val, ber->ber_memctx );
                                 goto nomem;                                  goto nomem;
                         }                          }
                         (*b->res.bv)[n] = bvp;                          res.bv[n] = bvp;
                         *bvp = bv;                          *bvp = bv;
                         break;                          break;
                 case BvOff:                  case BvOff:
                         *(BerVarray)((char *)(*b->res.ba)+n*b->siz+b->off) = bv;                          *(struct berval *)(res.bo + tot_size) = bv;
                           tot_size += siz;
                         break;                          break;
                 }                  }
         }          } while (++n < i);
         return tag;          return tag;
   
 nomem:  nomem:
         if (b->alloc || b->choice == BvVec) {          if (b->choice != BvOff) {       /* BvOff does not have b->alloc set */
                 for (--n; n>=0; n--) {                  while (--n >= 0) {
                         switch(b->choice) {                          switch(b->choice) {
                         case ChArray:                          case ChArray:
                                 ber_memfree_x((*b->res.c)[n], b->ber->ber_memctx);                                  ber_memfree_x(res.ca[n], ber->ber_memctx);
                                 break;                                  break;
                         case BvArray:                          case BvArray:
                                 ber_memfree_x((*b->res.ba)[n].bv_val, b->ber->ber_memctx);                                  ber_memfree_x(res.ba[n].bv_val, ber->ber_memctx);
                                 break;                                  break;
                         case BvVec:                          case BvVec:
                                 ber_memfree_x((*b->res.bv)[n]->bv_val, b->ber->ber_memctx);                                  ber_memfree_x(res.bv[n]->bv_val, ber->ber_memctx);
                                 ber_memfree_x((*b->res.bv)[n], b->ber->ber_memctx);                                  ber_memfree_x(res.bv[n], ber->ber_memctx);
                                 break;                                  break;
                         default:                          default:
                                 break;                                  break;
                         }                          }
                 }                  }
         }          }
         ber_memfree_x(*b->res.c, b->ber->ber_memctx);          ber_memfree_x(b->result, ber->ber_memctx);
         *b->res.c = NULL;          b->result = NULL;
         return LBER_DEFAULT;          return LBER_DEFAULT;
 }  }
   
Line 745  ber_scanf ( BerElement *ber, Line 741  ber_scanf ( BerElement *ber,
                         break;                          break;
   
                 case 'e':       /* enumerated */                  case 'e':       /* enumerated */
                 case 'i':       /* int */                  case 'i':       /* integer */
                         i = va_arg( ap, ber_int_t * );                          i = va_arg( ap, ber_int_t * );
                         rc = ber_get_int( ber, i );                          rc = ber_get_int( ber, i );
                         break;                          break;
Line 766  ber_scanf ( BerElement *ber, Line 762  ber_scanf ( BerElement *ber,
                                  * len ptr on finish. parsed in-place.                                   * len ptr on finish. parsed in-place.
                                  */                                   */
                 {                  {
                         bgbvr cookie = { BvOff };                          bgbvr cookie = { BvOff, 0 };
                         cookie.ber = ber;                          bvp = va_arg( ap, struct berval ** );
                         cookie.res.ba = va_arg( ap, struct berval ** );  
                         cookie.alloc = 0;  
                         l = va_arg( ap, ber_len_t * );                          l = va_arg( ap, ber_len_t * );
                         cookie.siz = *l;                          cookie.siz = *l;
                         cookie.off = va_arg( ap, ber_len_t );                          cookie.off = va_arg( ap, ber_len_t );
                         rc = ber_get_stringbvl( &cookie, l );                          rc = ber_get_stringbvl( ber, &cookie );
                           *bvp = cookie.result;
                           *l = cookie.siz;
                         break;                          break;
                 }                  }
   
Line 809  ber_scanf ( BerElement *ber, Line 805  ber_scanf ( BerElement *ber,
   
                 case 'v':       /* sequence of strings */                  case 'v':       /* sequence of strings */
                 {                  {
                         bgbvr cookie = { ChArray };                          bgbvr cookie = {
                         cookie.ber = ber;                                  ChArray, LBER_BV_ALLOC, sizeof( char * )
                         cookie.res.c = va_arg( ap, char *** );                          };
                         cookie.alloc = LBER_BV_ALLOC;                          rc = ber_get_stringbvl( ber, &cookie );
                         rc = ber_get_stringbvl( &cookie, NULL );                          *(va_arg( ap, char *** )) = cookie.result;
                         break;                          break;
                 }                  }
   
                 case 'V':       /* sequence of strings + lengths */                  case 'V':       /* sequence of strings + lengths */
                 {                  {
                         bgbvr cookie = { BvVec };                          bgbvr cookie = {
                         cookie.ber = ber;                                  BvVec, LBER_BV_ALLOC, sizeof( struct berval * )
                         cookie.res.bv = va_arg( ap, struct berval *** );                          };
                         cookie.alloc = LBER_BV_ALLOC;                          rc = ber_get_stringbvl( ber, &cookie );
                         rc = ber_get_stringbvl( &cookie, NULL );                          *(va_arg( ap, struct berval *** )) = cookie.result;
                         break;                          break;
                 }                  }
   
                 case 'W':       /* bvarray */                  case 'W':       /* bvarray */
                 {                  {
                         bgbvr cookie = { BvArray };                          bgbvr cookie = {
                         cookie.ber = ber;                                  BvArray, LBER_BV_ALLOC, sizeof( struct berval )
                         cookie.res.ba = va_arg( ap, struct berval ** );                          };
                         cookie.alloc = LBER_BV_ALLOC;                          rc = ber_get_stringbvl( ber, &cookie );
                         rc = ber_get_stringbvl( &cookie, NULL );                          *(va_arg( ap, struct berval ** )) = cookie.result;
                         break;                          break;
                 }                  }
   
Line 899  ber_scanf ( BerElement *ber, Line 895  ber_scanf ( BerElement *ber,
   
                 case 'b':       /* boolean */                  case 'b':       /* boolean */
                 case 'e':       /* enumerated */                  case 'e':       /* enumerated */
                 case 'i':       /* int */                  case 'i':       /* integer */
                         (void) va_arg( ap, int * );                          (void) va_arg( ap, ber_int_t * );
                         break;                          break;
   
                 case 'l':       /* length of next item */                  case 'l':       /* length of next item */
Line 914  ber_scanf ( BerElement *ber, Line 910  ber_scanf ( BerElement *ber,
   
                 case 'M':       /* BVoff array in-place */                  case 'M':       /* BVoff array in-place */
                         bvp = va_arg( ap, struct berval ** );                          bvp = va_arg( ap, struct berval ** );
                         ber_memfree_x( bvp, ber->ber_memctx );                          ber_memfree_x( *bvp, ber->ber_memctx );
                         *bvp = NULL;                          *bvp = NULL;
                         *(va_arg( ap, ber_len_t * )) = 0;                          *(va_arg( ap, ber_len_t * )) = 0;
                         (void) va_arg( ap, ber_len_t );                          (void) va_arg( ap, ber_len_t );

Removed from v.1.121  
changed lines
  Added in v.1.124


______________
© Copyright 1998-2020, OpenLDAP Foundation, info@OpenLDAP.org