mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-01-06 10:46:21 +08:00
More ITS#6215 -
Speedup & less memory allocation: Simplify the work to encode tag, length, integer/enum, sequence/set. Drop struct seqorset and allocations of it. Replace BerElement.ber_sos. Drop ber_write(,,,nonzero) support. Callers, if any, need to be rewritten. Make ber_log_sos_dump() and ber_sos_dump() stubs, they could no longer work. Fix ber_write() buffer overrun after ber_start_seqorset(). Check overflow and max sizes, e.g. for functions returning int size. Some cleanup, and handwaves in the direction of supporting CHAR_BIT>8. Add/fix comments and a few descriptive types/macros.
This commit is contained in:
parent
53f884ac1d
commit
36d2dc034d
@ -276,47 +276,19 @@ ber_dump(
|
|||||||
ber_bprint( ber->ber_ptr, len );
|
ber_bprint( ber->ber_ptr, len );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Exists for binary compatibility with OpenLDAP 2.4.17-- */
|
||||||
int
|
int
|
||||||
ber_log_sos_dump(
|
ber_log_sos_dump(
|
||||||
int errlvl,
|
int errlvl,
|
||||||
int loglvl,
|
int loglvl,
|
||||||
Seqorset *sos )
|
Seqorset *sos )
|
||||||
{
|
{
|
||||||
assert( sos != NULL );
|
|
||||||
|
|
||||||
if ( !ber_log_check( errlvl, loglvl )) {
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ber_sos_dump( sos );
|
/* Exists for binary compatibility with OpenLDAP 2.4.17-- */
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ber_sos_dump(
|
ber_sos_dump(
|
||||||
Seqorset *sos )
|
Seqorset *sos )
|
||||||
{
|
{
|
||||||
char buf[132];
|
|
||||||
|
|
||||||
assert( sos != NULL );
|
|
||||||
|
|
||||||
(*ber_pvt_log_print)( "*** sos dump ***\n" );
|
|
||||||
|
|
||||||
while ( sos != NULL ) {
|
|
||||||
sprintf( buf, "ber_sos_dump: clen %ld first %p ptr %p\n",
|
|
||||||
(long) sos->sos_clen,
|
|
||||||
sos->sos_first,
|
|
||||||
sos->sos_ptr );
|
|
||||||
(*ber_pvt_log_print)( buf );
|
|
||||||
|
|
||||||
sprintf( buf, " current len %ld contents:\n",
|
|
||||||
(long) (sos->sos_ptr - sos->sos_first) );
|
|
||||||
(*ber_pvt_log_print)( buf );
|
|
||||||
|
|
||||||
ber_bprint( sos->sos_first, sos->sos_ptr - sos->sos_first );
|
|
||||||
|
|
||||||
sos = sos->sos_next;
|
|
||||||
}
|
|
||||||
|
|
||||||
(*ber_pvt_log_print)( "*** end dump ***\n" );
|
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
#include "portable.h"
|
#include "portable.h"
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <limits.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include <ac/stdlib.h>
|
#include <ac/stdlib.h>
|
||||||
@ -41,141 +42,69 @@
|
|||||||
|
|
||||||
#include "lber-int.h"
|
#include "lber-int.h"
|
||||||
|
|
||||||
static int ber_put_len LDAP_P((
|
|
||||||
BerElement *ber,
|
|
||||||
ber_len_t len,
|
|
||||||
int nosos ));
|
|
||||||
|
|
||||||
static int ber_start_seqorset LDAP_P((
|
#define OCTET_SIZE(type) ((ber_len_t) (sizeof(type)*CHAR_BIT + 7) / 8)
|
||||||
BerElement *ber,
|
#define TAGBUF_SIZE OCTET_SIZE(ber_tag_t)
|
||||||
ber_tag_t tag ));
|
#define LENBUF_SIZE (1 + OCTET_SIZE(ber_len_t))
|
||||||
|
#define HEADER_SIZE (TAGBUF_SIZE + LENBUF_SIZE)
|
||||||
|
|
||||||
static int ber_put_seqorset LDAP_P(( BerElement *ber ));
|
/*
|
||||||
|
* BER element size constrains:
|
||||||
|
*
|
||||||
|
* - We traditionally support a length of max 0xffffffff. However
|
||||||
|
* some functions return an int length so that is their max.
|
||||||
|
* MAXINT_BERSIZE is the max for those functions.
|
||||||
|
*
|
||||||
|
* - MAXINT_BERSIZE must fit in MAXINT_BERSIZE_OCTETS octets.
|
||||||
|
*
|
||||||
|
* - sizeof(ber_elem_size_t) is normally MAXINT_BERSIZE_OCTETS:
|
||||||
|
* Big enough for MAXINT_BERSIZE, but not more. (Larger wastes
|
||||||
|
* space in the working encoding and DER encoding of a sequence
|
||||||
|
* or set. Smaller further limits sizes near a sequence/set.)
|
||||||
|
*
|
||||||
|
* ber_len_t is mostly unrelated to this. Which may be for the best,
|
||||||
|
* since it is also used for lengths of data that are never encoded.
|
||||||
|
*/
|
||||||
|
#define MAXINT_BERSIZE \
|
||||||
|
(INT_MAX>0xffffffffUL ? (ber_len_t) 0xffffffffUL : INT_MAX-HEADER_SIZE)
|
||||||
|
#define MAXINT_BERSIZE_OCTETS 4
|
||||||
|
typedef ber_uint_t ber_elem_size_t; /* normally 32 bits */
|
||||||
|
|
||||||
static int ber_put_int_or_enum LDAP_P((
|
|
||||||
BerElement *ber,
|
|
||||||
ber_int_t num,
|
|
||||||
ber_tag_t tag ));
|
|
||||||
|
|
||||||
#define BER_TOP_BYTE(type) (sizeof(type)-1)
|
/* Prepend tag to ptr, which points to the end of a tag buffer */
|
||||||
#define BER_TOP_MASK(type) ((type)0xffU << (BER_TOP_BYTE(type)*8))
|
static unsigned char *
|
||||||
|
ber_prepend_tag( unsigned char *ptr, ber_tag_t tag )
|
||||||
static int
|
|
||||||
ber_calc_taglen( ber_tag_t tag )
|
|
||||||
{
|
{
|
||||||
int i = BER_TOP_BYTE(ber_tag_t);
|
do {
|
||||||
ber_tag_t mask = BER_TOP_MASK(ber_tag_t);
|
*--ptr = (unsigned char) tag & 0xffU;
|
||||||
|
} while ( (tag >>= 8) != 0 );
|
||||||
|
|
||||||
/* find the first non-all-zero byte in the tag */
|
return ptr;
|
||||||
for ( ; i > 0; i-- ) {
|
|
||||||
/* not all zero */
|
|
||||||
if ( tag & mask ) break;
|
|
||||||
mask >>= 8;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return i + 1;
|
/* Prepend ber length to ptr, which points to the end of a length buffer */
|
||||||
}
|
static unsigned char *
|
||||||
|
ber_prepend_len( unsigned char *ptr, ber_len_t len )
|
||||||
static int
|
|
||||||
ber_put_tag(
|
|
||||||
BerElement *ber,
|
|
||||||
ber_tag_t tag,
|
|
||||||
int nosos )
|
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
int taglen;
|
|
||||||
int i;
|
|
||||||
unsigned char nettag[sizeof(ber_tag_t)];
|
|
||||||
|
|
||||||
assert( ber != NULL );
|
|
||||||
assert( LBER_VALID( ber ) );
|
|
||||||
|
|
||||||
taglen = ber_calc_taglen( tag );
|
|
||||||
|
|
||||||
for( i=taglen-1; i>=0; i-- ) {
|
|
||||||
nettag[i] = (unsigned char)(tag & 0xffU);
|
|
||||||
tag >>= 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = ber_write( ber, (char *) nettag, taglen, nosos );
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ber_len_t
|
|
||||||
ber_calc_lenlen( ber_len_t len )
|
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* short len if it's less than 128 - one byte giving the len,
|
* short len if it's less than 128 - one byte giving the len,
|
||||||
* with bit 8 0.
|
* with bit 8 0.
|
||||||
*/
|
|
||||||
|
|
||||||
if ( len <= (ber_len_t) 0x7FU ) return 1;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* long len otherwise - one byte with bit 8 set, giving the
|
* long len otherwise - one byte with bit 8 set, giving the
|
||||||
* length of the length, followed by the length itself.
|
* length of the length, followed by the length itself.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ( len <= (ber_len_t) 0xffU ) return 2;
|
*--ptr = (unsigned char) len & 0xffU;
|
||||||
if ( len <= (ber_len_t) 0xffffU ) return 3;
|
|
||||||
if ( len <= (ber_len_t) 0xffffffU ) return 4;
|
|
||||||
|
|
||||||
return 5;
|
if ( len >= 0x80 ) {
|
||||||
|
unsigned char *endptr = ptr--;
|
||||||
|
|
||||||
|
while ( (len >>= 8) != 0 ) {
|
||||||
|
*ptr-- = (unsigned char) len & 0xffU;
|
||||||
|
}
|
||||||
|
*ptr = (unsigned char) (endptr - ptr) + 0x80U;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
return ptr;
|
||||||
ber_put_len( BerElement *ber, ber_len_t len, int nosos )
|
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
int i,j;
|
|
||||||
char lenlen;
|
|
||||||
ber_len_t mask;
|
|
||||||
unsigned char netlen[sizeof(ber_len_t)];
|
|
||||||
|
|
||||||
assert( ber != NULL );
|
|
||||||
assert( LBER_VALID( ber ) );
|
|
||||||
|
|
||||||
/*
|
|
||||||
* short len if it's less than 128 - one byte giving the len,
|
|
||||||
* with bit 8 0.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ( len <= 127 ) {
|
|
||||||
char length_byte = (char) len;
|
|
||||||
return ber_write( ber, &length_byte, 1, nosos );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* long len otherwise - one byte with bit 8 set, giving the
|
|
||||||
* length of the length, followed by the length itself.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* find the first non-all-zero byte */
|
|
||||||
i = BER_TOP_BYTE(ber_len_t);
|
|
||||||
mask = BER_TOP_MASK(ber_len_t);
|
|
||||||
for ( ; i > 0; i-- ) {
|
|
||||||
/* not all zero */
|
|
||||||
if ( len & mask ) break;
|
|
||||||
mask >>= 8;
|
|
||||||
}
|
|
||||||
lenlen = (unsigned char) ++i;
|
|
||||||
if ( lenlen > 4 ) return -1;
|
|
||||||
|
|
||||||
lenlen |= 0x80UL;
|
|
||||||
|
|
||||||
/* write the length of the length */
|
|
||||||
if ( ber_write( ber, &lenlen, 1, nosos ) != 1 ) return -1;
|
|
||||||
|
|
||||||
for( j=i-1; j>=0; j-- ) {
|
|
||||||
netlen[j] = (unsigned char)(len & 0xffU);
|
|
||||||
len >>= 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* write the length itself */
|
|
||||||
rc = ber_write( ber, (char *) netlen, i, nosos );
|
|
||||||
|
|
||||||
return rc == i ? i+1 : -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* out->bv_len should be the buffer size on input */
|
/* out->bv_len should be the buffer size on input */
|
||||||
@ -210,6 +139,7 @@ ber_encode_oid( BerValue *in, BerValue *out )
|
|||||||
for (;;) {
|
for (;;) {
|
||||||
if ( ptr > inend ) return -1;
|
if ( ptr > inend ) return -1;
|
||||||
|
|
||||||
|
/* Write the OID component little-endian, then reverse it */
|
||||||
len = 0;
|
len = 0;
|
||||||
do {
|
do {
|
||||||
der[len++] = (val & 0xff) | 0x80;
|
der[len++] = (val & 0xff) | 0x80;
|
||||||
@ -241,61 +171,25 @@ ber_put_int_or_enum(
|
|||||||
ber_int_t num,
|
ber_int_t num,
|
||||||
ber_tag_t tag )
|
ber_tag_t tag )
|
||||||
{
|
{
|
||||||
int rc;
|
ber_uint_t unum;
|
||||||
int i, j, sign, taglen, lenlen;
|
unsigned char sign, data[TAGBUF_SIZE+1 + OCTET_SIZE(ber_int_t)], *ptr;
|
||||||
ber_len_t len;
|
|
||||||
ber_uint_t unum, mask;
|
|
||||||
unsigned char netnum[sizeof(ber_uint_t)];
|
|
||||||
|
|
||||||
sign = (num < 0);
|
sign = 0;
|
||||||
unum = num; /* Bit fiddling should be done with unsigned values */
|
unum = num; /* Bit fiddling should be done with unsigned values */
|
||||||
|
if ( num < 0 ) {
|
||||||
/*
|
sign = 0xffU;
|
||||||
* high bit is set - look for first non-all-one byte
|
unum = ~unum;
|
||||||
* high bit is clear - look for first non-all-zero byte
|
|
||||||
*/
|
|
||||||
i = BER_TOP_BYTE(ber_int_t);
|
|
||||||
mask = BER_TOP_MASK(ber_uint_t);
|
|
||||||
for ( ; i > 0; i-- ) {
|
|
||||||
if ( sign ) {
|
|
||||||
/* not all ones */
|
|
||||||
if ( (unum & mask) != mask ) break;
|
|
||||||
} else {
|
|
||||||
/* not all zero */
|
|
||||||
if ( unum & mask ) break;
|
|
||||||
}
|
}
|
||||||
mask >>= 8;
|
for ( ptr = &data[sizeof(data) - 1] ;; unum >>= 8 ) {
|
||||||
|
*ptr-- = (sign ^ (unsigned char) unum) & 0xffU;
|
||||||
|
if ( unum < 0x80 ) /* top bit at *ptr is sign bit */
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
*ptr = (unsigned char) (&data[sizeof(data) - 1] - ptr); /* length */
|
||||||
* we now have the "leading byte". if the high bit on this
|
ptr = ber_prepend_tag( ptr, tag );
|
||||||
* byte matches the sign bit, we need to "back up" a byte.
|
|
||||||
*/
|
|
||||||
mask = (unum & ((ber_uint_t)0x80U << (i * 8)));
|
|
||||||
if ( (mask && !sign) || (sign && !mask) ) {
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
len = i + 1;
|
return ber_write( ber, (char *) ptr, &data[sizeof(data)] - ptr, 0 );
|
||||||
|
|
||||||
if ( (taglen = ber_put_tag( ber, tag, 0 )) == -1 ) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( (lenlen = ber_put_len( ber, len, 0 )) == -1 ) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
|
|
||||||
for( j=i-1; j>=0; j-- ) {
|
|
||||||
netnum[j] = (unsigned char)(unum & 0xffU);
|
|
||||||
unum >>= 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = ber_write( ber, (char *) netnum, i, 0 );
|
|
||||||
|
|
||||||
/* length of tag + length + contents */
|
|
||||||
return rc == i ? taglen + lenlen + i : -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -331,22 +225,24 @@ ber_put_ostring(
|
|||||||
ber_len_t len,
|
ber_len_t len,
|
||||||
ber_tag_t tag )
|
ber_tag_t tag )
|
||||||
{
|
{
|
||||||
int taglen, lenlen, rc;
|
int rc;
|
||||||
|
unsigned char header[HEADER_SIZE], *ptr;
|
||||||
|
|
||||||
if ( tag == LBER_DEFAULT ) {
|
if ( tag == LBER_DEFAULT ) {
|
||||||
tag = LBER_OCTETSTRING;
|
tag = LBER_OCTETSTRING;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (taglen = ber_put_tag( ber, tag, 0 )) == -1 )
|
if ( len > MAXINT_BERSIZE ) {
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if ( (lenlen = ber_put_len( ber, len, 0 )) == -1 ||
|
ptr = ber_prepend_len( &header[sizeof(header)], len );
|
||||||
(ber_len_t) ber_write( ber, str, len, 0 ) != len )
|
ptr = ber_prepend_tag( ptr, tag );
|
||||||
{
|
|
||||||
rc = -1;
|
rc = ber_write( ber, (char *) ptr, &header[sizeof(header)] - ptr, 0 );
|
||||||
} else {
|
if ( rc >= 0 && ber_write( ber, str, len, 0 ) >= 0 ) {
|
||||||
/* return length of tag + length + contents */
|
/* length(tag + length + contents) */
|
||||||
rc = taglen + lenlen + len;
|
rc += (int) len;
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
@ -383,54 +279,46 @@ ber_put_bitstring(
|
|||||||
ber_len_t blen /* in bits */,
|
ber_len_t blen /* in bits */,
|
||||||
ber_tag_t tag )
|
ber_tag_t tag )
|
||||||
{
|
{
|
||||||
int taglen, lenlen;
|
int rc;
|
||||||
ber_len_t len;
|
ber_len_t len;
|
||||||
unsigned char unusedbits;
|
unsigned char unusedbits, header[HEADER_SIZE + 1], *ptr;
|
||||||
|
|
||||||
if ( tag == LBER_DEFAULT ) {
|
if ( tag == LBER_DEFAULT ) {
|
||||||
tag = LBER_BITSTRING;
|
tag = LBER_BITSTRING;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (taglen = ber_put_tag( ber, tag, 0 )) == -1 ) {
|
unusedbits = (unsigned char) -blen & 7;
|
||||||
|
len = blen / 8 + (unusedbits != 0); /* (blen+7)/8 without overflow */
|
||||||
|
if ( len >= MAXINT_BERSIZE ) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = ( blen + 7 ) / 8;
|
header[sizeof(header) - 1] = unusedbits;
|
||||||
unusedbits = (unsigned char) ((len * 8) - blen);
|
ptr = ber_prepend_len( &header[sizeof(header) - 1], len + 1 );
|
||||||
if ( (lenlen = ber_put_len( ber, len + 1, 0 )) == -1 ) {
|
ptr = ber_prepend_tag( ptr, tag );
|
||||||
return -1;
|
|
||||||
|
rc = ber_write( ber, (char *) ptr, &header[sizeof(header)] - ptr, 0 );
|
||||||
|
if ( rc >= 0 && ber_write( ber, str, len, 0 ) >= 0 ) {
|
||||||
|
/* length(tag + length + unused bit count + bitstring) */
|
||||||
|
rc += (int) len;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ber_write( ber, (char *)&unusedbits, 1, 0 ) != 1 ) {
|
return rc;
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( (ber_len_t) ber_write( ber, str, len, 0 ) != len ) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* return length of tag + length + unused bit count + contents */
|
|
||||||
return taglen + 1 + lenlen + len;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ber_put_null( BerElement *ber, ber_tag_t tag )
|
ber_put_null( BerElement *ber, ber_tag_t tag )
|
||||||
{
|
{
|
||||||
int taglen;
|
unsigned char data[TAGBUF_SIZE + 1], *ptr;
|
||||||
|
|
||||||
if ( tag == LBER_DEFAULT ) {
|
if ( tag == LBER_DEFAULT ) {
|
||||||
tag = LBER_NULL;
|
tag = LBER_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (taglen = ber_put_tag( ber, tag, 0 )) == -1 ) {
|
data[sizeof(data) - 1] = 0; /* length */
|
||||||
return -1;
|
ptr = ber_prepend_tag( &data[sizeof(data) - 1], tag );
|
||||||
}
|
|
||||||
|
|
||||||
if ( ber_put_len( ber, 0, 0 ) != 1 ) {
|
return ber_write( ber, (char *) ptr, &data[sizeof(data)] - ptr, 0 );
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return taglen + 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -439,61 +327,85 @@ ber_put_boolean(
|
|||||||
ber_int_t boolval,
|
ber_int_t boolval,
|
||||||
ber_tag_t tag )
|
ber_tag_t tag )
|
||||||
{
|
{
|
||||||
int taglen;
|
unsigned char data[TAGBUF_SIZE + 2], *ptr;
|
||||||
unsigned char c;
|
|
||||||
|
|
||||||
if ( tag == LBER_DEFAULT )
|
if ( tag == LBER_DEFAULT )
|
||||||
tag = LBER_BOOLEAN;
|
tag = LBER_BOOLEAN;
|
||||||
|
|
||||||
if ( (taglen = ber_put_tag( ber, tag, 0 )) == -1 ) {
|
data[sizeof(data) - 1] = boolval ? 0xff : 0;
|
||||||
return -1;
|
data[sizeof(data) - 2] = 1; /* length */
|
||||||
|
ptr = ber_prepend_tag( &data[sizeof(data) - 2], tag );
|
||||||
|
|
||||||
|
return ber_write( ber, (char *) ptr, &data[sizeof(data)] - ptr, 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ber_put_len( ber, 1, 0 ) != 1 ) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
c = boolval ? (unsigned char) ~0U : (unsigned char) 0U;
|
/* Max number of length octets in a sequence or set, normally 5 */
|
||||||
|
#define SOS_LENLEN (1 + (sizeof(ber_elem_size_t) > MAXINT_BERSIZE_OCTETS ? \
|
||||||
|
(ber_len_t) sizeof(ber_elem_size_t) : MAXINT_BERSIZE_OCTETS))
|
||||||
|
|
||||||
if ( ber_write( ber, (char *) &c, 1, 0 ) != 1 ) {
|
/* Header of incomplete sequence or set */
|
||||||
return -1;
|
typedef struct seqorset_header {
|
||||||
}
|
char xtagbuf[TAGBUF_SIZE + 1]; /* room for tag + len(tag or len) */
|
||||||
|
union {
|
||||||
return taglen + 2;
|
ber_elem_size_t offset; /* enclosing seqence/set */
|
||||||
}
|
char padding[SOS_LENLEN-1]; /* for final length encoding */
|
||||||
|
} next_sos;
|
||||||
#define FOUR_BYTE_LEN 5
|
# define SOS_TAG_END(header) ((unsigned char *) &(header).next_sos - 1)
|
||||||
|
} Seqorset_header;
|
||||||
|
|
||||||
|
/* Start a sequence or set */
|
||||||
static int
|
static int
|
||||||
ber_start_seqorset(
|
ber_start_seqorset(
|
||||||
BerElement *ber,
|
BerElement *ber,
|
||||||
ber_tag_t tag )
|
ber_tag_t tag )
|
||||||
{
|
{
|
||||||
Seqorset *new;
|
/*
|
||||||
|
* Write the tag and SOS_LENLEN octets reserved for length, to ber.
|
||||||
|
* For now, length octets = (tag length, previous ber_sos_inner).
|
||||||
|
*
|
||||||
|
* Update ber_sos_inner and the write-cursor ber_sos_ptr. ber_ptr
|
||||||
|
* will not move until the outermost sequence or set is complete.
|
||||||
|
*/
|
||||||
|
|
||||||
|
Seqorset_header header;
|
||||||
|
unsigned char *headptr;
|
||||||
|
ber_len_t taglen, headlen;
|
||||||
|
char *dest, **p;
|
||||||
|
|
||||||
assert( ber != NULL );
|
assert( ber != NULL );
|
||||||
assert( LBER_VALID( ber ) );
|
assert( LBER_VALID( ber ) );
|
||||||
|
|
||||||
new = (Seqorset *) ber_memcalloc_x( 1, sizeof(Seqorset), ber->ber_memctx );
|
if ( ber->ber_sos_ptr == NULL ) { /* outermost sequence/set? */
|
||||||
|
header.next_sos.offset = 0;
|
||||||
if ( new == NULL ) {
|
p = &ber->ber_ptr;
|
||||||
|
} else {
|
||||||
|
if ( (ber_len_t) -1 > (ber_elem_size_t) -1 ) {
|
||||||
|
if ( ber->ber_sos_inner > (ber_elem_size_t) -1 )
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
header.next_sos.offset = ber->ber_sos_inner;
|
||||||
new->sos_ber = ber;
|
p = &ber->ber_sos_ptr;
|
||||||
if ( ber->ber_sos == NULL ) {
|
|
||||||
new->sos_first = ber->ber_ptr;
|
|
||||||
} else {
|
|
||||||
new->sos_first = ber->ber_sos->sos_ptr;
|
|
||||||
}
|
}
|
||||||
|
headptr = ber_prepend_tag( SOS_TAG_END(header), tag );
|
||||||
|
*SOS_TAG_END(header) = taglen = SOS_TAG_END(header) - headptr;
|
||||||
|
headlen = taglen + SOS_LENLEN;
|
||||||
|
|
||||||
/* Set aside room for a 4 byte length field */
|
/* As ber_write(,headptr,headlen,) except update ber_sos_ptr, not *p */
|
||||||
new->sos_ptr = new->sos_first + ber_calc_taglen( tag ) + FOUR_BYTE_LEN;
|
if ( headlen > (ber_len_t) (ber->ber_end - *p) ) {
|
||||||
new->sos_tag = tag;
|
if ( ber_realloc( ber, headlen ) != 0 )
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
dest = *p;
|
||||||
|
AC_MEMCPY( dest, headptr, headlen );
|
||||||
|
ber->ber_sos_ptr = dest + headlen;
|
||||||
|
|
||||||
new->sos_next = ber->ber_sos;
|
ber->ber_sos_inner = dest + taglen - ber->ber_buf;
|
||||||
ber->ber_sos = new;
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do not return taglen + SOS_LENLEN here - then ber_put_seqorset()
|
||||||
|
* should return lenlen - SOS_LENLEN + len, which can be < 0.
|
||||||
|
*/
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -517,163 +429,56 @@ ber_start_set( BerElement *ber, ber_tag_t tag )
|
|||||||
return ber_start_seqorset( ber, tag );
|
return ber_start_seqorset( ber, tag );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* End a sequence or set */
|
||||||
static int
|
static int
|
||||||
ber_put_seqorset( BerElement *ber )
|
ber_put_seqorset( BerElement *ber )
|
||||||
{
|
{
|
||||||
int rc;
|
Seqorset_header header;
|
||||||
ber_len_t len;
|
unsigned char *lenptr; /* length octets in the sequence/set */
|
||||||
unsigned char netlen[sizeof(ber_len_t)];
|
ber_len_t len; /* length(contents) */
|
||||||
int taglen;
|
ber_len_t xlen; /* len + length(length) */
|
||||||
ber_len_t lenlen;
|
|
||||||
unsigned char ltag = 0x80U + FOUR_BYTE_LEN - 1;
|
|
||||||
Seqorset *next;
|
|
||||||
Seqorset **sos = &ber->ber_sos;
|
|
||||||
|
|
||||||
assert( ber != NULL );
|
assert( ber != NULL );
|
||||||
assert( LBER_VALID( ber ) );
|
assert( LBER_VALID( ber ) );
|
||||||
|
|
||||||
if( *sos == NULL ) return -1;
|
if ( ber->ber_sos_ptr == NULL ) return -1;
|
||||||
|
|
||||||
/*
|
lenptr = (unsigned char *) ber->ber_buf + ber->ber_sos_inner;
|
||||||
* If this is the toplevel sequence or set, we need to actually
|
xlen = ber->ber_sos_ptr - (char *) lenptr;
|
||||||
* write the stuff out. Otherwise, it's already been put in
|
if ( xlen > MAXINT_BERSIZE + SOS_LENLEN ) {
|
||||||
* the appropriate buffer and will be written when the toplevel
|
|
||||||
* one is written. In this case all we need to do is update the
|
|
||||||
* length and tag.
|
|
||||||
*/
|
|
||||||
|
|
||||||
len = (*sos)->sos_clen;
|
|
||||||
|
|
||||||
if ( sizeof(ber_len_t) > 4 && len > 0xffffffffUL ) {
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Extract sequence/set information from length octets */
|
||||||
|
memcpy( SOS_TAG_END(header), lenptr, SOS_LENLEN );
|
||||||
|
|
||||||
|
/* Store length, and close gap of leftover reserved length octets */
|
||||||
|
len = xlen - SOS_LENLEN;
|
||||||
if ( ber->ber_options & LBER_USE_DER ) {
|
if ( ber->ber_options & LBER_USE_DER ) {
|
||||||
lenlen = ber_calc_lenlen( len );
|
|
||||||
|
|
||||||
} else {
|
|
||||||
lenlen = FOUR_BYTE_LEN;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( lenlen > 1 ) {
|
|
||||||
int i;
|
int i;
|
||||||
ber_len_t j = len;
|
lenptr[0] = SOS_LENLEN - 1 + 0x80; /* length(length)-1 */
|
||||||
for( i=lenlen-2; i >= 0; i-- ) {
|
for( i = SOS_LENLEN; --i > 0; len >>= 8 ) {
|
||||||
netlen[i] = j & 0xffU;
|
lenptr[i] = len & 0xffU;
|
||||||
j >>= 8;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
netlen[0] = (unsigned char)(len & 0x7fU);
|
unsigned char *p = ber_prepend_len( lenptr + SOS_LENLEN, len );
|
||||||
|
ber_len_t unused = p - lenptr;
|
||||||
|
if ( unused != 0 ) {
|
||||||
|
/* length(length) < the reserved SOS_LENLEN bytes */
|
||||||
|
xlen -= unused;
|
||||||
|
AC_MEMCPY( lenptr, p, xlen );
|
||||||
|
ber->ber_sos_ptr = (char *) lenptr + xlen;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (next = (*sos)->sos_next) == NULL ) {
|
ber->ber_sos_inner = header.next_sos.offset;
|
||||||
/* write the tag */
|
if ( header.next_sos.offset == 0 ) { /* outermost sequence/set? */
|
||||||
if ( (taglen = ber_put_tag( ber, (*sos)->sos_tag, 1 )) == -1 ) {
|
|
||||||
return( -1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ber->ber_options & LBER_USE_DER ) {
|
|
||||||
/* Write the length in the minimum # of octets */
|
|
||||||
if ( ber_put_len( ber, len, 1 ) == -1 ) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lenlen != FOUR_BYTE_LEN) {
|
|
||||||
/*
|
|
||||||
* We set aside FOUR_BYTE_LEN bytes for
|
|
||||||
* the length field. Move the data if
|
|
||||||
* we don't actually need that much
|
|
||||||
*/
|
|
||||||
AC_MEMCPY( (*sos)->sos_first + taglen +
|
|
||||||
lenlen, (*sos)->sos_first + taglen +
|
|
||||||
FOUR_BYTE_LEN, len );
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* Fill FOUR_BYTE_LEN bytes for length field */
|
|
||||||
/* one byte of length length */
|
|
||||||
if ( ber_write( ber, (char *)<ag, 1, 1 ) != 1 ) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* the length itself */
|
|
||||||
rc = ber_write( ber, (char *) netlen, FOUR_BYTE_LEN-1, 1 );
|
|
||||||
|
|
||||||
if( rc != FOUR_BYTE_LEN - 1 ) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* The ber_ptr is at the set/seq start - move it to the end */
|
/* The ber_ptr is at the set/seq start - move it to the end */
|
||||||
(*sos)->sos_ber->ber_ptr += len;
|
ber->ber_ptr = ber->ber_sos_ptr;
|
||||||
|
ber->ber_sos_ptr = NULL;
|
||||||
} else {
|
|
||||||
int i;
|
|
||||||
unsigned char nettag[sizeof(ber_tag_t)];
|
|
||||||
ber_tag_t tmptag = (*sos)->sos_tag;
|
|
||||||
|
|
||||||
if( ber->ber_sos->sos_ptr > ber->ber_end ) {
|
|
||||||
/* The sos_ptr exceeds the end of the BerElement
|
|
||||||
* this can happen, for example, when the sos_ptr
|
|
||||||
* is near the end and no data was written for the
|
|
||||||
* 'V'. We must realloc the BerElement to ensure
|
|
||||||
* we don't overwrite the buffer when writing
|
|
||||||
* the tag and length fields.
|
|
||||||
*/
|
|
||||||
ber_len_t ext = ber->ber_sos->sos_ptr - ber->ber_end;
|
|
||||||
|
|
||||||
if( ber_realloc( ber, ext ) != 0 ) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* the tag */
|
return xlen + *SOS_TAG_END(header); /* lenlen + len + taglen */
|
||||||
taglen = ber_calc_taglen( tmptag );
|
|
||||||
|
|
||||||
for( i = taglen-1; i >= 0; i-- ) {
|
|
||||||
nettag[i] = (unsigned char)(tmptag & 0xffU);
|
|
||||||
tmptag >>= 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
AC_FMEMCPY( (*sos)->sos_first, nettag, taglen );
|
|
||||||
|
|
||||||
if ( ber->ber_options & LBER_USE_DER ) {
|
|
||||||
ltag = (lenlen == 1)
|
|
||||||
? (unsigned char) len
|
|
||||||
: (unsigned char) (0x80U + (lenlen - 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* one byte of length length */
|
|
||||||
(*sos)->sos_first[1] = ltag;
|
|
||||||
|
|
||||||
if ( ber->ber_options & LBER_USE_DER ) {
|
|
||||||
if (lenlen > 1) {
|
|
||||||
/* Write the length itself */
|
|
||||||
AC_FMEMCPY( (*sos)->sos_first + 2, netlen, lenlen - 1 );
|
|
||||||
}
|
|
||||||
if (lenlen != FOUR_BYTE_LEN) {
|
|
||||||
/*
|
|
||||||
* We set aside FOUR_BYTE_LEN bytes for
|
|
||||||
* the length field. Move the data if
|
|
||||||
* we don't actually need that much
|
|
||||||
*/
|
|
||||||
AC_FMEMCPY( (*sos)->sos_first + taglen +
|
|
||||||
lenlen, (*sos)->sos_first + taglen +
|
|
||||||
FOUR_BYTE_LEN, len );
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* the length itself */
|
|
||||||
AC_FMEMCPY( (*sos)->sos_first + taglen + 1,
|
|
||||||
netlen, FOUR_BYTE_LEN - 1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
next->sos_clen += (taglen + lenlen + len);
|
|
||||||
next->sos_ptr += (taglen + lenlen + len);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* we're done with this seqorset, so free it up */
|
|
||||||
ber_memfree_x( (char *) (*sos), ber->ber_memctx );
|
|
||||||
*sos = next;
|
|
||||||
|
|
||||||
return taglen + lenlen + len;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -740,11 +545,10 @@ ber_printf( BerElement *ber, LDAP_CONST char *fmt, ... )
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'N': /* Debug NULL */
|
case 'N': /* Debug NULL */
|
||||||
|
rc = 0;
|
||||||
if( lber_int_null != 0 ) {
|
if( lber_int_null != 0 ) {
|
||||||
/* Insert NULL to ensure peer ignores unknown tags */
|
/* Insert NULL to ensure peer ignores unknown tags */
|
||||||
rc = ber_put_null( ber, lber_int_null );
|
rc = ber_put_null( ber, lber_int_null );
|
||||||
} else {
|
|
||||||
rc = 0;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -55,7 +55,6 @@ ber_skip_data(
|
|||||||
ber_len_t actuallen, nleft;
|
ber_len_t actuallen, nleft;
|
||||||
|
|
||||||
assert( ber != NULL );
|
assert( ber != NULL );
|
||||||
|
|
||||||
assert( LBER_VALID( ber ) );
|
assert( LBER_VALID( ber ) );
|
||||||
|
|
||||||
nleft = ber_pvt_ber_remaining( ber );
|
nleft = ber_pvt_ber_remaining( ber );
|
||||||
@ -66,6 +65,10 @@ ber_skip_data(
|
|||||||
return( (ber_slen_t) actuallen );
|
return( (ber_slen_t) actuallen );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read from the ber buffer. The caller must maintain ber->ber_tag.
|
||||||
|
* Do not use to read whole tags. See ber_get_tag() and ber_skip_data().
|
||||||
|
*/
|
||||||
ber_slen_t
|
ber_slen_t
|
||||||
ber_read(
|
ber_read(
|
||||||
BerElement *ber,
|
BerElement *ber,
|
||||||
@ -76,7 +79,6 @@ ber_read(
|
|||||||
|
|
||||||
assert( ber != NULL );
|
assert( ber != NULL );
|
||||||
assert( buf != NULL );
|
assert( buf != NULL );
|
||||||
|
|
||||||
assert( LBER_VALID( ber ) );
|
assert( LBER_VALID( ber ) );
|
||||||
|
|
||||||
nleft = ber_pvt_ber_remaining( ber );
|
nleft = ber_pvt_ber_remaining( ber );
|
||||||
@ -89,44 +91,46 @@ ber_read(
|
|||||||
return( (ber_slen_t) actuallen );
|
return( (ber_slen_t) actuallen );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Write to the ber buffer.
|
||||||
|
* Note that ber_start_seqorset/ber_put_seqorset() bypass ber_write().
|
||||||
|
*/
|
||||||
ber_slen_t
|
ber_slen_t
|
||||||
ber_write(
|
ber_write(
|
||||||
BerElement *ber,
|
BerElement *ber,
|
||||||
LDAP_CONST char *buf,
|
LDAP_CONST char *buf,
|
||||||
ber_len_t len,
|
ber_len_t len,
|
||||||
int nosos )
|
int zero ) /* nonzero is unsupported from OpenLDAP 2.4.18 */
|
||||||
{
|
{
|
||||||
|
char **p;
|
||||||
|
|
||||||
assert( ber != NULL );
|
assert( ber != NULL );
|
||||||
assert( buf != NULL );
|
assert( buf != NULL );
|
||||||
|
|
||||||
assert( LBER_VALID( ber ) );
|
assert( LBER_VALID( ber ) );
|
||||||
|
|
||||||
if ( nosos || ber->ber_sos == NULL ) {
|
if ( zero != 0 ) {
|
||||||
if ( ber->ber_ptr + len > ber->ber_end ) {
|
ber_log_printf( LDAP_DEBUG_ANY, ber->ber_debug, "%s",
|
||||||
if ( ber_realloc( ber, len ) != 0 ) return( -1 );
|
"ber_write: nonzero 4th argument not supported\n" );
|
||||||
}
|
return( -1 );
|
||||||
AC_MEMCPY( ber->ber_ptr, buf, (size_t)len );
|
|
||||||
ber->ber_ptr += len;
|
|
||||||
return( (ber_slen_t) len );
|
|
||||||
|
|
||||||
} else {
|
|
||||||
if ( ber->ber_sos->sos_ptr + len > ber->ber_end ) {
|
|
||||||
if ( ber_realloc( ber, len ) != 0 ) return( -1 );
|
|
||||||
}
|
|
||||||
AC_MEMCPY( ber->ber_sos->sos_ptr, buf, (size_t)len );
|
|
||||||
ber->ber_sos->sos_ptr += len;
|
|
||||||
ber->ber_sos->sos_clen += len;
|
|
||||||
return( (ber_slen_t) len );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p = ber->ber_sos_ptr == NULL ? &ber->ber_ptr : &ber->ber_sos_ptr;
|
||||||
|
if ( len > (ber_len_t) (ber->ber_end - *p) ) {
|
||||||
|
if ( ber_realloc( ber, len ) != 0 ) return( -1 );
|
||||||
|
}
|
||||||
|
AC_MEMCPY( *p, buf, len );
|
||||||
|
*p += len;
|
||||||
|
|
||||||
|
return( (ber_slen_t) len );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Resize the ber buffer */
|
||||||
int
|
int
|
||||||
ber_realloc( BerElement *ber, ber_len_t len )
|
ber_realloc( BerElement *ber, ber_len_t len )
|
||||||
{
|
{
|
||||||
ber_len_t total;
|
ber_len_t total, offset, sos_offset;
|
||||||
Seqorset *s;
|
Seqorset *s;
|
||||||
long off;
|
char *buf;
|
||||||
char *oldbuf;
|
|
||||||
|
|
||||||
assert( ber != NULL );
|
assert( ber != NULL );
|
||||||
assert( LBER_VALID( ber ) );
|
assert( LBER_VALID( ber ) );
|
||||||
@ -144,7 +148,7 @@ ber_realloc( BerElement *ber, ber_len_t len )
|
|||||||
/* don't realloc by small amounts */
|
/* don't realloc by small amounts */
|
||||||
total += len < LBER_EXBUFSIZ ? LBER_EXBUFSIZ : len;
|
total += len < LBER_EXBUFSIZ ? LBER_EXBUFSIZ : len;
|
||||||
# else
|
# else
|
||||||
{ /* not sure what value this adds */
|
{ /* not sure what value this adds. reduce fragmentation? */
|
||||||
ber_len_t have = (total + (LBER_EXBUFSIZE - 1)) / LBER_EXBUFSIZ;
|
ber_len_t have = (total + (LBER_EXBUFSIZE - 1)) / LBER_EXBUFSIZ;
|
||||||
ber_len_t need = (len + (LBER_EXBUFSIZ - 1)) / LBER_EXBUFSIZ;
|
ber_len_t need = (len + (LBER_EXBUFSIZ - 1)) / LBER_EXBUFSIZ;
|
||||||
total = ( have + need ) * LBER_EXBUFSIZ;
|
total = ( have + need ) * LBER_EXBUFSIZ;
|
||||||
@ -154,35 +158,26 @@ ber_realloc( BerElement *ber, ber_len_t len )
|
|||||||
total += len; /* realloc just what's needed */
|
total += len; /* realloc just what's needed */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
oldbuf = ber->ber_buf;
|
if ( total < len || total > (ber_len_t)-1 / 2 /* max ber_slen_t */ ) {
|
||||||
|
|
||||||
ber->ber_buf = (char *) ber_memrealloc_x( oldbuf, total, ber->ber_memctx );
|
|
||||||
|
|
||||||
if ( ber->ber_buf == NULL ) {
|
|
||||||
ber->ber_buf = oldbuf;
|
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
ber->ber_end = ber->ber_buf + total;
|
buf = ber->ber_buf;
|
||||||
|
offset = ber->ber_ptr - buf;
|
||||||
|
sos_offset = ber->ber_sos_ptr ? ber->ber_sos_ptr - buf : 0;
|
||||||
|
/* if ber_sos_ptr != NULL, it is > ber_buf so that sos_offset > 0 */
|
||||||
|
|
||||||
/*
|
buf = (char *) ber_memrealloc_x( buf, total, ber->ber_memctx );
|
||||||
* If the stinking thing was moved, we need to go through and
|
if ( buf == NULL ) {
|
||||||
* reset all the sos and ber pointers. Offsets would've been
|
return( -1 );
|
||||||
* a better idea... oh well.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ( ber->ber_buf != oldbuf ) {
|
|
||||||
ber->ber_ptr = ber->ber_buf + (ber->ber_ptr - oldbuf);
|
|
||||||
|
|
||||||
for ( s = ber->ber_sos; s != NULL; s = s->sos_next ) {
|
|
||||||
off = s->sos_first - oldbuf;
|
|
||||||
s->sos_first = ber->ber_buf + off;
|
|
||||||
|
|
||||||
off = s->sos_ptr - oldbuf;
|
|
||||||
s->sos_ptr = ber->ber_buf + off;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ber->ber_buf = buf;
|
||||||
|
ber->ber_end = buf + total;
|
||||||
|
ber->ber_ptr = buf + offset;
|
||||||
|
if ( sos_offset )
|
||||||
|
ber->ber_sos_ptr = buf + sos_offset;
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,13 +190,8 @@ ber_free_buf( BerElement *ber )
|
|||||||
|
|
||||||
if ( ber->ber_buf) ber_memfree_x( ber->ber_buf, ber->ber_memctx );
|
if ( ber->ber_buf) ber_memfree_x( ber->ber_buf, ber->ber_memctx );
|
||||||
|
|
||||||
for( s = ber->ber_sos ; s != NULL ; s = next ) {
|
|
||||||
next = s->sos_next;
|
|
||||||
ber_memfree_x( s, ber->ber_memctx );
|
|
||||||
}
|
|
||||||
|
|
||||||
ber->ber_buf = NULL;
|
ber->ber_buf = NULL;
|
||||||
ber->ber_sos = NULL;
|
ber->ber_sos_ptr = NULL;
|
||||||
ber->ber_valid = LBER_UNINITIALIZED;
|
ber->ber_valid = LBER_UNINITIALIZED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -234,7 +224,6 @@ ber_flush2( Sockbuf *sb, BerElement *ber, int freeit )
|
|||||||
|
|
||||||
assert( sb != NULL );
|
assert( sb != NULL );
|
||||||
assert( ber != NULL );
|
assert( ber != NULL );
|
||||||
|
|
||||||
assert( SOCKBUF_VALID( sb ) );
|
assert( SOCKBUF_VALID( sb ) );
|
||||||
assert( LBER_VALID( ber ) );
|
assert( LBER_VALID( ber ) );
|
||||||
|
|
||||||
@ -491,7 +480,6 @@ ber_get_next(
|
|||||||
assert( sb != NULL );
|
assert( sb != NULL );
|
||||||
assert( len != NULL );
|
assert( len != NULL );
|
||||||
assert( ber != NULL );
|
assert( ber != NULL );
|
||||||
|
|
||||||
assert( SOCKBUF_VALID( sb ) );
|
assert( SOCKBUF_VALID( sb ) );
|
||||||
assert( LBER_VALID( ber ) );
|
assert( LBER_VALID( ber ) );
|
||||||
|
|
||||||
@ -732,9 +720,13 @@ void
|
|||||||
ber_rewind ( BerElement * ber )
|
ber_rewind ( BerElement * ber )
|
||||||
{
|
{
|
||||||
ber->ber_rwptr = NULL;
|
ber->ber_rwptr = NULL;
|
||||||
ber->ber_sos = NULL;
|
ber->ber_sos_ptr = NULL;
|
||||||
ber->ber_end = ber->ber_ptr;
|
ber->ber_end = ber->ber_ptr;
|
||||||
ber->ber_ptr = ber->ber_buf;
|
ber->ber_ptr = ber->ber_buf;
|
||||||
|
#if 0 /* TODO: Should we add this? */
|
||||||
|
ber->ber_tag = LBER_DEFAULT;
|
||||||
|
ber->ber_usertag = 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -72,12 +72,39 @@ LBER_F( int ) ber_pvt_log_output(
|
|||||||
LBER_V (struct lber_options) ber_int_options;
|
LBER_V (struct lber_options) ber_int_options;
|
||||||
#define ber_int_debug ber_int_options.lbo_debug
|
#define ber_int_debug ber_int_options.lbo_debug
|
||||||
|
|
||||||
|
/* Data encoded in ASN.1 BER format */
|
||||||
struct berelement {
|
struct berelement {
|
||||||
struct lber_options ber_opts;
|
struct lber_options ber_opts;
|
||||||
#define ber_valid ber_opts.lbo_valid
|
#define ber_valid ber_opts.lbo_valid
|
||||||
#define ber_options ber_opts.lbo_options
|
#define ber_options ber_opts.lbo_options
|
||||||
#define ber_debug ber_opts.lbo_debug
|
#define ber_debug ber_opts.lbo_debug
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The members below, when not NULL/LBER_DEFAULT/etc, are:
|
||||||
|
* ber_buf Data buffer. Other pointers normally point into it.
|
||||||
|
* ber_rwptr Read/write cursor for Sockbuf I/O.
|
||||||
|
* ber_memctx Context passed to ber_memalloc() & co.
|
||||||
|
* When decoding data (reading it from the BerElement):
|
||||||
|
* ber_end End of BER data.
|
||||||
|
* ber_ptr Read cursor, except for 1st octet of tags.
|
||||||
|
* ber_tag 1st octet of next tag, saved from *ber_ptr when
|
||||||
|
* ber_ptr may be pointing at a tag and is >ber_buf.
|
||||||
|
* The octet *ber_ptr itself may get overwritten with
|
||||||
|
* a \0, to terminate the preceding element.
|
||||||
|
* When encoding data (writing it to the BerElement):
|
||||||
|
* ber_end End of allocated buffer - 1 (allowing a final \0).
|
||||||
|
* ber_ptr Last complete BER element (normally write cursor).
|
||||||
|
* ber_sos_ptr NULL or write cursor for incomplete sequence or set.
|
||||||
|
* ber_sos_inner offset(seq/set length octets) if ber_sos_ptr!=NULL.
|
||||||
|
* ber_tag Default tag for next ber_printf() element.
|
||||||
|
* ber_usertag True after a ber_printf format char set ber_tag.
|
||||||
|
* ber_len Reused for ber_sos_inner.
|
||||||
|
* When output to a Sockbuf:
|
||||||
|
* ber_ptr End of encoded data to write.
|
||||||
|
* When input from a Sockbuf:
|
||||||
|
* See ber_get_next().
|
||||||
|
*/
|
||||||
|
|
||||||
/* Do not change the order of these 3 fields! see ber_get_next */
|
/* Do not change the order of these 3 fields! see ber_get_next */
|
||||||
ber_tag_t ber_tag;
|
ber_tag_t ber_tag;
|
||||||
ber_len_t ber_len;
|
ber_len_t ber_len;
|
||||||
@ -87,7 +114,9 @@ struct berelement {
|
|||||||
char *ber_ptr;
|
char *ber_ptr;
|
||||||
char *ber_end;
|
char *ber_end;
|
||||||
|
|
||||||
struct seqorset *ber_sos;
|
char *ber_sos_ptr;
|
||||||
|
# define ber_sos_inner ber_len /* reused for binary compat */
|
||||||
|
|
||||||
char *ber_rwptr;
|
char *ber_rwptr;
|
||||||
void *ber_memctx;
|
void *ber_memctx;
|
||||||
};
|
};
|
||||||
@ -115,15 +144,6 @@ struct sockbuf {
|
|||||||
|
|
||||||
#define SOCKBUF_VALID( sb ) ( (sb)->sb_valid == LBER_VALID_SOCKBUF )
|
#define SOCKBUF_VALID( sb ) ( (sb)->sb_valid == LBER_VALID_SOCKBUF )
|
||||||
|
|
||||||
struct seqorset {
|
|
||||||
BerElement *sos_ber;
|
|
||||||
ber_len_t sos_clen;
|
|
||||||
ber_tag_t sos_tag;
|
|
||||||
char *sos_first;
|
|
||||||
char *sos_ptr;
|
|
||||||
struct seqorset *sos_next;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* decode.c, encode.c
|
* decode.c, encode.c
|
||||||
|
Loading…
Reference in New Issue
Block a user