Diff for /libraries/liblber/encode.c between versions 1.23 and 1.23.4.6

version 1.23, 1999/06/28 18:12:30 version 1.23.4.6, 2000/10/12 19:52:39
Line 1 Line 1
 /* encode.c - ber output encoding routines */  /* encode.c - ber output encoding routines */
   /* $OpenLDAP: pkg/ldap/libraries/liblber/encode.c,v 1.23.4.5 2000/07/29 01:53:07 kurt Exp $ */
 /*  /*
  * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.   * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file   * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */   */
 /* Portions  /* Portions
Line 25 Line 26
 #include <ac/socket.h>  #include <ac/socket.h>
 #include <ac/string.h>  #include <ac/string.h>
   
 #undef LDAP_F_PRE  
 #define LDAP_F_PRE LDAP_F_EXPORT  
   
 #include "lber-int.h"  #include "lber-int.h"
   
 static int ber_put_len LDAP_P((  static int ber_put_len LDAP_P((
Line 57  ber_calc_taglen( ber_tag_t tag ) Line 55  ber_calc_taglen( ber_tag_t tag )
         for ( i = sizeof(ber_tag_t) - 1; i > 0; i-- ) {          for ( i = sizeof(ber_tag_t) - 1; i > 0; i-- ) {
                 mask = ((ber_tag_t)0xffU << (i * 8));                  mask = ((ber_tag_t)0xffU << (i * 8));
                 /* not all zero */                  /* not all zero */
                 if ( tag & mask )                  if ( tag & mask ) break;
                         break;  
         }          }
   
         return( i + 1 );          return i + 1;
 }  }
   
 static int  static int
