Back to index

openldap  2.4.31
Classes | Typedefs | Enumerations | Functions
decode.c File Reference
#include "portable.h"
#include <stdio.h>
#include <ac/stdlib.h>
#include <ac/stdarg.h>
#include <ac/string.h>
#include <ac/socket.h>
#include "lber-int.h"

Go to the source code of this file.

Classes

struct  bgbvr

Typedefs

typedef struct bgbvr bgbvr

Enumerations

enum  bgbvc { ChArray, BvArray, BvVec, BvOff }

Functions

int ber_decode_oid (BerValue *in, BerValue *out)
static ber_tag_t ber_tag_and_rest (const BerElement *ber, struct berval *bv)
ber_tag_t ber_get_tag (BerElement *ber)
ber_tag_t ber_peek_element (const BerElement *ber, struct berval *bv)
ber_tag_t ber_skip_element (BerElement *ber, struct berval *bv)
ber_tag_t ber_peek_tag (BerElement *ber, ber_len_t *len)
ber_tag_t ber_skip_tag (BerElement *ber, ber_len_t *lenp)
ber_tag_t ber_get_int (BerElement *ber, ber_int_t *num)
ber_tag_t ber_get_enum (BerElement *ber, ber_int_t *num)
ber_tag_t ber_get_stringb (BerElement *ber, char *buf, ber_len_t *len)
static ber_tag_t ber_get_stringbvl (BerElement *ber, bgbvr *b)
ber_tag_t ber_get_stringbv (BerElement *ber, struct berval *bv, int option)
ber_tag_t ber_get_stringbv_null (BerElement *ber, struct berval *bv, int option)
ber_tag_t ber_get_stringa (BerElement *ber, char **buf)
ber_tag_t ber_get_stringa_null (BerElement *ber, char **buf)
ber_tag_t ber_get_stringal (BerElement *ber, struct berval **bv)
ber_tag_t ber_get_bitstringa (BerElement *ber, char **buf, ber_len_t *blen)
ber_tag_t ber_get_null (BerElement *ber)
ber_tag_t ber_get_boolean (BerElement *ber, ber_int_t *boolval)
ber_tag_t ber_first_element (BerElement *ber, ber_len_t *len, char **last)
ber_tag_t ber_next_element (BerElement *ber, ber_len_t *len, LDAP_CONST char *last)
ber_tag_t ber_scanf (BerElement *ber, LDAP_CONST char *fmt,...)

Class Documentation

struct bgbvr

Definition at line 346 of file decode.c.


Typedef Documentation

typedef struct bgbvr bgbvr

Enumeration Type Documentation

enum bgbvc
Enumerator:
ChArray 
BvArray 
BvVec 
BvOff 

Definition at line 341 of file decode.c.


Function Documentation

int ber_decode_oid ( BerValue in,
BerValue out 
)

Definition at line 45 of file decode.c.

{
       const unsigned char *der;
       unsigned long val;
       unsigned val1;
       ber_len_t i;
       char *ptr;

       assert( in != NULL );
       assert( out != NULL );

       /* need 4 chars/inbyte + \0 for input={7f 7f 7f...} */
       if ( !out->bv_val || (out->bv_len+3)/4 <= in->bv_len )
              return -1;

       ptr = NULL;
       der = (unsigned char *) in->bv_val;
       val = 0;
       for ( i=0; i < in->bv_len; i++ ) {
              val |= der[i] & 0x7f;
              if ( !( der[i] & 0x80 )) {
                     if ( ptr == NULL ) {
                            /* Initial "x.y": val=x*40+y, x<=2, y<40 if x<2 */
                            ptr = out->bv_val;
                            val1 = (val < 80 ? val/40 : 2);
                            val -= val1*40;
                            ptr += sprintf( ptr, "%u", val1 );
                     }
                     ptr += sprintf( ptr, ".%lu", val );
                     val = 0;
              } else if ( val - 1UL < LBER_OID_COMPONENT_MAX >> 7 ) {
                     val <<= 7;
              } else {
                     /* val would overflow, or is 0 from invalid initial 0x80 octet */
                     return -1;
              }
       }
       if ( ptr == NULL || val != 0 )
              return -1;

       out->bv_len = ptr - out->bv_val;
       return 0;
}

Here is the caller graph for this function:

ber_tag_t ber_first_element ( BerElement *  ber,
ber_len_t len,
char **  last 
)

Definition at line 657 of file decode.c.

{
       assert( last != NULL );

       /* skip the sequence header, use the len to mark where to stop */
       if ( ber_skip_tag( ber, len ) == LBER_DEFAULT ) {
              *last = NULL;
              return LBER_DEFAULT;
       }

       *last = ber->ber_ptr + *len;

       if ( *len == 0 ) {
              return LBER_DEFAULT;
       }

       return ber_peek_tag( ber, len );
}

Here is the call graph for this function:

Here is the caller graph for this function:

ber_tag_t ber_get_bitstringa ( BerElement *  ber,
char **  buf,
ber_len_t blen 
)

Definition at line 597 of file decode.c.

{
       ber_tag_t     tag;
       struct berval data;
       unsigned char unusedbits;

       assert( buf != NULL );
       assert( blen != NULL );

       if ( (tag = ber_skip_element( ber, &data )) == LBER_DEFAULT ) {
              goto fail;
       }

       if ( --data.bv_len > (ber_len_t)-1 / 8 ) {
              goto fail;
       }
       unusedbits = *(unsigned char *) data.bv_val++;
       if ( unusedbits > 7 ) {
              goto fail;
       }

       if ( memchr( data.bv_val, 0, data.bv_len )) {
              goto fail;
       }

       *buf = (char *) ber_memalloc_x( data.bv_len, ber->ber_memctx );
       if ( *buf == NULL ) {
              return LBER_DEFAULT;
       }
       memcpy( *buf, data.bv_val, data.bv_len );

       *blen = data.bv_len * 8 - unusedbits;
       return tag;

 fail:
       *buf = NULL;
       return LBER_DEFAULT;
}

Here is the call graph for this function:

Here is the caller graph for this function:

ber_tag_t ber_get_boolean ( BerElement *  ber,
ber_int_t *  boolval 
)

Definition at line 649 of file decode.c.

{
       return ber_get_int( ber, boolval );
}

Here is the call graph for this function:

Here is the caller graph for this function:

ber_tag_t ber_get_enum ( BerElement *  ber,
ber_int_t *  num 
)

Definition at line 303 of file decode.c.

{
       return ber_get_int( ber, num );
}

Here is the call graph for this function:

Here is the caller graph for this function:

ber_tag_t ber_get_int ( BerElement *  ber,
ber_int_t *  num 
)

Definition at line 263 of file decode.c.

{
       ber_tag_t     tag;
       ber_len_t     len;
       struct berval bv;

       assert( num != NULL );

       tag = ber_skip_element( ber, &bv );
       len = bv.bv_len;
       if ( tag == LBER_DEFAULT || len > sizeof(ber_int_t) ) {
              return LBER_DEFAULT;
       }

       /* parse two's complement integer */
       if( len ) {
              unsigned char *buf = (unsigned char *) bv.bv_val;
              ber_len_t i;
              ber_int_t netnum = buf[0] & 0xff;

              /* sign extend */
              netnum = (netnum ^ 0x80) - 0x80;

              /* shift in the bytes */
              for( i = 1; i < len; i++ ) {
                     netnum = (netnum << 8 ) | buf[i];
              }

              *num = netnum;

       } else {
              *num = 0;
       }

       return tag;
}

Here is the call graph for this function:

Here is the caller graph for this function:

ber_tag_t ber_get_null ( BerElement *  ber)

Definition at line 640 of file decode.c.

{
       ber_len_t     len;
       ber_tag_t     tag = ber_skip_tag( ber, &len );

       return( len == 0 ? tag : LBER_DEFAULT );
}

Here is the call graph for this function:

Here is the caller graph for this function:

ber_tag_t ber_get_stringa ( BerElement *  ber,
char **  buf 
)

Definition at line 547 of file decode.c.

{
       BerValue      bv;
       ber_tag_t     tag;

       assert( buf != NULL );

       tag = ber_get_stringbv( ber, &bv, LBER_BV_ALLOC | LBER_BV_STRING );
       *buf = bv.bv_val;

       return tag;
}

Here is the call graph for this function:

Here is the caller graph for this function:

ber_tag_t ber_get_stringa_null ( BerElement *  ber,
char **  buf 
)

