]> git.sur5r.net Git - openldap/commitdiff
don't malloc empty strings for matched, error
authorPierangelo Masarati <ando@openldap.org>
Sat, 12 Nov 2005 18:42:03 +0000 (18:42 +0000)
committerPierangelo Masarati <ando@openldap.org>
Sat, 12 Nov 2005 18:42:03 +0000 (18:42 +0000)
include/lber.h
libraries/liblber/decode.c
libraries/libldap/error.c
libraries/libldap/extended.c
libraries/libldap/options.c
libraries/libldap/result.c
libraries/libldap/sasl.c

index 93eebc3e486495895ddc3e0c5aca34baab5ca57d..fb29a8cb41f3f4c449e59a8a27d5d36929b8a61d 100644 (file)
@@ -622,6 +622,10 @@ LBER_F( int * ) ber_errno_addr LDAP_P((void));
 #define LBER_ERROR_PARAM       0x1
 #define LBER_ERROR_MEMORY      0x2
 
+#ifdef LDAP_DEVEL
+#define LDAP_NULL_IS_NULL
+#endif
+
 LDAP_END_DECL
 
 #endif /* _LBER_H */
index 04ba7cabc65b8dd87cc01ada0946cab6cd1576c3..f84ed861119daf72e49f05fce8e365316cd858ee 100644 (file)
@@ -479,6 +479,57 @@ ber_get_stringbv( BerElement *ber, struct berval *bv, int alloc )
        return tag;
 }
 
+#ifdef LDAP_NULL_IS_NULL
+ber_tag_t
+ber_get_stringbv_null( BerElement *ber, struct berval *bv, int alloc )
+{
+       ber_tag_t       tag;
+
+       assert( ber != NULL );
+       assert( bv != NULL );
+
+       assert( LBER_VALID( ber ) );
+
+       if ( (tag = ber_skip_tag( ber, &bv->bv_len )) == LBER_DEFAULT ) {
+               bv->bv_val = NULL;
+               return LBER_DEFAULT;
+       }
+
+       if ( (ber_len_t) ber_pvt_ber_remaining( ber ) < bv->bv_len ) {
+               return LBER_DEFAULT;
+       }
+
+       if ( bv->bv_len == 0 ) {
+               bv->bv_val = NULL;
+               ber->ber_tag = *(unsigned char *)ber->ber_ptr;
+               return tag;
+       }
+
+       if ( alloc ) {
+               bv->bv_val = (char *) ber_memalloc_x( bv->bv_len + 1,
+                       ber->ber_memctx );
+               if ( bv->bv_val == NULL ) {
+                       return LBER_DEFAULT;
+               }
+
+               if ( bv->bv_len > 0 && (ber_len_t) ber_read( ber, bv->bv_val,
+                       bv->bv_len ) != bv->bv_len )
+               {
+                       LBER_FREE( bv->bv_val );
+                       bv->bv_val = NULL;
+                       return LBER_DEFAULT;
+               }
+       } else {
+               bv->bv_val = ber->ber_ptr;
+               ber->ber_ptr += bv->bv_len;
+       }
+       ber->ber_tag = *(unsigned char *)ber->ber_ptr;
+       bv->bv_val[bv->bv_len] = '\0';
+
+       return tag;
+}
+#endif /* LDAP_NULL_IS_NULL */
+
 ber_tag_t
 ber_get_stringa( BerElement *ber, char **buf )
 {
@@ -493,6 +544,22 @@ ber_get_stringa( BerElement *ber, char **buf )
        return tag;
 }
 
+#ifdef LDAP_NULL_IS_NULL
+ber_tag_t
+ber_get_stringa_null( BerElement *ber, char **buf )
+{
+       BerValue        bv;
+       ber_tag_t       tag;
+
+       assert( buf != NULL );
+
+       tag = ber_get_stringbv_null( ber, &bv, 1 );
+       *buf = bv.bv_val;
+
+       return tag;
+}
+#endif /* LDAP_NULL_IS_NULL */
+
 ber_tag_t
 ber_get_stringal( BerElement *ber, struct berval **bv )
 {
@@ -692,11 +759,25 @@ ber_scanf ( BerElement *ber,
                        rc = ber_get_stringa( ber, ss );
                        break;
 
+#ifdef LDAP_NULL_IS_NULL
+               case 'A':       /* octet string - allocate storage as needed,
+                                * but return NULL if len == 0 */
+                       ss = va_arg( ap, char ** );
+                       rc = ber_get_stringa_null( ber, ss );
+                       break;
+#endif /* LDAP_NULL_IS_NULL */
+
                case 'b':       /* boolean */
                        i = va_arg( ap, ber_int_t * );
                        rc = ber_get_boolean( ber, i );
                        break;
 
+               case 'B':       /* bit string - allocate storage as needed */
+                       ss = va_arg( ap, char ** );
+                       l = va_arg( ap, ber_len_t * ); /* for length, in bits */
+                       rc = ber_get_bitstringa( ber, ss, l );
+                       break;
+
                case 'e':       /* enumerated */
                case 'i':       /* int */
                        i = va_arg( ap, ber_int_t * );
@@ -708,19 +789,30 @@ ber_scanf ( BerElement *ber,
                        rc = ber_peek_tag( ber, l );
                        break;
 
-               case 'n':       /* null */
-                       rc = ber_get_null( ber );
+               case 'm':       /* octet string in berval, in-place */
+                       bval = va_arg( ap, struct berval * );
+                       rc = ber_get_stringbv( ber, bval, 0 );
                        break;
 
-               case 's':       /* octet string - in a buffer */
-                       s = va_arg( ap, char * );
+               case 'M':       /* bvoffarray - must include address of
+                                * a record len, and record offset.
+                                * number of records will be returned thru
+                                * len ptr on finish. parsed in-place.
+                                */
+               {
+                       bgbvr cookie = { BvOff };
+                       cookie.ber = ber;
+                       cookie.res.ba = va_arg( ap, struct berval ** );
+                       cookie.alloc = 0;
                        l = va_arg( ap, ber_len_t * );
-                       rc = ber_get_stringb( ber, s, l );
+                       cookie.siz = *l;
+                       cookie.off = va_arg( ap, ber_len_t );
+                       rc = ber_get_stringbvl( &cookie, l );
                        break;
+               }
 
-               case 'm':       /* octet string in berval, in-place */
-                       bval = va_arg( ap, struct berval * );
-                       rc = ber_get_stringbv( ber, bval, 0 );
+               case 'n':       /* null */
+                       rc = ber_get_null( ber );
                        break;
 
                case 'o':       /* octet string in a supplied berval */
@@ -733,10 +825,10 @@ ber_scanf ( BerElement *ber,
                        rc = ber_get_stringal( ber, bvp );
                        break;
 
-               case 'B':       /* bit string - allocate storage as needed */
-                       ss = va_arg( ap, char ** );
-                       l = va_arg( ap, ber_len_t * ); /* for length, in bits */
-                       rc = ber_get_bitstringa( ber, ss, l );
+               case 's':       /* octet string - in a buffer */
+                       s = va_arg( ap, char * );
+                       l = va_arg( ap, ber_len_t * );
+                       rc = ber_get_stringb( ber, s, l );
                        break;
 
                case 't':       /* tag of next item */
@@ -779,23 +871,6 @@ ber_scanf ( BerElement *ber,
                        break;
                }
 
-               case 'M':       /* bvoffarray - must include address of
-                                * a record len, and record offset.
-                                * number of records will be returned thru
-                                * len ptr on finish. parsed in-place.
-                                */
-               {
-                       bgbvr cookie = { BvOff };
-                       cookie.ber = ber;
-                       cookie.res.ba = va_arg( ap, struct berval ** );
-                       cookie.alloc = 0;
-                       l = va_arg( ap, ber_len_t * );
-                       cookie.siz = *l;
-                       cookie.off = va_arg( ap, ber_len_t );
-                       rc = ber_get_stringbvl( &cookie, l );
-                       break;
-               }
-
                case 'x':       /* skip the next element - whatever it is */
                        if ( (rc = ber_skip_tag( ber, &len )) == LBER_DEFAULT )
                                break;
@@ -845,6 +920,9 @@ ber_scanf ( BerElement *ber,
                        } break;
 
                case 'a':       /* octet string - allocate storage as needed */
+#ifdef LDAP_NULL_IS_NULL
+               case 'A':
+#endif /* LDAP_NULL_IS_NULL */
                        ss = va_arg( ap, char ** );
                        if ( *ss ) {
                                LBER_FREE( *ss );
@@ -858,20 +936,10 @@ ber_scanf ( BerElement *ber,
                        (void) va_arg( ap, int * );
                        break;
 
-               case 's':       /* octet string - in a buffer */
-                       (void) va_arg( ap, char * );
-                       (void) va_arg( ap, ber_len_t * );
-                       break;
-
                case 'l':       /* length of next item */
                        (void) va_arg( ap, ber_len_t * );
                        break;
 
-               case 't':       /* tag of next item */
-               case 'T':       /* skip tag of next item */
-                       (void) va_arg( ap, ber_tag_t * );
-                       break;
-
                case 'o':       /* octet string in a supplied berval */
                        bval = va_arg( ap, struct berval * );
                        if ( bval->bv_val != NULL ) {
@@ -889,6 +957,16 @@ ber_scanf ( BerElement *ber,
                        }
                        break;
 
+               case 's':       /* octet string - in a buffer */
+                       (void) va_arg( ap, char * );
+                       (void) va_arg( ap, ber_len_t * );
+                       break;
+
+               case 't':       /* tag of next item */
+               case 'T':       /* skip tag of next item */
+                       (void) va_arg( ap, ber_tag_t * );
+                       break;
+
                case 'B':       /* bit string - allocate storage as needed */
                        ss = va_arg( ap, char ** );
                        if ( *ss ) {
@@ -898,12 +976,12 @@ ber_scanf ( BerElement *ber,
                        *(va_arg( ap, ber_len_t * )) = 0; /* for length, in bits */
                        break;
 
-               case 'v':       /* sequence of strings */
-               case 'V':       /* sequence of strings + lengths */
-               case 'W':       /* BerVarray */
                case 'm':       /* berval in-place */
                case 'M':       /* BVoff array in-place */
                case 'n':       /* null */
+               case 'v':       /* sequence of strings */
+               case 'V':       /* sequence of strings + lengths */
+               case 'W':       /* BerVarray */
                case 'x':       /* skip the next element - whatever it is */
                case '{':       /* begin sequence */
                case '[':       /* begin set */
index b1482eb93e0e0e23b27cc4345bba9fa215202c2e..bf782d767510a33b04c9e9f4365540e8dc6c810f 100644 (file)
@@ -311,12 +311,24 @@ ldap_parse_result(
        ber = ber_dup( lm->lm_ber );
 
        if ( ld->ld_version < LDAP_VERSION2 ) {
+#ifdef LDAP_NULL_IS_NULL
+               tag = ber_scanf( ber, "{iA}",
+                       &ld->ld_errno, &ld->ld_error );
+#else /* ! LDAP_NULL_IS_NULL */
                tag = ber_scanf( ber, "{ia}",
                        &ld->ld_errno, &ld->ld_error );
+#endif /* ! LDAP_NULL_IS_NULL */
+
        } else {
                ber_len_t len;
+
+#ifdef LDAP_NULL_IS_NULL
+               tag = ber_scanf( ber, "{iAA" /*}*/,
+                       &ld->ld_errno, &ld->ld_matched, &ld->ld_error );
+#else /* ! LDAP_NULL_IS_NULL */
                tag = ber_scanf( ber, "{iaa" /*}*/,
                        &ld->ld_errno, &ld->ld_matched, &ld->ld_error );
+#endif /* ! LDAP_NULL_IS_NULL */
 
                if( tag != LBER_ERROR ) {
                        /* peek for referrals */
@@ -377,10 +389,20 @@ ldap_parse_result(
        }
        if ( errcode == LDAP_SUCCESS ) {
                if( matcheddnp != NULL ) {
-                       *matcheddnp = LDAP_STRDUP( ld->ld_matched );
+#ifdef LDAP_NULL_IS_NULL
+                       if ( ld->ld_matched )
+#endif /* LDAP_NULL_IS_NULL */
+                       {
+                               *matcheddnp = LDAP_STRDUP( ld->ld_matched );
+                       }
                }
                if( errmsgp != NULL ) {
-                       *errmsgp = LDAP_STRDUP( ld->ld_error );
+#ifdef LDAP_NULL_IS_NULL
+                       if ( ld->ld_error )
+#endif /* LDAP_NULL_IS_NULL */
+                       {
+                               *errmsgp = LDAP_STRDUP( ld->ld_error );
+                       }
                }
 
                if( referralsp != NULL) {
index 99d29d8f62ec844feac77140b87362ae60f415c7..137dc69f040c9874053ada01f5d2d6dafd132028 100644 (file)
@@ -210,8 +210,13 @@ ldap_parse_extended_result (
                return ld->ld_errno;
        }
 
+#ifdef LDAP_NULL_IS_NULL
+       rc = ber_scanf( ber, "{eAA" /*}*/, &errcode,
+               &ld->ld_matched, &ld->ld_error );
+#else /* ! LDAP_NULL_IS_NULL */
        rc = ber_scanf( ber, "{eaa" /*}*/, &errcode,
                &ld->ld_matched, &ld->ld_error );
+#endif /* ! LDAP_NULL_IS_NULL */
 
        if( rc == LBER_ERROR ) {
                ld->ld_errno = LDAP_DECODING_ERROR;
@@ -243,6 +248,10 @@ ldap_parse_extended_result (
                        return ld->ld_errno;
                }
 
+#ifdef LDAP_NULL_IS_NULL
+               assert( resoid[ 0 ] != '\0' );
+#endif /* LDAP_NULL_IS_NULL */
+
                tag = ber_peek_tag( ber, &len );
        }
 
@@ -350,6 +359,10 @@ ldap_parse_intermediate (
                        return ld->ld_errno;
                }
 
+#ifdef LDAP_NULL_IS_NULL
+               assert( resoid[ 0 ] != '\0' );
+#endif /* LDAP_NULL_IS_NULL */
+
                tag = ber_peek_tag( ber, &len );
        }
 
index e8106c5e7d0d872c34b094ab7f0de64191ebc909..29760e332114f863295d1559ff9e09df35237828 100644 (file)
@@ -261,7 +261,7 @@ ldap_get_option(
                if( ld->ld_matched == NULL ) {
                        * (char **) outvalue = NULL;
                } else {
-                       * (char **) outvalue = LDAP_STRDUP(ld->ld_matched);
+                       * (char **) outvalue = LDAP_STRDUP( ld->ld_matched );
                }
 
                return LDAP_OPT_SUCCESS;
@@ -615,24 +615,30 @@ ldap_set_option(
 
                        if( ld->ld_error ) {
                                LDAP_FREE(ld->ld_error);
+                               ld->ld_error = NULL;
                        }
 
-                       ld->ld_error = LDAP_STRDUP(err);
+                       if ( err ) {
+                               ld->ld_error = LDAP_STRDUP(err);
+                       }
                } return LDAP_OPT_SUCCESS;
 
        case LDAP_OPT_MATCHED_DN: {
-                       const char *err = (const char *) invalue;
+                       const char *matched = (const char *) invalue;
 
-                       if(ld == NULL) {
+                       if (ld == NULL) {
                                /* need a struct ldap */
                                break;
                        }
 
                        if( ld->ld_matched ) {
                                LDAP_FREE(ld->ld_matched);
+                               ld->ld_matched = NULL;
                        }
 
-                       ld->ld_matched = LDAP_STRDUP(err);
+                       if ( matched ) {
+                               ld->ld_matched = LDAP_STRDUP( matched );
+                       }
                } return LDAP_OPT_SUCCESS;
 
        case LDAP_OPT_REFERRAL_URLS: {
index 172ab6311efeaf0f81b96e0c096f900c3d19cebd..f080c04ff9a5a581a5d0f6ea16e0cdf44bc72479 100644 (file)
@@ -565,18 +565,33 @@ nextresp2:
                        ber_len_t       len;
                        char            *lr_res_error = NULL;
 
+#ifdef LDAP_NULL_IS_NULL
+                       if ( ber_scanf( &tmpber, "{eAA",/*}*/ &lderr,
+                                   &lr->lr_res_matched, &lr_res_error )
+                                   != LBER_ERROR )
+#else /* ! LDAP_NULL_IS_NULL */
                        if ( ber_scanf( &tmpber, "{eaa",/*}*/ &lderr,
                                    &lr->lr_res_matched, &lr_res_error )
                                    != LBER_ERROR )
+#endif /* ! LDAP_NULL_IS_NULL */
                        {
                                if ( lr_res_error != NULL ) {
-                                       if ( lr->lr_res_error != NULL ) {
-                                               (void)ldap_append_referral( ld, &lr->lr_res_error, lr_res_error );
-                                               LDAP_FREE( (char *)lr_res_error );
+#ifndef LDAP_NULL_IS_NULL
+                                       if ( lr_res_error[ 0 ] == '\0' ) {
+                                               LDAP_FREE( lr_res_error );
+                                               lr_res_error = NULL;
+                                       } else
+#endif /* ! LDAP_NULL_IS_NULL */
+                                       {
+                                               if ( lr->lr_res_error != NULL ) {
+                                                       (void)ldap_append_referral( ld, &lr->lr_res_error, lr_res_error );
+                                                       LDAP_FREE( (char *)lr_res_error );
 
-                                       } else {
-                                               lr->lr_res_error = lr_res_error;
+                                               } else {
+                                                       lr->lr_res_error = lr_res_error;
+                                               }
                                        }
+                                       lr_res_error = NULL;
                                }
 
                                /* Check if V3 referral */
@@ -649,16 +664,29 @@ nextresp2:
                                 */
                                if ( tag == LDAP_RES_SEARCH_RESULT )
                                        refer_cnt = 0;
+#ifdef LDAP_NULL_IS_NULL
+                       } else if ( ber_scanf( &tmpber, "{eAA}", &lderr,
+                               &lr->lr_res_matched, &lr_res_error )
+                               != LBER_ERROR )
+#else /* ! LDAP_NULL_IS_NULL */
                        } else if ( ber_scanf( &tmpber, "{eaa}", &lderr,
                                &lr->lr_res_matched, &lr_res_error )
                                != LBER_ERROR )
+#endif /* ! LDAP_NULL_IS_NULL */
                        {
                                if ( lr_res_error != NULL ) {
-                                       if ( lr->lr_res_error != NULL ) {
-                                               (void)ldap_append_referral( ld, &lr->lr_res_error, lr_res_error );
-                                               LDAP_FREE( (char *)lr_res_error );
-                                       } else {
-                                               lr->lr_res_error = lr_res_error;
+#ifndef LDAP_NULL_IS_NULL
+                                       if ( lr_res_error[ 0 ] == '\0' ) {
+                                               LDAP_FREE( lr_res_error );
+                                       } else
+#endif /* ! LDAP_NULL_IS_NULL */
+                                       {
+                                               if ( lr->lr_res_error != NULL ) {
+                                                       (void)ldap_append_referral( ld, &lr->lr_res_error, lr_res_error );
+                                                       LDAP_FREE( (char *)lr_res_error );
+                                               } else {
+                                                       lr->lr_res_error = lr_res_error;
+                                               }
                                        }
                                        lr_res_error = NULL;
                                }
@@ -697,10 +725,19 @@ nextresp2:
                                } else {
                                        lr->lr_res_errno = LDAP_PARTIAL_RESULTS;
                                }
-Debug( LDAP_DEBUG_TRACE,
-    "new result:  res_errno: %d, res_error: <%s>, res_matched: <%s>\n",
-    lr->lr_res_errno, lr->lr_res_error ? lr->lr_res_error : "",
-    lr->lr_res_matched ? lr->lr_res_matched : "" );
+
+                               Debug( LDAP_DEBUG_TRACE, "new result:  "
+                                       "res_errno: %d, "
+                                       "res_error: <%s>, "
+                                       "res_matched: <%s>\n",
+                                       lr->lr_res_errno,
+                                       lr->lr_res_error ? lr->lr_res_error : "",
+                                       lr->lr_res_matched ? lr->lr_res_matched : "" );
+                       }
+
+                       /* in any case, don't leave any lr_res_error 'round */
+                       if ( lr_res_error ) {
+                               LDAP_FREE( lr_res_error );
                        }
                }
 
index 849a9fa3809c04d2001d3bc28f98f9a6efc6cd3d..e47302f33b3ef14cddf255e05a07bab87979975a 100644 (file)
@@ -294,8 +294,13 @@ ldap_parse_sasl_bind_result(
        }
 
        if ( ld->ld_version < LDAP_VERSION2 ) {
+#ifdef LDAP_NULL_IS_NULL
+               tag = ber_scanf( ber, "{iA}",
+                       &errcode, &ld->ld_error );
+#else /* ! LDAP_NULL_IS_NULL */
                tag = ber_scanf( ber, "{ia}",
                        &errcode, &ld->ld_error );
+#endif /* ! LDAP_NULL_IS_NULL */
 
                if( tag == LBER_ERROR ) {
                        ber_free( ber, 0 );
@@ -306,8 +311,13 @@ ldap_parse_sasl_bind_result(
        } else {
                ber_len_t len;
 
+#ifdef LDAP_NULL_IS_NULL
+               tag = ber_scanf( ber, "{eAA" /*}*/,
+                       &errcode, &ld->ld_matched, &ld->ld_error );
+#else /* ! LDAP_NULL_IS_NULL */
                tag = ber_scanf( ber, "{eaa" /*}*/,
                        &errcode, &ld->ld_matched, &ld->ld_error );
+#endif /* ! LDAP_NULL_IS_NULL */
 
                if( tag == LBER_ERROR ) {
                        ber_free( ber, 0 );