]> git.sur5r.net Git - openldap/blobdiff - libraries/liblber/decode.c
ITS#897 Internal connection that is closed on one end and about to
[openldap] / libraries / liblber / decode.c
index e2c204d7937e0abc55a836512e6ce0370b27ac41..c0e22c0de3f623c49c45787cb0d8c8cc5c441b00 100644 (file)
@@ -1,7 +1,7 @@
 /* decode.c - ber input decoding routines */
 /* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 /* Portions
@@ -26,9 +26,6 @@
 #include <ac/string.h>
 #include <ac/socket.h>
 
-#undef LDAP_F_PRE
-#define LDAP_F_PRE LDAP_F_EXPORT
-
 #include "lber-int.h"
 
 static ber_len_t ber_getnint LDAP_P((
@@ -42,36 +39,40 @@ ber_get_tag( BerElement *ber )
 {
        unsigned char   xbyte;
        ber_tag_t       tag;
-       char            *tagp;
        unsigned int    i;
 
        assert( ber != NULL );
        assert( BER_VALID( ber ) );
 
-       if ( ber_read( ber, (char *) &xbyte, 1 ) != 1 )
-               return( LBER_DEFAULT );
+       if ( ber_read( ber, (char *) &xbyte, 1 ) != 1 ) {
+               return LBER_DEFAULT;
+       }
 
-       if ( (xbyte & LBER_BIG_TAG_MASK) != LBER_BIG_TAG_MASK )
-               return( (ber_tag_t) xbyte );
+       tag = xbyte;
+
+       if ( (xbyte & LBER_BIG_TAG_MASK) != LBER_BIG_TAG_MASK ) {
+               return tag;
+       }
 
-       tagp = (char *) &tag;
-       tagp[0] = xbyte;
        for ( i = 1; i < sizeof(ber_tag_t); i++ ) {
-               if ( ber_read( ber, (char *) &xbyte, 1 ) != 1 )
-                       return( LBER_DEFAULT );
+               if ( ber_read( ber, (char *) &xbyte, 1 ) != 1 ) {
+                       return LBER_DEFAULT;
+               }
 
-               tagp[i] = xbyte;
+               tag <<= 8;
+               tag |= 0x00ffUL & (ber_tag_t) xbyte;
 
-               if ( ! (xbyte & LBER_MORE_TAG_MASK) )
+               if ( ! (xbyte & LBER_MORE_TAG_MASK) ) {
                        break;
+               }
        }
 
        /* tag too big! */
-       if ( i == sizeof(ber_tag_t) )
-               return( LBER_DEFAULT );
+       if ( i == sizeof(ber_tag_t) ) {
+               return LBER_DEFAULT;
+       }
 
-       /* want leading, not trailing 0's */
-       return( tag >> (sizeof(ber_tag_t) - i - 1) );
+       return tag;
 }
 
 ber_tag_t
@@ -79,9 +80,8 @@ ber_skip_tag( BerElement *ber, ber_len_t *len )
 {
        ber_tag_t       tag;
        unsigned char   lc;
-       ber_len_t       noctets;
-       int             diff;
-       ber_len_t       netlen;
+       ber_len_t       i, noctets;
+       unsigned char netlen[sizeof(ber_len_t)];
 
        assert( ber != NULL );
        assert( len != NULL );
@@ -97,12 +97,15 @@ ber_skip_tag( BerElement *ber, ber_len_t *len )
         *      2) primitive encodings used whenever possible
         */
 
+       *len = 0;
+
        /*
         * First, we read the tag.
         */
 
-       if ( (tag = ber_get_tag( ber )) == LBER_DEFAULT )
-               return( LBER_DEFAULT );
+       if ( (tag = ber_get_tag( ber )) == LBER_DEFAULT ) {
+               return LBER_DEFAULT;
+       }
 
        /*
         * Next, read the length.  The first byte contains the length of
@@ -111,48 +114,50 @@ ber_skip_tag( BerElement *ber, ber_len_t *len )
         * greater than what we can hold in a ber_len_t.
         */
 
-       *len = netlen = 0;
        if ( ber_read( ber, (char *) &lc, 1 ) != 1 )