Definition at line 561 of file decode.c.

{
       BerValue      bv;
       ber_tag_t     tag;

       assert( buf != NULL );

       tag = ber_get_stringbv_null( ber, &bv, LBER_BV_ALLOC | LBER_BV_STRING );
       *buf = bv.bv_val;

       return tag;
}

Here is the call graph for this function:

Here is the caller graph for this function:

ber_tag_t ber_get_stringal ( BerElement *  ber,
struct berval **  bv 
)

Definition at line 575 of file decode.c.

{
       ber_tag_t     tag;

       assert( ber != NULL );
       assert( bv != NULL );

       *bv = (struct berval *) ber_memalloc_x( sizeof(struct berval),
              ber->ber_memctx );
       if ( *bv == NULL ) {
              return LBER_DEFAULT;
       }

       tag = ber_get_stringbv( ber, *bv, LBER_BV_ALLOC );
       if ( tag == LBER_DEFAULT ) {
              ber_memfree_x( *bv, ber->ber_memctx );
              *bv = NULL;
       }
       return tag;
}

Here is the call graph for this function:

Here is the caller graph for this function:

ber_tag_t ber_get_stringb ( BerElement *  ber,
char *  buf,
ber_len_t len 
)

Definition at line 311 of file decode.c.

{
       struct berval bv;
       ber_tag_t     tag;

       if ( (tag = ber_skip_element( ber, &bv )) == LBER_DEFAULT ) {
              return LBER_DEFAULT;
       }

       /* must fit within allocated space with termination */
       if ( bv.bv_len >= *len ) {
              return LBER_DEFAULT;
       }

       memcpy( buf, bv.bv_val, bv.bv_len );
       buf[bv.bv_len] = '\0';

       *len = bv.bv_len;
       return tag;
}

Here is the call graph for this function:

Here is the caller graph for this function:

ber_tag_t ber_get_stringbv ( BerElement *  ber,
struct berval bv,
int  option 
)

Definition at line 477 of file decode.c.

{
       ber_tag_t     tag;
       char          *data;

       tag = ber_skip_element( ber, bv );
       if ( tag == LBER_DEFAULT ||
              (( option & LBER_BV_STRING ) &&
               bv->bv_len && memchr( bv->bv_val, 0, bv->bv_len - 1 )))
       {
              bv->bv_val = NULL;
              return LBER_DEFAULT;
       }

       data = bv->bv_val;
       if ( option & LBER_BV_ALLOC ) {
              bv->bv_val = (char *) ber_memalloc_x( bv->bv_len + 1,
                     ber->ber_memctx );
              if ( bv->bv_val == NULL ) {
                     return LBER_DEFAULT;
              }

              if ( bv->bv_len != 0 ) {
                     memcpy( bv->bv_val, data, bv->bv_len );
              }
              data = bv->bv_val;
       }
       if ( !( option & LBER_BV_NOTERM ))
              data[bv->bv_len] = '\0';

       return tag;
}

Here is the call graph for this function:

Here is the caller graph for this function:

ber_tag_t ber_get_stringbv_null ( BerElement *  ber,
struct berval bv,
int  option 
)

Definition at line 511 of file decode.c.