Line 72  ber_put_tag( Line 69  ber_put_tag(
 {  {
         int rc;          int rc;
         ber_len_t       taglen;          ber_len_t       taglen;
         ber_tag_t       ntag;          ber_len_t       i;
           unsigned char nettag[sizeof(ber_tag_t)];
   
         assert( ber != NULL );          assert( ber != NULL );
         assert( BER_VALID( ber ) );          assert( BER_VALID( ber ) );
   
         taglen = ber_calc_taglen( tag );          taglen = ber_calc_taglen( tag );
   
         ntag = LBER_TAG_HTON( tag );          for( i=0; i<taglen; i++ ) {
                   nettag[(sizeof(ber_tag_t)-1) - i] = (unsigned char)(tag & 0xffU);
                   tag >>= 8;
           }
   
         rc = ber_write( ber,          rc = ber_write( ber,
                 ((char *) &ntag) + sizeof(ber_tag_t) - taglen,                  &nettag[sizeof(ber_tag_t) - taglen],
             taglen, nosos );              taglen, nosos );
   
         return rc;          return rc;
Line 97  ber_calc_lenlen( ber_len_t len ) Line 98  ber_calc_lenlen( ber_len_t len )
          */           */
   
         if ( len <= (ber_len_t) 0x7FU )          if ( len <= (ber_len_t) 0x7FU )
                 return( 1 );                  return 1;
   
         /*          /*
          * long len otherwise - one byte with bit 8 set, giving the           * long len otherwise - one byte with bit 8 set, giving the
Line 105  ber_calc_lenlen( ber_len_t len ) Line 106  ber_calc_lenlen( ber_len_t len )
          */           */
   
         if ( len <= (ber_len_t) 0xffU )          if ( len <= (ber_len_t) 0xffU )
                 return( 2 );                  return 2;
         if ( len <= (ber_len_t) 0xffffU )          if ( len <= (ber_len_t) 0xffffU )
                 return( 3 );                  return 3;
         if ( len <= (ber_len_t) 0xffffffU )          if ( len <= (ber_len_t) 0xffffffU )
                 return( 4 );                  return 4;
   
         return( 5 );          return 5;
 }  }
   
 static int  static int
 ber_put_len( BerElement *ber, ber_len_t len, int nosos )  ber_put_len( BerElement *ber, ber_len_t len, int nosos )
 {  {
         int             i;          int rc;
           int             i,j;
         char            lenlen;          char            lenlen;
         ber_len_t       mask;          ber_len_t       mask;
         ber_len_t       netlen;          unsigned char netlen[sizeof(ber_len_t)];
   
         assert( ber != NULL );          assert( ber != NULL );
         assert( BER_VALID( ber ) );          assert( BER_VALID( ber ) );
Line 131  ber_put_len( BerElement *ber, ber_len_t Line 133  ber_put_len( BerElement *ber, ber_len_t
          */           */
   
         if ( len <= 127 ) {          if ( len <= 127 ) {
                 netlen = LBER_LEN_HTON( len );                  char length_byte = (char) len;
                 return( ber_write( ber, (char *) &netlen + sizeof(long) - 1,                  return ber_write( ber, &length_byte, 1, nosos );
                     1, nosos ) );  
         }          }
   
         /*          /*
Line 143  ber_put_len( BerElement *ber, ber_len_t Line 144  ber_put_len( BerElement *ber, ber_len_t
   
         /* find the first non-all-zero byte */          /* find the first non-all-zero byte */
         for ( i = sizeof(ber_len_t) - 1; i > 0; i-- ) {          for ( i = sizeof(ber_len_t) - 1; i > 0; i-- ) {
                 mask = (0xffU << (i * 8));                  mask = ((ber_len_t)0xffU << (i * 8));
                 /* not all zero */                  /* not all zero */
                 if ( len & mask )                  if ( len & mask ) break;
                         break;  
         }          }
         lenlen = (unsigned char) ++i;          lenlen = (unsigned char) ++i;
         if ( lenlen > 4 )          if ( lenlen > 4 )
                 return( -1 );                  return -1;
   
         lenlen |= 0x80UL;          lenlen |= 0x80UL;
   
         /* write the length of the length */          /* write the length of the length */
         if ( ber_write( ber, &lenlen, 1, nosos ) != 1 )          if ( ber_write( ber, &lenlen, 1, nosos ) != 1 )
                 return( -1 );                  return -1;
   
           for( j=0; j<i; j++) {
                   netlen[(sizeof(ber_len_t)-1) - j] = (unsigned char)(len & 0xffU);
                   len >>= 8;
           }
   
         /* write the length itself */          /* write the length itself */
         netlen = LBER_LEN_HTON( len );          rc = ber_write( ber,
         if ( ber_write( ber, (char *) &netlen + (sizeof(ber_len_t) - i), i, nosos )                  &netlen[sizeof(ber_len_t)-i],
             != i )                  i, nosos );
                 return( -1 );  
   
         return( i + 1 );          return rc == i ?  i+1 : -1;
 }  }
   
 static int  static int
Line 172  ber_put_int_or_enum( Line 177  ber_put_int_or_enum(
         ber_int_t num,          ber_int_t num,
         ber_tag_t tag )          ber_tag_t tag )
 {  {
         int     i, sign;          int rc;
           int     i, j, sign;
         ber_len_t       len, lenlen, taglen;          ber_len_t       len, lenlen, taglen;
         ber_int_t       netnum, mask;          ber_uint_t      unum, mask;
           unsigned char netnum[sizeof(ber_uint_t)];
   
         assert( ber != NULL );          assert( ber != NULL );
         assert( BER_VALID( ber ) );          assert( BER_VALID( ber ) );
   
         sign = (num < 0);          sign = (num < 0);
           unum = num;     /* Bit fiddling should be done with unsigned values */
   
         /*          /*
          * high bit is set - look for first non-all-one byte           * high bit is set - look for first non-all-one byte
          * high bit is clear - look for first non-all-zero byte           * high bit is clear - look for first non-all-zero byte
          */           */
         for ( i = sizeof(ber_int_t) - 1; i > 0; i-- ) {          for ( i = sizeof(ber_int_t) - 1; i > 0; i-- ) {
                 mask = (0xffU << (i * 8));                  mask = ((ber_uint_t)0xffU << (i * 8));
   
                 if ( sign ) {                  if ( sign ) {
                         /* not all ones */                          /* not all ones */
                         if ( (num & mask) != mask )                          if ( (unum & mask) != mask ) break;
                                 break;  
                 } else {                  } else {
                         /* not all zero */                          /* not all zero */
                         if ( num & mask )                          if ( unum & mask ) break;
                                 break;  
                 }                  }
         }          }
   
Line 203  ber_put_int_or_enum( Line 209  ber_put_int_or_enum(
          * we now have the "leading byte".  if the high bit on this           * we now have the "leading byte".  if the high bit on this
          * byte matches the sign bit, we need to "back up" a byte.           * byte matches the sign bit, we need to "back up" a byte.
          */           */
         mask = (num & (0x80U << (i * 8)));          mask = (unum & ((ber_uint_t)0x80U << (i * 8)));
         if ( (mask && !sign) || (sign && !mask) )          if ( (mask && !sign) || (sign && !mask) ) {
                 i++;                  i++;
           }
   
         len = i + 1;          len = i + 1;
   
         if ( (taglen = ber_put_tag( ber, tag, 0 )) == -1 )          if ( (taglen = ber_put_tag( ber, tag, 0 )) == -1 ) {
                 return( -1 );                  return -1;
           }
   
         if ( (lenlen = ber_put_len( ber, len, 0 )) == -1 )          if ( (lenlen = ber_put_len( ber, len, 0 )) == -1 )
                 return( -1 );                  return -1;
         i++;          i++;
         netnum = LBER_INT_HTON( num );  
         if ( ber_write( ber, (char *) &netnum + (sizeof(ber_int_t) - i), i, 0 )          for( j=0; j<i; j++ ) {
            != i )                  netnum[(sizeof(ber_int_t)-1) - j] = (unsigned char)(unum & 0xffU);
                 return( -1 );                  unum >>= 8;
           }
   
           rc = ber_write( ber,
                   &netnum[sizeof(ber_int_t) - i],
                   i, 0 );
   
         /* length of tag + length + contents */          /* length of tag + length + contents */
         return( taglen + lenlen + i );          return rc == i ? taglen + lenlen + i : -1;
 }  }
   
 int  int
Line 233  ber_put_enum( Line 246  ber_put_enum(
         assert( ber != NULL );          assert( ber != NULL );
         assert( BER_VALID( ber ) );          assert( BER_VALID( ber ) );
   
         if ( tag == LBER_DEFAULT )          if ( tag == LBER_DEFAULT ) {
                 tag = LBER_ENUMERATED;                  tag = LBER_ENUMERATED;
           }
   
         return( ber_put_int_or_enum( ber, num, tag ) );          return ber_put_int_or_enum( ber, num, tag );
 }  }
   
 int  int
Line 248  ber_put_int( Line 262  ber_put_int(
         assert( ber != NULL );          assert( ber != NULL );
         assert( BER_VALID( ber ) );          assert( BER_VALID( ber ) );
   
         if ( tag == LBER_DEFAULT )          if ( tag == LBER_DEFAULT ) {
                 tag = LBER_INTEGER;                  tag = LBER_INTEGER;
           }
   
         return( ber_put_int_or_enum( ber, num, tag ) );          return ber_put_int_or_enum( ber, num, tag );
 }  }
   
 int  int
Line 263  ber_put_ostring( Line 278  ber_put_ostring(
 {  {
         ber_len_t       taglen, lenlen;          ber_len_t       taglen, lenlen;
         int rc;          int rc;
 #ifdef STR_TRANSLATION  
         int     free_str;  
 #endif /* STR_TRANSLATION */  
   
         assert( ber != NULL );          assert( ber != NULL );
         assert( str != NULL );          assert( str != NULL );
   
         assert( BER_VALID( ber ) );          assert( BER_VALID( ber ) );
   
         if ( tag == LBER_DEFAULT )          if ( tag == LBER_DEFAULT ) {
                 tag = LBER_OCTETSTRING;                  tag = LBER_OCTETSTRING;
           }
   
         if ( (taglen = ber_put_tag( ber, tag, 0 )) == -1 )          if ( (taglen = ber_put_tag( ber, tag, 0 )) == -1 )
                 return( -1 );                  return -1;
   
 #ifdef STR_TRANSLATION  
         if ( len > 0 && ( ber->ber_options & LBER_TRANSLATE_STRINGS ) != 0 &&  
             ber->ber_encode_translate_proc ) {  
                 if ( (*(ber->ber_encode_translate_proc))( &str, &len, 0 )  
                     != 0 ) {  
                         return( -1 );  
                 }  
                 free_str = 1;  
         } else {  
                 free_str = 0;  
         }  
 #endif /* STR_TRANSLATION */  
   
         if ( (lenlen = ber_put_len( ber, len, 0 )) == -1 ||          if ( (lenlen = ber_put_len( ber, len, 0 )) == -1 ||
                 (unsigned long) ber_write( ber, str, len, 0 ) != len ) {                  (ber_len_t) ber_write( ber, str, len, 0 ) != len ) {
                 rc = -1;                  rc = -1;
         } else {          } else {
                 /* return length of tag + length + contents */                  /* return length of tag + length + contents */
                 rc = taglen + lenlen + len;                  rc = taglen + lenlen + len;
         }          }
   
 #ifdef STR_TRANSLATION          return rc;
         if ( free_str ) {  
                 LBER_FREE( str );  
         }  
 #endif /* STR_TRANSLATION */  
   
         return( rc );  
 }  }
   
 int  int
Line 335  ber_put_string( Line 329  ber_put_string(
   
         assert( BER_VALID( ber ) );          assert( BER_VALID( ber ) );
   
         return( ber_put_ostring( ber, str, strlen( str ), tag ));          return ber_put_ostring( ber, str, strlen( str ), tag );
 }  }
   
 int  int
Line 353  ber_put_bitstring( Line 347  ber_put_bitstring(
   
         assert( BER_VALID( ber ) );          assert( BER_VALID( ber ) );
   
         if ( tag == LBER_DEFAULT )          if ( tag == LBER_DEFAULT ) {
                 tag = LBER_BITSTRING;                  tag = LBER_BITSTRING;
           }
   
         if ( (taglen = ber_put_tag( ber, tag, 0 )) == -1 )          if ( (taglen = ber_put_tag( ber, tag, 0 )) == -1 ) {
                 return( -1 );                  return -1;
           }
   
         len = ( blen + 7 ) / 8;          len = ( blen + 7 ) / 8;
         unusedbits = (unsigned char) ((len * 8) - blen);          unusedbits = (unsigned char) ((len * 8) - blen);
         if ( (lenlen = ber_put_len( ber, len + 1, 0 )) == -1 )          if ( (lenlen = ber_put_len( ber, len + 1, 0 )) == -1 ) {
                 return( -1 );                  return -1;
           }
   
         if ( ber_write( ber, (char *)&unusedbits, 1, 0 ) != 1 )          if ( ber_write( ber, (char *)&unusedbits, 1, 0 ) != 1 ) {
                 return( -1 );                  return -1;
           }
   
         if ( (ber_len_t) ber_write( ber, str, len, 0 ) != len )          if ( (ber_len_t) ber_write( ber, str, len, 0 ) != len ) {
                 return( -1 );                  return -1;
           }
   
         /* return length of tag + length + unused bit count + contents */          /* return length of tag + length + unused bit count + contents */
         return( taglen + 1 + lenlen + len );          return taglen + 1 + lenlen + len;
 }  }
   
 int  int
Line 382  ber_put_null( BerElement *ber, ber_tag_t Line 381  ber_put_null( BerElement *ber, ber_tag_t
         assert( ber != NULL );          assert( ber != NULL );
         assert( BER_VALID( ber ) );          assert( BER_VALID( ber ) );
   
         if ( tag == LBER_DEFAULT )          if ( tag == LBER_DEFAULT ) {
                 tag = LBER_NULL;                  tag = LBER_NULL;
           }
   
         if ( (taglen = ber_put_tag( ber, tag, 0 )) == -1 )          if ( (taglen = ber_put_tag( ber, tag, 0 )) == -1 ) {
                 return( -1 );                  return -1;
           }
   
         if ( ber_put_len( ber, 0, 0 ) != 1 )          if ( ber_put_len( ber, 0, 0 ) != 1 ) {
                 return( -1 );                  return -1;
           }
   
         return( taglen + 1 );          return taglen + 1;
 }  }
   
 int  int
Line 401  ber_put_boolean( Line 403  ber_put_boolean(
         ber_tag_t tag )          ber_tag_t tag )
 {  {
         ber_len_t               taglen;          ber_len_t               taglen;
         unsigned char   trueval = 0xFFU;          unsigned char   trueval = (unsigned char) -1;
         unsigned char   falseval = 0x00U;          unsigned char   falseval = 0;
   
         assert( ber != NULL );          assert( ber != NULL );
         assert( BER_VALID( ber ) );          assert( BER_VALID( ber ) );
Line 410  ber_put_boolean( Line 412  ber_put_boolean(
         if ( tag == LBER_DEFAULT )          if ( tag == LBER_DEFAULT )
                 tag = LBER_BOOLEAN;                  tag = LBER_BOOLEAN;
   
         if ( (taglen = ber_put_tag( ber, tag, 0 )) == -1 )          if ( (taglen = ber_put_tag( ber, tag, 0 )) == -1 ) {
                 return( -1 );                  return -1;
           }
   
         if ( ber_put_len( ber, 1, 0 ) != 1 )          if ( ber_put_len( ber, 1, 0 ) != 1 ) {
                 return( -1 );                  return -1;
           }
   
         if ( ber_write( ber, (char *)(boolval ? &trueval : &falseval), 1, 0 )          if ( ber_write( ber, (char *)(boolval ? &trueval : &falseval), 1, 0 )
             != 1 )                  != 1 )
                 return( -1 );          {
                   return -1;
           }
   
         return( taglen + 2 );          return taglen + 2;
 }  }
   
 #define FOUR_BYTE_LEN   5  #define FOUR_BYTE_LEN   5
Line 437  ber_start_seqorset( Line 443  ber_start_seqorset(
   
         new = (Seqorset *) LBER_CALLOC( 1, sizeof(Seqorset) );          new = (Seqorset *) LBER_CALLOC( 1, sizeof(Seqorset) );
   
         if ( new == NULL )          if ( new == NULL ) {
                 return( -1 );                  return -1;
           }
   
         new->sos_ber = ber;          new->sos_ber = ber;
         if ( ber->ber_sos == NULL )          if ( ber->ber_sos == NULL ) {
                 new->sos_first = ber->ber_ptr;                  new->sos_first = ber->ber_ptr;
         else          } else {
                 new->sos_first = ber->ber_sos->sos_ptr;                  new->sos_first = ber->ber_sos->sos_ptr;
           }
   
         /* Set aside room for a 4 byte length field */          /* Set aside room for a 4 byte length field */
         new->sos_ptr = new->sos_first + ber_calc_taglen( tag ) + FOUR_BYTE_LEN;          new->sos_ptr = new->sos_first + ber_calc_taglen( tag ) + FOUR_BYTE_LEN;
Line 453  ber_start_seqorset( Line 461  ber_start_seqorset(
         new->sos_next = ber->ber_sos;          new->sos_next = ber->ber_sos;
         ber->ber_sos = new;          ber->ber_sos = new;
   
         return( 0 );          return 0;
 }  }
   
 int  int
Line 462  ber_start_seq( BerElement *ber, ber_tag_ Line 470  ber_start_seq( BerElement *ber, ber_tag_
         assert( ber != NULL );          assert( ber != NULL );
         assert( BER_VALID( ber ) );          assert( BER_VALID( ber ) );
   
         if ( tag == LBER_DEFAULT )          if ( tag == LBER_DEFAULT ) {
                 tag = LBER_SEQUENCE;                  tag = LBER_SEQUENCE;
           }
   
         return( ber_start_seqorset( ber, tag ) );          return ber_start_seqorset( ber, tag );
 }  }
   
 int  int
Line 474  ber_start_set( BerElement *ber, ber_tag_ Line 483  ber_start_set( BerElement *ber, ber_tag_
         assert( ber != NULL );          assert( ber != NULL );
         assert( BER_VALID( ber ) );          assert( BER_VALID( ber ) );
   
         if ( tag == LBER_DEFAULT )          if ( tag == LBER_DEFAULT ) {
                 tag = LBER_SET;                  tag = LBER_SET;
           }
   
         return( ber_start_seqorset( ber, tag ) );          return ber_start_seqorset( ber, tag );
 }  }
   
 static int  static int
 ber_put_seqorset( BerElement *ber )  ber_put_seqorset( BerElement *ber )
 {  {
         ber_len_t       len, netlen;          int rc;
           ber_len_t       len;
           unsigned char netlen[sizeof(ber_len_t)];
         ber_len_t       taglen, lenlen;          ber_len_t       taglen, lenlen;
         unsigned char   ltag = 0x80U + FOUR_BYTE_LEN - 1;          unsigned char   ltag = 0x80U + FOUR_BYTE_LEN - 1;
         Seqorset        *next;          Seqorset        *next;
Line 501  ber_put_seqorset( BerElement *ber ) Line 513  ber_put_seqorset( BerElement *ber )
          */           */
   
         len = (*sos)->sos_clen;          len = (*sos)->sos_clen;
         netlen = LBER_LEN_HTON( len );  
         if ( sizeof(ber_len_t) > 4 && len > 0xffffffffUL )          if ( sizeof(ber_len_t) > 4 && len > 0xffffffffUL ) {
                 return( -1 );                  return -1;
           }
   
         if ( ber->ber_options & LBER_USE_DER ) {          if ( ber->ber_options & LBER_USE_DER ) {
                 lenlen = ber_calc_lenlen( len );                  lenlen = ber_calc_lenlen( len );
   
         } else {          } else {
                 lenlen = FOUR_BYTE_LEN;                  lenlen = FOUR_BYTE_LEN;
         }          }
   
           if( lenlen > 1 ) {
                   ber_len_t i;
                   for( i=0; i < lenlen-1; i++ ) {
                           netlen[(sizeof(ber_len_t)-1) - i] = 
                                   (unsigned char)((len >> i*8) & 0xffU);
                   }
           } else {
                   netlen[sizeof(ber_len_t)-1] = (unsigned char)(len & 0x7fU);
           }
   
         if ( (next = (*sos)->sos_next) == NULL ) {          if ( (next = (*sos)->sos_next) == NULL ) {
                 /* write the tag */                  /* write the tag */
                 if ( (taglen = ber_put_tag( ber, (*sos)->sos_tag, 1 )) == -1 )                  if ( (taglen = ber_put_tag( ber, (*sos)->sos_tag, 1 )) == -1 )
Line 518  ber_put_seqorset( BerElement *ber ) Line 542  ber_put_seqorset( BerElement *ber )
   
                 if ( ber->ber_options & LBER_USE_DER ) {                  if ( ber->ber_options & LBER_USE_DER ) {
                         /* Write the length in the minimum # of octets */                          /* Write the length in the minimum # of octets */
                         if ( ber_put_len( ber, len, 1 ) == -1 )                          if ( ber_put_len( ber, len, 1 ) == -1 ) {
                                 return( -1 );                                  return -1;
                           }
   
                         if (lenlen != FOUR_BYTE_LEN) {                          if (lenlen != FOUR_BYTE_LEN) {
                                 /*                                  /*
Line 527  ber_put_seqorset( BerElement *ber ) Line 552  ber_put_seqorset( BerElement *ber )
                                  * the length field.  Move the data if                                   * the length field.  Move the data if
                                  * we don't actually need that much                                   * we don't actually need that much
                                  */                                   */
                                 SAFEMEMCPY( (*sos)->sos_first + taglen +                                  AC_MEMCPY( (*sos)->sos_first + taglen +
                                     lenlen, (*sos)->sos_first + taglen +                                      lenlen, (*sos)->sos_first + taglen +
                                     FOUR_BYTE_LEN, len );                                      FOUR_BYTE_LEN, len );
                         }                          }
                 } else {                  } else {
                         /* Fill FOUR_BYTE_LEN bytes for length field */                          /* Fill FOUR_BYTE_LEN bytes for length field */
                         /* one byte of length length */                          /* one byte of length length */
                         if ( ber_write( ber, (char *)&ltag, 1, 1 ) != 1 )                          if ( ber_write( ber, (char *)&ltag, 1, 1 ) != 1 ) {
                                 return( -1 );                                  return -1;
                           }
   
                         /* the length itself */                          /* the length itself */
                         if ( ber_write( ber, (char *) &netlen + sizeof(long)                          rc  = ber_write( ber,
                             - (FOUR_BYTE_LEN - 1), FOUR_BYTE_LEN - 1, 1 )                                  &netlen[sizeof(ber_len_t) - (FOUR_BYTE_LEN-1)],
                             != FOUR_BYTE_LEN - 1 )                                  FOUR_BYTE_LEN-1, 1 );
                                 return( -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;                  (*sos)->sos_ber->ber_ptr += len;
   
         } else {          } else {
                 ber_tag_t       ntag;                  ber_len_t 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 */                  /* the tag */
                 taglen = ber_calc_taglen( (*sos)->sos_tag );                  taglen = ber_calc_taglen( tmptag );
                 ntag = LBER_TAG_HTON( (*sos)->sos_tag );  
                 SAFEMEMCPY( (*sos)->sos_first, (char *) &ntag +                  for( i = 0; i < taglen; i++ ) {
                     sizeof(ber_tag_t) - taglen, taglen );                          nettag[(sizeof(ber_tag_t)-1) - i] = (unsigned char)(tmptag & 0xffU);
                           tmptag >>= 8;
                   }
   
                   AC_FMEMCPY( (*sos)->sos_first,
                           &nettag[sizeof(ber_tag_t) - taglen],
                           taglen );
   
                 if ( ber->ber_options & LBER_USE_DER ) {                  if ( ber->ber_options & LBER_USE_DER ) {
                         ltag = (lenlen == 1)                          ltag = (lenlen == 1)
Line 561  ber_put_seqorset( BerElement *ber ) Line 614  ber_put_seqorset( BerElement *ber )
                 }                  }
   
                 /* one byte of length length */                  /* one byte of length length */
                 SAFEMEMCPY( (*sos)->sos_first + 1, &ltag, 1 );                  (*sos)->sos_first[1] = ltag;
   
                 if ( ber->ber_options & LBER_USE_DER ) {                  if ( ber->ber_options & LBER_USE_DER ) {
                         if (lenlen > 1) {                          if (lenlen > 1) {
                                 /* Write the length itself */                                  /* Write the length itself */
                                 SAFEMEMCPY( (*sos)->sos_first + 2,                                  AC_FMEMCPY( (*sos)->sos_first + 2,
                                     (char *)&netlen + sizeof(ber_len_t) -                                      &netlen[sizeof(ber_len_t) - (lenlen - 1)],
                                     (lenlen - 1),                                          lenlen - 1 );
                                     lenlen - 1 );  
                         }                          }
                         if (lenlen != FOUR_BYTE_LEN) {                          if (lenlen != FOUR_BYTE_LEN) {
                                 /*                                  /*
Line 577  ber_put_seqorset( BerElement *ber ) Line 629  ber_put_seqorset( BerElement *ber )
                                  * the length field.  Move the data if                                   * the length field.  Move the data if
                                  * we don't actually need that much                                   * we don't actually need that much
                                  */                                   */
                                 SAFEMEMCPY( (*sos)->sos_first + taglen +                                  AC_FMEMCPY( (*sos)->sos_first + taglen +
                                     lenlen, (*sos)->sos_first + taglen +                                      lenlen, (*sos)->sos_first + taglen +
                                     FOUR_BYTE_LEN, len );                                      FOUR_BYTE_LEN, len );
                         }                          }
                 } else {                  } else {
                         /* the length itself */                          /* the length itself */
                         SAFEMEMCPY( (*sos)->sos_first + taglen + 1,                          AC_FMEMCPY( (*sos)->sos_first + taglen + 1,
                             (char *) &netlen + sizeof(ber_len_t) -                              &netlen[sizeof(ber_len_t) - (FOUR_BYTE_LEN - 1)],
                             (FOUR_BYTE_LEN - 1), FOUR_BYTE_LEN - 1 );                                  FOUR_BYTE_LEN - 1 );
                 }                  }
   
                 next->sos_clen += (taglen + lenlen + len);                  next->sos_clen += (taglen + lenlen + len);
Line 596  ber_put_seqorset( BerElement *ber ) Line 648  ber_put_seqorset( BerElement *ber )
         LBER_FREE( (char *) (*sos) );          LBER_FREE( (char *) (*sos) );
         *sos = next;          *sos = next;
   
         return( taglen + lenlen + len );          return taglen + lenlen + len;
 }  }
   
 int  int
Line 605  ber_put_seq( BerElement *ber ) Line 657  ber_put_seq( BerElement *ber )
         assert( ber != NULL );          assert( ber != NULL );
         assert( BER_VALID( ber ) );          assert( BER_VALID( ber ) );
   
         return( ber_put_seqorset( ber ) );          return ber_put_seqorset( ber );
 }  }
   
 int  int
Line 614  ber_put_set( BerElement *ber ) Line 666  ber_put_set( BerElement *ber )
         assert( ber != NULL );          assert( ber != NULL );
         assert( BER_VALID( ber ) );          assert( BER_VALID( ber ) );
   
         return( ber_put_seqorset( ber ) );          return ber_put_seqorset( ber );
 }  }
   
   /* N tag */
   static ber_tag_t lber_int_null = 0;
   
 /* VARARGS */  /* VARARGS */
 int  int
 ber_printf  ber_printf( BerElement *ber, LDAP_CONST char *fmt, ... )
 #ifdef HAVE_STDARG  
         ( BerElement *ber,  
         LDAP_CONST char *fmt,  
         ... )  
 #else  
         ( va_alist )  
 va_dcl  
 #endif  
 {  {
         va_list         ap;          va_list         ap;
 #ifndef HAVE_STDARG  
         BerElement      *ber;  
         char            *fmt;  
 #endif  
         char            *s, **ss;          char            *s, **ss;
         struct berval   *bv, **bvp;          struct berval   *bv, **bvp;
         int             rc;          int             rc;
         ber_int_t       i;          ber_int_t       i;
         ber_len_t       len;          ber_len_t       len;
   
 #ifdef HAVE_STDARG  
         va_start( ap, fmt );  
 #else  
         va_start( ap );  
         ber = va_arg( ap, BerElement * );  
         fmt = va_arg( ap, char * );  
 #endif  
   
         assert( ber != NULL );          assert( ber != NULL );
         assert( fmt != NULL );          assert( fmt != NULL );
   
         assert( BER_VALID( ber ) );          assert( BER_VALID( ber ) );
   
           va_start( ap, fmt );
   
         for ( rc = 0; *fmt && rc != -1; fmt++ ) {          for ( rc = 0; *fmt && rc != -1; fmt++ ) {
                 switch ( *fmt ) {                  switch ( *fmt ) {
                 case '!': { /* hook */                  case '!': { /* hook */
Line 684  va_dcl Line 721  va_dcl
                         rc = ber_put_null( ber, ber->ber_tag );                          rc = ber_put_null( ber, ber->ber_tag );
                         break;                          break;
   
                   case 'N':       /* Debug NULL */
                           if( lber_int_null != 0 ) {
                                   /* Insert NULL to ensure peer ignores unknown tags */
                                   rc = ber_put_null( ber, lber_int_null );
                           } else {
                                   rc = 0;
                           }
                           break;
   
                 case 'o':       /* octet string (non-null terminated) */                  case 'o':       /* octet string (non-null terminated) */
                         s = va_arg( ap, char * );                          s = va_arg( ap, char * );
                         len = va_arg( ap, ber_len_t );                          len = va_arg( ap, ber_len_t );
Line 702  va_dcl Line 748  va_dcl
                         break;                          break;
   
                 case 'B':       /* bit string */                  case 'B':       /* bit string */
                   case 'X':       /* bit string (deprecated) */
                         s = va_arg( ap, char * );                          s = va_arg( ap, char * );
                         len = va_arg( ap, int );        /* in bits */                          len = va_arg( ap, int );        /* in bits */
                         rc = ber_put_bitstring( ber, s, len, ber->ber_tag );                          rc = ber_put_bitstring( ber, s, len, ber->ber_tag );
Line 765  va_dcl Line 812  va_dcl
   
         va_end( ap );          va_end( ap );
   
         return( rc );          return rc;
 }  }

Removed from v.1.23  
changed lines
  Added in v.1.23.4.6


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