-               return( LBER_DEFAULT );
+               return LBER_DEFAULT;
+
        if ( lc & 0x80U ) {
                noctets = (lc & 0x7fU);
-               if ( noctets > sizeof(ber_len_t) )
-                       return( LBER_DEFAULT );
-               diff = sizeof(ber_len_t) - noctets;
-               if ( (unsigned) ber_read( ber, (char *) &netlen + diff, noctets )
-                   != noctets )
-                       return( LBER_DEFAULT );
-               *len = LBER_LEN_NTOH( netlen );
+
+               if ( noctets > sizeof(ber_len_t) ) {
+                       return LBER_DEFAULT;
+               }
+
+               if( (unsigned) ber_read( ber, netlen, noctets ) != noctets ) {
+                       return LBER_DEFAULT;
+               }
+
+               for( i = 0; i < noctets; i++ ) {
+                       *len <<= 8;
+                       *len |= netlen[i];
+               }
+
        } else {
                *len = lc;
        }
 
-       return( tag );
+       return tag;
 }
 
 ber_tag_t
 ber_peek_tag(
-       LDAP_CONST BerElement *ber_in,
+       BerElement *ber,
        ber_len_t *len )
 {
-       ber_tag_t       tag;
-       BerElement *ber;
-
-       assert( ber_in != NULL );
-       assert( BER_VALID( ber_in ) );
-
-       ber = ber_dup( ber_in );
-
-       if( ber == NULL ) {
-               return LBER_ERROR;
-       }
+       /*
+        * This implementation assumes ber_skip_tag() only
+        * modifies ber_ptr field of the BerElement.
+        */
 
-       assert( BER_VALID( ber ) );
+       char *save;
+       ber_tag_t       tag;
 
+       save = ber->ber_ptr;
        tag = ber_skip_tag( ber, len );
+       ber->ber_ptr = save;
 
-       ber_free( ber, 0 );
-       return( tag );
+       return tag;
 }
 
 static ber_len_t
@@ -165,7 +170,6 @@ ber_getnint(
 
        assert( ber != NULL );
        assert( num != NULL );
-
        assert( BER_VALID( ber ) );
 
        /*
@@ -175,12 +179,13 @@ ber_getnint(
         * extend after we read it in.
         */
 
-       if ( len > sizeof(ber_int_t) )
-               return( -1 );
+       if ( len > sizeof(ber_int_t) ) {
+               return -1;
+       }
 
        /* read into the low-order bytes of our buffer */
        if ( (ber_len_t) ber_read( ber, (char *) buf, len ) != len ) {
-               return( -1 );
+               return -1;
        }
 
        if( len ) {
@@ -199,7 +204,7 @@ ber_getnint(
                *num = 0;
        }
 
-       return( len );
+       return len;
 }
 
 ber_tag_t
@@ -213,13 +218,23 @@ ber_get_int(
        assert( ber != NULL );
        assert( BER_VALID( ber ) );
 
-       if ( (tag = ber_skip_tag( ber, &len )) == LBER_DEFAULT )
-               return( LBER_DEFAULT );
+       if ( (tag = ber_skip_tag( ber, &len )) == LBER_DEFAULT ) {
+               return LBER_DEFAULT;
+       }
 
-       if ( ber_getnint( ber, num, len ) != len )
-               return( LBER_DEFAULT );
-       else
-               return( tag );
+       if ( ber_getnint( ber, num, len ) != len ) {
+               return LBER_DEFAULT;
+       }
+       
+       return tag;
+}
+
+ber_tag_t
+ber_get_enum(
+       BerElement *ber,
+       ber_int_t *num )
+{
+       return ber_get_int( ber, num );
 }
 
 ber_tag_t
@@ -231,44 +246,24 @@ ber_get_stringb(
        ber_len_t       datalen;
        ber_tag_t       tag;
 
-#ifdef STR_TRANSLATION
-       char            *transbuf;
-#endif /* STR_TRANSLATION */
-
        assert( ber != NULL );
        assert( BER_VALID( ber ) );
 
-       if ( (tag = ber_skip_tag( ber, &datalen )) == LBER_DEFAULT )
-               return( LBER_DEFAULT );
-       if ( datalen > (*len - 1) )
-               return( LBER_DEFAULT );
+       if ( (tag = ber_skip_tag( ber, &datalen )) == LBER_DEFAULT ) {
+               return LBER_DEFAULT;
+       }
+       if ( datalen > (*len - 1) ) {
+               return LBER_DEFAULT;
+       }
 
-       if ( (ber_len_t) ber_read( ber, buf, datalen ) != datalen )
-               return( LBER_DEFAULT );
+       if ( (ber_len_t) ber_read( ber, buf, datalen ) != datalen ) {
+               return LBER_DEFAULT;
+       }
 
        buf[datalen] = '\0';
 
-#ifdef STR_TRANSLATION
-       if ( datalen > 0 && ( ber->ber_options & LBER_TRANSLATE_STRINGS ) != 0
-           && ber->ber_decode_translate_proc ) {
-               transbuf = buf;
-               ++datalen;
-               if ( (*(ber->ber_decode_translate_proc))( &transbuf, &datalen,
-                   0 ) != 0 ) {
-                       return( LBER_DEFAULT );
-               }
-               if ( datalen > *len ) {
-                       LBER_FREE( transbuf );
-                       return( LBER_DEFAULT );
-               }
-               SAFEMEMCPY( buf, transbuf, datalen );
-               LBER_FREE( transbuf );
-               --datalen;
-       }
-#endif /* STR_TRANSLATION */
-
        *len = datalen;
-       return( tag );
+       return tag;
 }
 
 ber_tag_t
@@ -284,33 +279,21 @@ ber_get_stringa( BerElement *ber, char **buf )
 
        if ( (tag = ber_skip_tag( ber, &datalen )) == LBER_DEFAULT ) {
                *buf = NULL;
-               return( LBER_DEFAULT );
+               return LBER_DEFAULT;
        }
 
-       if ( (*buf = (char *) LBER_MALLOC( datalen + 1 )) == NULL )
-               return( LBER_DEFAULT );
+       if ( (*buf = (char *) LBER_MALLOC( datalen + 1 )) == NULL ) {
+               return LBER_DEFAULT;
+       }
 
        if ( (ber_len_t) ber_read( ber, *buf, datalen ) != datalen ) {
                LBER_FREE( *buf );
                *buf = NULL;
-               return( LBER_DEFAULT );
+               return LBER_DEFAULT;
        }
        (*buf)[datalen] = '\0';
 
-#ifdef STR_TRANSLATION
-       if ( datalen > 0 && ( ber->ber_options & LBER_TRANSLATE_STRINGS ) != 0
-           && ber->ber_decode_translate_proc ) {
-               ++datalen;
-               if ( (*(ber->ber_decode_translate_proc))( buf, &datalen, 1 )
-                   != 0 ) {
-                       LBER_FREE( *buf );
-                       *buf = NULL;
-                       return( LBER_DEFAULT );
-               }
-       }
-#endif /* STR_TRANSLATION */
-
-       return( tag );
+       return tag;
 }
 
 ber_tag_t