{
       ber_tag_t     tag;
       char          *data;

       tag = ber_skip_element( ber, bv );
       if ( tag == LBER_DEFAULT || bv->bv_len == 0 ) {
              bv->bv_val = NULL;
              return tag;
       }

       if (( option & LBER_BV_STRING ) &&
              memchr( bv->bv_val, 0, bv->bv_len - 1 ))
       {
              bv->bv_val = NULL;
              return LBER_DEFAULT;
       }

       data = bv->bv_val;
       if ( option & LBER_BV_ALLOC ) {
              bv->bv_val = (char *) ber_memalloc_x( bv->bv_len + 1,
                     ber->ber_memctx );
              if ( bv->bv_val == NULL ) {
                     return LBER_DEFAULT;
              }

              memcpy( bv->bv_val, data, bv->bv_len );
              data = bv->bv_val;
       }
       if ( !( option & LBER_BV_NOTERM ))
              data[bv->bv_len] = '\0';

       return tag;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static ber_tag_t ber_get_stringbvl ( BerElement *  ber,
bgbvr b 
) [static]

Definition at line 355 of file decode.c.

{
       int i = 0, n;
       ber_tag_t tag;
       ber_len_t tot_size = 0, siz = b->siz;
       char *last, *orig;
       struct berval bv, *bvp = NULL;
       union stringbvl_u {
              char **ca;                         /* ChArray */
              BerVarray ba;               /* BvArray */
              struct berval **bv;         /* BvVec */
              char *bo;                          /* BvOff */
       } res;

       tag = ber_skip_tag( ber, &bv.bv_len );

       if ( tag != LBER_DEFAULT ) {
              tag = 0;
              orig = ber->ber_ptr;
              last = orig + bv.bv_len;

              for ( ; ber->ber_ptr < last; i++, tot_size += siz ) {
                     if ( ber_skip_element( ber, &bv ) == LBER_DEFAULT )
                            break;
              }
              if ( ber->ber_ptr != last ) {
                     i = 0;
                     tag = LBER_DEFAULT;
              }

              ber->ber_ptr = orig;
              ber->ber_tag = *(unsigned char *) orig;
       }

       b->siz = i;
       if ( i == 0 ) {
              return tag;
       }

       /* Allocate and NULL-terminate the result vector */
       b->result = ber_memalloc_x( tot_size + siz, ber->ber_memctx );
       if ( b->result == NULL ) {
              return LBER_DEFAULT;
       }
       switch (b->choice) {
       case ChArray:
              res.ca = b->result;
              res.ca[i] = NULL;
              break;
       case BvArray:
              res.ba = b->result;
              res.ba[i].bv_val = NULL;
              break;
       case BvVec:
              res.bv = b->result;
              res.bv[i] = NULL;
              break;
       case BvOff:
              res.bo = (char *) b->result + b->off;
              ((struct berval *) (res.bo + tot_size))->bv_val = NULL;
              tot_size = 0;
              break;
       }

       n = 0;
       do {
              tag = ber_get_stringbv( ber, &bv, b->option );
              if ( tag == LBER_DEFAULT ) {
                     goto failed;
              }

              /* store my result */
              switch (b->choice) {
              case ChArray:
                     res.ca[n] = bv.bv_val;
                     break;
              case BvArray:
                     res.ba[n] = bv;
                     break;
              case BvVec:
                     bvp = ber_memalloc_x( sizeof( struct berval ),
                            ber->ber_memctx );
                     if ( !bvp ) {
                            ber_memfree_x( bv.bv_val, ber->ber_memctx );
                            goto failed;
                     }
                     res.bv[n] = bvp;
                     *bvp = bv;
                     break;
              case BvOff:
                     *(struct berval *)(res.bo + tot_size) = bv;
                     tot_size += siz;
                     break;
              }
       } while (++n < i);
       return tag;

failed:
       if (b->choice != BvOff) { /* BvOff does not have LBER_BV_ALLOC set */
              while (--n >= 0) {
                     switch(b->choice) {
                     case ChArray:
                            ber_memfree_x(res.ca[n], ber->ber_memctx);
                            break;
                     case BvArray:
                            ber_memfree_x(res.ba[n].bv_val, ber->ber_memctx);
                            break;
                     case BvVec:
                            ber_memfree_x(res.bv[n]->bv_val, ber->ber_memctx);
                            ber_memfree_x(res.bv[n], ber->ber_memctx);
                            break;
                     default:
                            break;
                     }
              }
       }
       ber_memfree_x(b->result, ber->ber_memctx);
       b->result = NULL;
       return LBER_DEFAULT;
}

Here is the call graph for this function:

Here is the caller graph for this function:

ber_tag_t ber_get_tag ( BerElement *  ber)

Definition at line 141 of file decode.c.

{
       struct berval bv;
       ber_tag_t tag = ber_tag_and_rest( ber, &bv );

       ber->ber_ptr = bv.bv_val;
       return tag;
}

Here is the call graph for this function:

ber_tag_t ber_next_element ( BerElement *  ber,
ber_len_t len,
LDAP_CONST char *  last 
)

Definition at line 680 of file decode.c.

{
       assert( ber != NULL );
       assert( last != NULL );
       assert( LBER_VALID( ber ) );

       if ( ber->ber_ptr >= last ) {
              return LBER_DEFAULT;
       }

       return ber_peek_tag( ber, len );
}

Here is the call graph for this function:

Here is the caller graph for this function:

ber_tag_t ber_peek_element ( const BerElement *  ber,
struct berval bv 
)

Definition at line 152 of file decode.c.

{
       ber_tag_t     tag;
       ber_len_t     len, rest;
       unsigned      i;
       unsigned char *ptr;

       assert( bv != NULL );

       /*
        * Any ber element looks like this: tag length contents.
        * Assuming everything's ok, we return the tag, and point
        * bv at the contents.
        *
        * Assumptions:
        *     1) definite lengths
        *     2) primitive encodings used whenever possible
        */

       len = 0;

       /*
        * First, we read the tag.
        */
       tag = ber_tag_and_rest( ber, bv );

       rest = bv->bv_len;
       ptr = (unsigned char *) bv->bv_val;
       if ( tag == LBER_DEFAULT || rest == 0 ) {
              goto fail;
       }

       /*
        * Next, read the length.  The first octet determines the length
        * of the length.    If bit 8 is 0, the length is the short form,
        * otherwise if the octet != 0x80 it's the long form, otherwise
        * the ber element has the unsupported indefinite-length format.
        * Lengths that do not fit in a ber_len_t are not accepted.
        */

       len = *ptr++;
       rest--;

       if ( len & 0x80U ) {
              len &= 0x7fU;
              if ( len - 1U > sizeof(ber_len_t) - 1U || rest < len ) {
                     /* Indefinite-length/too long length/not enough data */
                     goto fail;
              }

              rest -= len;
              i = len;
              for( len = *ptr++ & 0xffU; --i; len |= *ptr++ & 0xffU ) {
                     len <<= 8;
              }
       }

       /* BER element should have enough data left */
       if( len > rest ) {
       fail:
              tag = LBER_DEFAULT;
       }

       bv->bv_len = len;
       bv->bv_val = (char *) ptr;
       return tag;
}

Here is the call graph for this function:

Here is the caller graph for this function:

ber_tag_t ber_peek_tag ( BerElement *  ber,
ber_len_t len 
)

Definition at line 238 of file decode.c.

{
       struct berval bv;
       ber_tag_t tag = ber_peek_element( ber, &bv );

       *len = bv.bv_len;
       return tag;
}

Here is the call graph for this function:

Here is the caller graph for this function:

ber_tag_t ber_scanf ( BerElement *  ber,
LDAP_CONST char *  fmt,
  ... 
)

Definition at line 698 of file decode.c.

{
       va_list              ap;
       LDAP_CONST char             *fmt_reset;
       char          *s, **ss, ***sss;
       struct berval data, *bval, **bvp, ***bvpp;
       ber_int_t     *i;
       ber_len_t     *l;
       ber_tag_t     *t;
       ber_tag_t     rc;
       ber_len_t     len;

       va_start( ap, fmt );

       assert( ber != NULL );
       assert( fmt != NULL );
       assert( LBER_VALID( ber ) );

       fmt_reset = fmt;

       if ( ber->ber_debug & (LDAP_DEBUG_TRACE|LDAP_DEBUG_BER)) {
              ber_log_printf( LDAP_DEBUG_TRACE, ber->ber_debug,
                     "ber_scanf fmt (%s) ber:\n", fmt );
              ber_log_dump( LDAP_DEBUG_BER, ber->ber_debug, ber, 1 );
       }

       for ( rc = 0; *fmt && rc != LBER_DEFAULT; fmt++ ) {
              /* When this is modified, remember to update
               * the error-cleanup code below accordingly. */
              switch ( *fmt ) {
              case '!': { /* Hook */
                            BERDecodeCallback *f;
                            void *p;

                            f = va_arg( ap, BERDecodeCallback * );
                            p = va_arg( ap, void * );

                            rc = (*f)( ber, p, 0 );
                     } break;

              case 'a':     /* octet string - allocate storage as needed */
                     ss = va_arg( ap, char ** );
                     rc = ber_get_stringa( ber, ss );
                     break;

              case 'A':     /* octet string - allocate storage as needed,
                             * but return NULL if len == 0 */
                     ss = va_arg( ap, char ** );
                     rc = ber_get_stringa_null( ber, ss );
                     break;

              case 'b':     /* boolean */
                     i = va_arg( ap, ber_int_t * );
                     rc = ber_get_boolean( ber, i );
                     break;

              case 'B':     /* bit string - allocate storage as needed */
                     ss = va_arg( ap, char ** );
                     l = va_arg( ap, ber_len_t * ); /* for length, in bits */
                     rc = ber_get_bitstringa( ber, ss, l );
                     break;

              case 'e':     /* enumerated */
              case 'i':     /* integer */
                     i = va_arg( ap, ber_int_t * );
                     rc = ber_get_int( ber, i );
                     break;

              case 'l':     /* length of next item */
                     l = va_arg( ap, ber_len_t * );
                     rc = ber_peek_tag( ber, l );
                     break;

              case 'm':     /* octet string in berval, in-place */
                     bval = va_arg( ap, struct berval * );
                     rc = ber_get_stringbv( ber, bval, 0 );
                     break;

              case 'M':     /* bvoffarray - must include address of
                             * a record len, and record offset.
                             * number of records will be returned thru
                             * len ptr on finish. parsed in-place.
                             */
              {
                     bgbvr cookie = { BvOff, 0 };
                     bvp = va_arg( ap, struct berval ** );
                     l = va_arg( ap, ber_len_t * );
                     cookie.siz = *l;
                     cookie.off = va_arg( ap, ber_len_t );
                     rc = ber_get_stringbvl( ber, &cookie );
                     *bvp = cookie.result;
                     *l = cookie.siz;
                     break;
              }

              case 'n':     /* null */
                     rc = ber_get_null( ber );
                     break;

              case 'o':     /* octet string in a supplied berval */
                     bval = va_arg( ap, struct berval * );
                     rc = ber_get_stringbv( ber, bval, LBER_BV_ALLOC );
                     break;

              case 'O':     /* octet string - allocate & include length */
                     bvp = va_arg( ap, struct berval ** );
                     rc = ber_get_stringal( ber, bvp );
                     break;

              case 's':     /* octet string - in a buffer */
                     s = va_arg( ap, char * );
                     l = va_arg( ap, ber_len_t * );
                     rc = ber_get_stringb( ber, s, l );
                     break;

              case 't':     /* tag of next item */
                     t = va_arg( ap, ber_tag_t * );
                     *t = rc = ber_peek_tag( ber, &len );
                     break;

              case 'T':     /* skip tag of next item */
                     t = va_arg( ap, ber_tag_t * );
                     *t = rc = ber_skip_tag( ber, &len );
                     break;

              case 'v':     /* sequence of strings */
              {
                     bgbvr cookie = {
                            ChArray, LBER_BV_ALLOC | LBER_BV_STRING, sizeof( char * )
                     };
                     rc = ber_get_stringbvl( ber, &cookie );
                     *(va_arg( ap, char *** )) = cookie.result;
                     break;
              }

              case 'V':     /* sequence of strings + lengths */
              {
                     bgbvr cookie = {
                            BvVec, LBER_BV_ALLOC, sizeof( struct berval * )
                     };
                     rc = ber_get_stringbvl( ber, &cookie );
                     *(va_arg( ap, struct berval *** )) = cookie.result;
                     break;
              }

              case 'W':     /* bvarray */
              {
                     bgbvr cookie = {
                            BvArray, LBER_BV_ALLOC, sizeof( struct berval )
                     };
                     rc = ber_get_stringbvl( ber, &cookie );
                     *(va_arg( ap, struct berval ** )) = cookie.result;
                     break;
              }

              case 'x':     /* skip the next element - whatever it is */
                     rc = ber_skip_element( ber, &data );
                     break;

              case '{':     /* begin sequence */
              case '[':     /* begin set */
                     switch ( fmt[1] ) {
                     case 'v': case 'V': case 'W': case 'M':
                            break;
                     default:
                            rc = ber_skip_tag( ber, &len );
                            break;
                     }
                     break;

              case '}':     /* end sequence */
              case ']':     /* end set */
                     break;

              default:
                     if( ber->ber_debug ) {
                            ber_log_printf( LDAP_DEBUG_ANY, ber->ber_debug,
                                   "ber_scanf: unknown fmt %c\n", *fmt );
                     }
                     rc = LBER_DEFAULT;
                     break;
              }
       }

       va_end( ap );

       if ( rc == LBER_DEFAULT ) {
              /*
               * Error.  Reclaim malloced memory that was given to the caller.
               * Set allocated pointers to NULL, "data length" outvalues to 0.
               */
              va_start( ap, fmt );

              for ( ; fmt_reset < fmt; fmt_reset++ ) {
              switch ( *fmt_reset ) {
              case '!': { /* Hook */
                            BERDecodeCallback *f;
                            void *p;

                            f = va_arg( ap, BERDecodeCallback * );
                            p = va_arg( ap, void * );

                            (void) (*f)( ber, p, 1 );
                     } break;

              case 'a':     /* octet string - allocate storage as needed */
              case 'A':
                     ss = va_arg( ap, char ** );
                     ber_memfree_x( *ss, ber->ber_memctx );
                     *ss = NULL;
                     break;

              case 'b':     /* boolean */
              case 'e':     /* enumerated */
              case 'i':     /* integer */
                     (void) va_arg( ap, ber_int_t * );
                     break;

              case 'l':     /* length of next item */
                     *(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 * );
                     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 ** );
                     ber_bvfree_x( *bvp, ber->ber_memctx );
                     *bvp = NULL;
                     break;

              case 's':     /* octet string - in a buffer */
                     (void) va_arg( ap, char * );
                     *(va_arg( ap, ber_len_t * )) = 0;
                     break;

              case 't':     /* tag of next item */
              case 'T':     /* skip tag of next item */
                     (void) va_arg( ap, ber_tag_t * );
                     break;

              case 'B':     /* bit string - allocate storage as needed */
                     ss = va_arg( ap, char ** );
                     ber_memfree_x( *ss, ber->ber_memctx );
                     *ss = NULL;
                     *(va_arg( ap, ber_len_t * )) = 0; /* for length, in bits */
                     break;

              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 */
              case '}':     /* end sequence */
              case ']':     /* end set */
                     break;

              default:
                     /* format should be good */
                     assert( 0 );
              }
              }

              va_end( ap );
       }

       return rc;
}

