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

version 1.23, 1999/06/28 18:12:30 version 1.23.4.4, 2000/07/04 17:58:50
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.3 2000/06/13 17:57:17 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 72  ber_put_tag( Line 70  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 117  ber_calc_lenlen( ber_len_t len ) Line 119  ber_calc_lenlen( ber_len_t len )
 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 134  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 145  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;
Line 151  ber_put_len( BerElement *ber, ber_len_t Line 153  ber_put_len( BerElement *ber, ber_len_t
         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 179  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 213  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++;
   
Line 215  ber_put_int_or_enum( Line 225  ber_put_int_or_enum(
         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 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 );
Line 278  ber_put_ostring( Line 290  ber_put_ostring(
         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  
         if ( free_str ) {  
                 LBER_FREE( str );  
         }  
 #endif /* STR_TRANSLATION */  
   
         return( rc );          return( rc );
 }  }
   
Line 401  ber_put_boolean( Line 394  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 483  ber_start_set( BerElement *ber, ber_tag_ Line 476  ber_start_set( BerElement *ber, 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 496  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 538  ber_put_seqorset( BerElement *ber ) Line 544  ber_put_seqorset( BerElement *ber )
                                 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 );
   
                           if( rc != FOUR_BYTE_LEN - 1 ) {
                                 return( -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;
                   }
   
                   SAFEMEMCPY( (*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 567  ber_put_seqorset( BerElement *ber ) Line 600  ber_put_seqorset( BerElement *ber )
                         if (lenlen > 1) {                          if (lenlen > 1) {
                                 /* Write the length itself */                                  /* Write the length itself */
                                 SAFEMEMCPY( (*sos)->sos_first + 2,                                  SAFEMEMCPY( (*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 584  ber_put_seqorset( BerElement *ber ) Line 616  ber_put_seqorset( BerElement *ber )
                 } else {                  } else {
                         /* the length itself */                          /* the length itself */
                         SAFEMEMCPY( (*sos)->sos_first + taglen + 1,                          SAFEMEMCPY( (*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 617  ber_put_set( BerElement *ber ) Line 649  ber_put_set( BerElement *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 701  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 728  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 );

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


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