@@ -326,41 +309,37 @@ ber_get_stringal( BerElement *ber, struct berval **bv )
 
        if ( (tag = ber_skip_tag( ber, &len )) == LBER_DEFAULT ) {
                *bv = NULL;
-               return( LBER_DEFAULT );
+               return LBER_DEFAULT;
+       }
+
+       *bv = (struct berval *) LBER_MALLOC( sizeof(struct berval) );
+       if ( *bv == NULL ) {
+               return LBER_DEFAULT;
        }
 
-       if ( (*bv = (struct berval *) LBER_MALLOC( sizeof(struct berval) )) == NULL )
-               return( LBER_DEFAULT );
+       if( len == 0 ) {
+               (*bv)->bv_val = NULL;
+               (*bv)->bv_len = 0;
+               return tag;
+       }
 
-       if ( ((*bv)->bv_val = (char *) LBER_MALLOC( len + 1 )) == NULL ) {
+       (*bv)->bv_val = (char *) LBER_MALLOC( len + 1 );
+       if ( (*bv)->bv_val == NULL ) {
                LBER_FREE( *bv );
                *bv = NULL;
-               return( LBER_DEFAULT );
+               return LBER_DEFAULT;
        }
 
        if ( (ber_len_t) ber_read( ber, (*bv)->bv_val, len ) != len ) {
                ber_bvfree( *bv );
                *bv = NULL;
-               return( LBER_DEFAULT );
+               return LBER_DEFAULT;
        }
+
        ((*bv)->bv_val)[len] = '\0';
        (*bv)->bv_len = len;
 
-#ifdef STR_TRANSLATION
-       if ( len > 0 && ( ber->ber_options & LBER_TRANSLATE_STRINGS ) != 0
-           && ber->ber_decode_translate_proc ) {
-               ++len;
-               if ( (*(ber->ber_decode_translate_proc))( &((*bv)->bv_val),
-                   &len, 1 ) != 0 ) {
-                       ber_bvfree( *bv );
-                       *bv = NULL;
-                       return( LBER_DEFAULT );
-               }
-               (*bv)->bv_len = len - 1;
-       }
-#endif /* STR_TRANSLATION */
-
-       return( tag );
+       return tag;
 }
 
 ber_tag_t
@@ -381,27 +360,28 @@ ber_get_bitstringa(
 
        if ( (tag = ber_skip_tag( ber, &datalen )) == LBER_DEFAULT ) {
                *buf = NULL;
-               return( LBER_DEFAULT );
+               return LBER_DEFAULT;
        }
        --datalen;
 
-       if ( (*buf = (char *) LBER_MALLOC( datalen )) == NULL )
-               return( LBER_DEFAULT );
+       if ( (*buf = (char *) LBER_MALLOC( datalen )) == NULL ) {
+               return LBER_DEFAULT;
+       }
 
        if ( ber_read( ber, (char *)&unusedbits, 1 ) != 1 ) {
                LBER_FREE( buf );
                *buf = NULL;
-               return( LBER_DEFAULT );
+               return LBER_DEFAULT;
        }
 
        if ( (ber_len_t) ber_read( ber, *buf, datalen ) != datalen ) {
                LBER_FREE( buf );
                *buf = NULL;
-               return( LBER_DEFAULT );
+               return LBER_DEFAULT;
        }
 
        *blen = datalen * 8 - unusedbits;
-       return( tag );
+       return tag;
 }
 
 ber_tag_t
@@ -413,11 +393,13 @@ ber_get_null( BerElement *ber )
        assert( ber != NULL );
        assert( BER_VALID( ber ) );
 
-       if ( (tag = ber_skip_tag( ber, &len )) == LBER_DEFAULT )
-               return( LBER_DEFAULT );
+       if ( (tag = ber_skip_tag( ber, &len )) == LBER_DEFAULT ) {
+               return LBER_DEFAULT;
+       }
 
-       if ( len != 0 )
-               return( LBER_DEFAULT );
+       if ( len != 0 ) {
+               return LBER_DEFAULT;
+       }
 
        return( tag );
 }
@@ -438,7 +420,7 @@ ber_get_boolean(
        rc = ber_get_int( ber, &longbool );
        *boolval = longbool;
 
-       return( rc );
+       return rc;
 }
 
 ber_tag_t
@@ -454,23 +436,23 @@ ber_first_element(
        /* skip the sequence header, use the len to mark where to stop */
        if ( ber_skip_tag( ber, len ) == LBER_DEFAULT ) {
                *last = NULL;
-               return( LBER_DEFAULT );
+               return LBER_DEFAULT;
        }
 
        *last = ber->ber_ptr + *len;
 
        if ( *last == ber->ber_ptr ) {
-               return( LBER_DEFAULT );
+               return LBER_DEFAULT;
        }
 
-       return( ber_peek_tag( ber, len ) );
+       return ber_peek_tag( ber, len );
 }
 
 ber_tag_t
 ber_next_element(
        BerElement *ber,
        ber_len_t *len,
-       char *last )
+       LDAP_CONST char *last )
 {
        assert( ber != NULL );
        assert( len != NULL );
@@ -479,10 +461,10 @@ ber_next_element(
        assert( BER_VALID( ber ) );
 
        if ( ber->ber_ptr == last ) {
-               return( LBER_DEFAULT );
+               return LBER_DEFAULT;
        }
 
-       return( ber_peek_tag( ber, len ) );
+       return ber_peek_tag( ber, len );
 }
 
 /* VARARGS */
@@ -512,9 +494,14 @@ ber_scanf ( BerElement *ber,
 
        fmt_reset = fmt;
 
+#ifdef NEW_LOGGING
+       LDAP_LOG(( "LIBLBER", LDAP_LEVEL_ENTRY, "ber_scanf fmt (%s) ber:\n", fmt ));
+        BER_DUMP(( "LIBLBER", LDAP_LEVEL_DETAIL2, ber, 1 ));
+#else
        ber_log_printf( LDAP_DEBUG_TRACE, ber->ber_debug,
                "ber_scanf fmt (%s) ber:\n", fmt );
        ber_log_dump( LDAP_DEBUG_BER, ber->ber_debug, ber, 1 );
+#endif
 
        for ( rc = 0; *fmt && rc != LBER_DEFAULT; fmt++ ) {
                /* When this is modified, remember to update
@@ -762,19 +749,5 @@ ber_scanf ( BerElement *ber,
            va_end( ap );
        }
 
-       return( rc );
-}
-
-
-#ifdef STR_TRANSLATION
-void
-ber_set_string_translators( BerElement *ber, BERTranslateProc encode_proc,
-       BERTranslateProc decode_proc )
-{
-       assert( ber != NULL );
-       assert( BER_VALID( ber ) );
-
-    ber->ber_encode_translate_proc = encode_proc;
-    ber->ber_decode_translate_proc = decode_proc;
+       return rc;
 }
-#endif /* STR_TRANSLATION */