Here is the call graph for this function:

ber_tag_t ber_skip_element ( BerElement *  ber,
struct berval bv 
)

Definition at line 225 of file decode.c.

{
       ber_tag_t tag = ber_peek_element( ber, bv );

       if ( tag != LBER_DEFAULT ) {
              ber->ber_ptr = bv->bv_val + bv->bv_len;
              ber->ber_tag = *(unsigned char *) ber->ber_ptr;
       }

       return tag;
}

Here is the call graph for this function:

Here is the caller graph for this function:

ber_tag_t ber_skip_tag ( BerElement *  ber,
ber_len_t lenp 
)

Definition at line 250 of file decode.c.

{
       struct berval bv;
       ber_tag_t tag = ber_peek_element( ber, &bv );

       ber->ber_ptr = bv.bv_val;
       ber->ber_tag = *(unsigned char *) ber->ber_ptr;

       *lenp = bv.bv_len;
       return tag;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static ber_tag_t ber_tag_and_rest ( const BerElement *  ber,
struct berval bv 
) [static]

Definition at line 91 of file decode.c.

{
       ber_tag_t     tag;
       ptrdiff_t     rest;
       unsigned char *ptr;

       assert( ber != NULL );
       assert( LBER_VALID( ber ) );

       ptr = (unsigned char *) ber->ber_ptr;
       rest = (unsigned char *) ber->ber_end - ptr;
       if ( rest <= 0 ) {
              goto fail;
       }

       tag = ber->ber_tag;
       if ( (char *) ptr == ber->ber_buf ) {
              tag = *ptr;
       }
       ptr++;
       rest--;
       if ( (tag & LBER_BIG_TAG_MASK) != LBER_BIG_TAG_MASK ) {
              goto done;
       }

       do {
              if ( rest <= 0 ) {
                     break;
              }
              tag <<= 8;
              tag |= *ptr++ & 0xffU;
              rest--;

              if ( ! (tag & LBER_MORE_TAG_MASK) ) {
                     goto done;
              }
       } while ( tag <= (ber_tag_t)-1 / 256 );

 fail:
       /* Error or unsupported tag size */
       tag = LBER_DEFAULT;

 done:
       bv->bv_len = rest;
       bv->bv_val = (char *) ptr;
       return tag;
}

Here is the caller graph for this function: