From bd8a9989f4f6c214a30982276570b3cce38cf8d9 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Wed, 19 Jan 2005 05:05:53 +0000 Subject: [PATCH] Added ldif_parse_line2 to parse in-place --- include/ldif.h | 8 ++++ libraries/liblutil/ldif.c | 90 +++++++++++++++++++++++++-------------- servers/slapd/entry.c | 34 ++++++--------- 3 files changed, 79 insertions(+), 53 deletions(-) diff --git a/include/ldif.h b/include/ldif.h index 4743f1de96..b484da6ae1 100644 --- a/include/ldif.h +++ b/include/ldif.h @@ -59,6 +59,14 @@ ldif_parse_line LDAP_P(( char **value, ber_len_t *vlen )); +LDAP_LDIF_F( int ) +ldif_parse_line2 LDAP_P(( + LDAP_CONST char *line, + char **name, + char **value, + ber_len_t *vlen, + int *alloc )); + LDAP_LDIF_F( int ) ldif_fetch_url LDAP_P(( LDAP_CONST char *line, diff --git a/libraries/liblutil/ldif.c b/libraries/liblutil/ldif.c index 05220b0947..9d67b3cf75 100644 --- a/libraries/liblutil/ldif.c +++ b/libraries/liblutil/ldif.c @@ -81,7 +81,12 @@ static const unsigned char b642nib[0x80] = { * ldif_parse_line - takes a line of the form "type:[:] value" and splits it * into components "type" and "value". if a double colon separates type from * value, then value is encoded in base 64, and parse_line un-decodes it - * (in place) before returning. + * (in place) before returning. The type and value are stored in malloc'd + * memory which must be freed by the caller. + * + * ldif_parse_line2 - operates in-place on input buffer, returning type + * in-place. Will return value in-place if possible, (must malloc for + * fetched URLs). */ int @@ -91,11 +96,23 @@ ldif_parse_line( char **valuep, ber_len_t *vlenp ) +{ + return ldif_parse_line2( line, typep, valuep, vlenp, NULL ); +} + +int +ldif_parse_line2( + LDAP_CONST char *line, + char **typep, + char **valuep, + ber_len_t *vlenp, + int *alloc +) { char *s, *p, *d; char nib; int b64, url; - char *freeme, *type, *value; + char *type, *value; ber_len_t vlen; *typep = NULL; @@ -107,15 +124,19 @@ ldif_parse_line( line++; } - freeme = ber_strdup( line ); + if ( alloc ) { + *alloc = 0; + } else { + line = ber_strdup( line ); - if( freeme == NULL ) { - ber_pvt_log_printf( LDAP_DEBUG_ANY, ldif_debug, - _("ldif_parse_line: line malloc failed\n")); - return( -1 ); + if( line == NULL ) { + ber_pvt_log_printf( LDAP_DEBUG_ANY, ldif_debug, + _("ldif_parse_line: line malloc failed\n")); + return( -1 ); + } } - type = freeme; + type = line; s = strchr( type, ':' ); @@ -123,7 +144,7 @@ ldif_parse_line( ber_pvt_log_printf( LDAP_DEBUG_PARSE, ldif_debug, _("ldif_parse_line: missing ':' after %s\n"), type ); - ber_memfree( freeme ); + if ( !alloc ) ber_memfree( line ); return( -1 ); } @@ -165,7 +186,7 @@ ldif_parse_line( /* no value is present, error out */ ber_pvt_log_printf( LDAP_DEBUG_PARSE, ldif_debug, _("ldif_parse_line: %s missing base64 value\n"), type ); - ber_memfree( freeme ); + if ( !alloc ) ber_memfree( line ); return( -1 ); } @@ -180,7 +201,7 @@ ldif_parse_line( _("ldif_parse_line: %s: invalid base64 encoding" " char (%c) 0x%x\n"), type, p[i], p[i] ); - ber_memfree( freeme ); + if ( !alloc ) ber_memfree( line ); return( -1 ); } } @@ -217,7 +238,7 @@ ldif_parse_line( /* no value is present, error out */ ber_pvt_log_printf( LDAP_DEBUG_PARSE, ldif_debug, _("ldif_parse_line: %s missing URL value\n"), type ); - ber_memfree( freeme ); + if ( !alloc ) ber_memfree( line ); return( -1 ); } @@ -225,40 +246,43 @@ ldif_parse_line( ber_pvt_log_printf( LDAP_DEBUG_ANY, ldif_debug, _("ldif_parse_line: %s: URL \"%s\" fetch failed\n"), type, s ); - ber_memfree( freeme ); + if ( !alloc ) ber_memfree( line ); return( -1 ); } + if ( alloc ) *alloc = 1; } else { value = s; vlen = (int) (d - s); } - type = ber_strdup( type ); - - if( type == NULL ) { - ber_pvt_log_printf( LDAP_DEBUG_ANY, ldif_debug, - _("ldif_parse_line: type malloc failed\n")); - if( url ) ber_memfree( value ); - ber_memfree( freeme ); - return( -1 ); - } + if ( !alloc ) { + type = ber_strdup( type ); - if( !url ) { - p = ber_memalloc( vlen + 1 ); - if( p == NULL ) { + if( type == NULL ) { ber_pvt_log_printf( LDAP_DEBUG_ANY, ldif_debug, - _("ldif_parse_line: value malloc failed\n")); - ber_memfree( type ); - ber_memfree( freeme ); + _("ldif_parse_line: type malloc failed\n")); + if( url ) ber_memfree( value ); + ber_memfree( line ); return( -1 ); } - AC_MEMCPY( p, value, vlen ); - p[vlen] = '\0'; - value = p; - } - ber_memfree( freeme ); + if( !url ) { + p = ber_memalloc( vlen + 1 ); + if( p == NULL ) { + ber_pvt_log_printf( LDAP_DEBUG_ANY, ldif_debug, + _("ldif_parse_line: value malloc failed\n")); + ber_memfree( type ); + ber_memfree( line ); + return( -1 ); + } + AC_MEMCPY( p, value, vlen ); + p[vlen] = '\0'; + value = p; + } + + ber_memfree( line ); + } *typep = type; *valuep = value; diff --git a/servers/slapd/entry.c b/servers/slapd/entry.c index 40dcdb638b..c1a1116360 100644 --- a/servers/slapd/entry.c +++ b/servers/slapd/entry.c @@ -69,6 +69,7 @@ str2entry( char *s ) const char *text; char *next; int attr_cnt; + int freeval; /* * LDIF is used as the string format. @@ -114,34 +115,33 @@ str2entry( char *s ) break; } - if ( ldif_parse_line( s, &type, &vals[0].bv_val, &vals[0].bv_len ) != 0 ) { + if ( ldif_parse_line2( s, &type, &vals[0].bv_val, &vals[0].bv_len, + &freeval ) != 0 ) { Debug( LDAP_DEBUG_TRACE, "<= str2entry NULL (parse_line)\n", 0, 0, 0 ); continue; } if ( strcasecmp( type, "dn" ) == 0 ) { - free( type ); if ( e->e_dn != NULL ) { Debug( LDAP_DEBUG_ANY, "str2entry: " "entry %ld has multiple DNs \"%s\" and \"%s\"\n", (long) e->e_id, e->e_dn, vals[0].bv_val ); - free( vals[0].bv_val ); + if ( freeval ) free( vals[0].bv_val ); entry_free( e ); return NULL; } rc = dnPrettyNormal( NULL, &vals[0], &e->e_name, &e->e_nname, NULL ); + if ( freeval ) free( vals[0].bv_val ); if( rc != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_ANY, "str2entry: " "entry %ld has invalid DN \"%s\"\n", (long) e->e_id, vals[0].bv_val, 0 ); entry_free( e ); - free( vals[0].bv_val ); return NULL; } - free( vals[0].bv_val ); continue; } @@ -155,8 +155,7 @@ str2entry( char *s ) "<= str2entry: str2ad(%s): %s\n", type, text, 0 ); if( slapMode & SLAP_TOOL_MODE ) { entry_free( e ); - free( vals[0].bv_val ); - free( type ); + if ( freeval ) free( vals[0].bv_val ); return NULL; } @@ -166,8 +165,7 @@ str2entry( char *s ) "<= str2entry: str2undef_ad(%s): %s\n", type, text, 0 ); entry_free( e ); - free( vals[0].bv_val ); - free( type ); + if ( freeval ) free( vals[0].bv_val ); return NULL; } } @@ -200,8 +198,7 @@ str2entry( char *s ) ad->ad_cname.bv_val, attr_cnt, ad->ad_type->sat_syntax->ssyn_oid ); entry_free( e ); - free( vals[0].bv_val ); - free( type ); + if ( freeval ) free( vals[0].bv_val ); return NULL; } @@ -212,14 +209,14 @@ str2entry( char *s ) ad->ad_cname.bv_val, attr_cnt, ad->ad_type->sat_syntax->ssyn_oid ); entry_free( e ); - free( vals[0].bv_val ); - free( type ); + if ( freeval ) free( vals[0].bv_val ); return NULL; } if( pretty ) { - free( vals[0].bv_val ); + if ( freeval ) free( vals[0].bv_val ); vals[0] = pval; + freeval = 1; } } @@ -240,8 +237,7 @@ str2entry( char *s ) "<= str2entry NULL (smr_normalize %d)\n", rc, 0, 0 ); entry_free( e ); - free( vals[0].bv_val ); - free( type ); + if ( freeval ) free( vals[0].bv_val ); return NULL; } @@ -256,13 +252,11 @@ str2entry( char *s ) Debug( LDAP_DEBUG_ANY, "<= str2entry NULL (attr_merge)\n", 0, 0, 0 ); entry_free( e ); - free( vals[0].bv_val ); - free( type ); + if ( freeval ) free( vals[0].bv_val ); return( NULL ); } - free( type ); - free( vals[0].bv_val ); + if ( freeval ) free( vals[0].bv_val ); free( nvals[0].bv_val ); attr_cnt++; -- 2.39.2