--- libraries/liblber/decode.c 2007/08/27 10:11:31 1.101.2.5 +++ libraries/liblber/decode.c 2007/03/23 14:27:38 1.108 @@ -1,5 +1,5 @@ /* decode.c - ber input decoding routines */ -/* $OpenLDAP: pkg/ldap/libraries/liblber/decode.c,v 1.101.2.4 2007/01/02 21:43:48 kurt Exp $ */ +/* $OpenLDAP: pkg/ldap/libraries/liblber/decode.c,v 1.107 2007/03/20 14:10:16 hyc Exp $ */ /* This work is part of OpenLDAP Software . * * Copyright 1998-2007 The OpenLDAP Foundation. @@ -45,6 +45,40 @@ static ber_len_t ber_getnint LDAP_P(( ber_int_t *num, ber_len_t len )); +/* out->bv_len should be the buffer size on input */ +int +ber_decode_oid( BerValue *in, BerValue *out ) +{ + unsigned char *der = in->bv_val; + unsigned long val, val1; + int i, len; + char *ptr; + + assert( in != NULL ); + assert( out != NULL ); + + /* expands by 5/2, and we add dots - call it 3 */ + if ( !out->bv_val || out->bv_len < in->bv_len * 3 ) + return -1; + + val1 = der[0] / 40; + val = der[0] - val1 * 40; + + len = sprintf( out->bv_val, "%ld.%ld", val1, val ); + ptr = out->bv_val + len; + val = 0; + for ( i=1; ibv_len; i++ ) { + val = val << 7; + val |= der[i] & 0x7f; + if ( !( der[i] & 0x80 )) { + ptr += sprintf( ptr, ".%ld", val ); + val = 0; + } + } + out->bv_len = ptr - out->bv_val; + return 0; +} + /* return the tag - LBER_DEFAULT returned means trouble */ ber_tag_t ber_get_tag( BerElement *ber ) @@ -373,7 +407,7 @@ ber_get_stringbvl( bgbvr *b, ber_len_t * case BvOff: *b->res.ba = ber_memalloc_x( (n+1) * b->siz, b->ber->ber_memctx ); if ( *b->res.ba == NULL ) return LBER_DEFAULT; - ((struct berval *)((char *)(*b->res.ba) + n*b->siz + + ((struct berval *)((long)(*b->res.ba) + n*b->siz + b->off))->bv_val = NULL; break; } @@ -406,7 +440,7 @@ ber_get_stringbvl( bgbvr *b, ber_len_t * *bvp = bv; break; case BvOff: - *(BerVarray)((char *)(*b->res.ba)+n*b->siz+b->off) = bv; + *(BerVarray)((long)(*b->res.ba)+n*b->siz+b->off) = bv; break; } } @@ -437,7 +471,7 @@ nomem: } ber_tag_t -ber_get_stringbv( BerElement *ber, struct berval *bv, int alloc ) +ber_get_stringbv( BerElement *ber, struct berval *bv, int option ) { ber_tag_t tag; @@ -455,7 +489,7 @@ ber_get_stringbv( BerElement *ber, struc return LBER_DEFAULT; } - if ( alloc ) { + if ( option & LBER_BV_ALLOC ) { bv->bv_val = (char *) ber_memalloc_x( bv->bv_len + 1, ber->ber_memctx ); if ( bv->bv_val == NULL ) { @@ -474,14 +508,14 @@ ber_get_stringbv( BerElement *ber, struc ber->ber_ptr += bv->bv_len; } ber->ber_tag = *(unsigned char *)ber->ber_ptr; - bv->bv_val[bv->bv_len] = '\0'; + if ( !( option & LBER_BV_NOTERM )) + bv->bv_val[bv->bv_len] = '\0'; return tag; } -#ifdef LDAP_NULL_IS_NULL ber_tag_t -ber_get_stringbv_null( BerElement *ber, struct berval *bv, int alloc ) +ber_get_stringbv_null( BerElement *ber, struct berval *bv, int option ) { ber_tag_t tag; @@ -505,7 +539,7 @@ ber_get_stringbv_null( BerElement *ber, return tag; } - if ( alloc ) { + if ( option & LBER_BV_ALLOC ) { bv->bv_val = (char *) ber_memalloc_x( bv->bv_len + 1, ber->ber_memctx ); if ( bv->bv_val == NULL ) { @@ -524,11 +558,11 @@ ber_get_stringbv_null( BerElement *ber, ber->ber_ptr += bv->bv_len; } ber->ber_tag = *(unsigned char *)ber->ber_ptr; - bv->bv_val[bv->bv_len] = '\0'; + if ( !( option & LBER_BV_NOTERM )) + bv->bv_val[bv->bv_len] = '\0'; return tag; } -#endif /* LDAP_NULL_IS_NULL */ ber_tag_t ber_get_stringa( BerElement *ber, char **buf ) @@ -538,13 +572,12 @@ ber_get_stringa( BerElement *ber, char * assert( buf != NULL ); - tag = ber_get_stringbv( ber, &bv, 1 ); + tag = ber_get_stringbv( ber, &bv, LBER_BV_ALLOC ); *buf = bv.bv_val; return tag; } -#ifdef LDAP_NULL_IS_NULL ber_tag_t ber_get_stringa_null( BerElement *ber, char **buf ) { @@ -553,12 +586,11 @@ ber_get_stringa_null( BerElement *ber, c assert( buf != NULL ); - tag = ber_get_stringbv_null( ber, &bv, 1 ); + tag = ber_get_stringbv_null( ber, &bv, LBER_BV_ALLOC ); *buf = bv.bv_val; return tag; } -#endif /* LDAP_NULL_IS_NULL */ ber_tag_t ber_get_stringal( BerElement *ber, struct berval **bv ) @@ -574,7 +606,7 @@ ber_get_stringal( BerElement *ber, struc return LBER_DEFAULT; } - tag = ber_get_stringbv( ber, *bv, 1 ); + tag = ber_get_stringbv( ber, *bv, LBER_BV_ALLOC ); if ( tag == LBER_DEFAULT ) { LBER_FREE( *bv ); *bv = NULL; @@ -759,13 +791,11 @@ ber_scanf ( BerElement *ber, rc = ber_get_stringa( ber, ss ); break; -#ifdef LDAP_NULL_IS_NULL 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; -#endif /* LDAP_NULL_IS_NULL */ case 'b': /* boolean */ i = va_arg( ap, ber_int_t * ); @@ -817,7 +847,7 @@ ber_scanf ( BerElement *ber, case 'o': /* octet string in a supplied berval */ bval = va_arg( ap, struct berval * ); - rc = ber_get_stringbv( ber, bval, 1 ); + rc = ber_get_stringbv( ber, bval, LBER_BV_ALLOC ); break; case 'O': /* octet string - allocate & include length */ @@ -846,7 +876,7 @@ ber_scanf ( BerElement *ber, bgbvr cookie = { ChArray }; cookie.ber = ber; cookie.res.c = va_arg( ap, char *** ); - cookie.alloc = 1; + cookie.alloc = LBER_BV_ALLOC; rc = ber_get_stringbvl( &cookie, NULL ); break; } @@ -856,7 +886,7 @@ ber_scanf ( BerElement *ber, bgbvr cookie = { BvVec }; cookie.ber = ber; cookie.res.bv = va_arg( ap, struct berval *** ); - cookie.alloc = 1; + cookie.alloc = LBER_BV_ALLOC; rc = ber_get_stringbvl( &cookie, NULL ); break; } @@ -866,7 +896,7 @@ ber_scanf ( BerElement *ber, bgbvr cookie = { BvArray }; cookie.ber = ber; cookie.res.ba = va_arg( ap, struct berval ** ); - cookie.alloc = 1; + cookie.alloc = LBER_BV_ALLOC; rc = ber_get_stringbvl( &cookie, NULL ); break; } @@ -920,9 +950,7 @@ ber_scanf ( BerElement *ber, } break; case 'a': /* octet string - allocate storage as needed */ -#ifdef LDAP_NULL_IS_NULL case 'A': -#endif /* LDAP_NULL_IS_NULL */ ss = va_arg( ap, char ** ); if ( *ss ) { LBER_FREE( *ss );