More tweaks to ldif_parse_line2 for str2entry

This commit is contained in:
Howard Chu 2005-01-19 12:07:06 +00:00
parent 6c34a7c3b2
commit 8db476e664
3 changed files with 60 additions and 58 deletions

View file

@ -61,11 +61,10 @@ ldif_parse_line LDAP_P((
LDAP_LDIF_F( int ) LDAP_LDIF_F( int )
ldif_parse_line2 LDAP_P(( ldif_parse_line2 LDAP_P((
LDAP_CONST char *line, char *line,
char **name, struct berval *type,
char **value, struct berval *value,
ber_len_t *vlen, int *freeval ));
int *alloc ));
LDAP_LDIF_F( int ) LDAP_LDIF_F( int )
ldif_fetch_url LDAP_P(( ldif_fetch_url LDAP_P((

View file

@ -86,7 +86,9 @@ static const unsigned char b642nib[0x80] = {
* *
* ldif_parse_line2 - operates in-place on input buffer, returning type * ldif_parse_line2 - operates in-place on input buffer, returning type
* in-place. Will return value in-place if possible, (must malloc for * in-place. Will return value in-place if possible, (must malloc for
* fetched URLs). * fetched URLs). If freeval is NULL, all return data will be malloc'd
* and the input line will be unmodified. Otherwise freeval is set to
* True if the value was malloc'd.
*/ */
int int
@ -97,35 +99,37 @@ ldif_parse_line(
ber_len_t *vlenp ber_len_t *vlenp
) )
{ {
return ldif_parse_line2( line, typep, valuep, vlenp, NULL ); struct berval type, value;
int rc = ldif_parse_line2( (char *)line, &type, &value, NULL );
*typep = type.bv_val;
*valuep = value.bv_val;
*vlenp = value.bv_len;
return rc;
} }
int int
ldif_parse_line2( ldif_parse_line2(
LDAP_CONST char *line, char *line,
char **typep, struct berval *type,
char **valuep, struct berval *value,
ber_len_t *vlenp, int *freeval
int *alloc
) )
{ {
char *s, *p, *d; char *s, *p, *d;
char nib; char nib;
int b64, url; int b64, url;
char *type, *value;
ber_len_t vlen;
*typep = NULL; BER_BVZERO( type );
*valuep = NULL; BER_BVZERO( value );
*vlenp = 0;
/* skip any leading space */ /* skip any leading space */
while ( isspace( (unsigned char) *line ) ) { while ( isspace( (unsigned char) *line ) ) {
line++; line++;
} }
if ( alloc ) { if ( freeval ) {
*alloc = 0; *freeval = 0;
} else { } else {
line = ber_strdup( line ); line = ber_strdup( line );
@ -136,23 +140,24 @@ ldif_parse_line2(
} }
} }
type = line; type->bv_val = line;
s = strchr( type, ':' ); s = strchr( type->bv_val, ':' );
if ( s == NULL ) { if ( s == NULL ) {
ber_pvt_log_printf( LDAP_DEBUG_PARSE, ldif_debug, ber_pvt_log_printf( LDAP_DEBUG_PARSE, ldif_debug,
_("ldif_parse_line: missing ':' after %s\n"), _("ldif_parse_line: missing ':' after %s\n"),
type ); type );
if ( !alloc ) ber_memfree( line ); if ( !freeval ) ber_memfree( line );
return( -1 ); return( -1 );
} }
/* trim any space between type and : */ /* trim any space between type and : */
for ( p = &s[-1]; p > type && isspace( * (unsigned char *) p ); p-- ) { for ( p = &s[-1]; p > type->bv_val && isspace( * (unsigned char *) p ); p-- ) {
*p = '\0'; *p = '\0';
} }
*s++ = '\0'; *s++ = '\0';
type->bv_len = s - type->bv_val - 1;
url = 0; url = 0;
b64 = 0; b64 = 0;
@ -186,13 +191,13 @@ ldif_parse_line2(
/* no value is present, error out */ /* no value is present, error out */
ber_pvt_log_printf( LDAP_DEBUG_PARSE, ldif_debug, ber_pvt_log_printf( LDAP_DEBUG_PARSE, ldif_debug,
_("ldif_parse_line: %s missing base64 value\n"), type ); _("ldif_parse_line: %s missing base64 value\n"), type );
if ( !alloc ) ber_memfree( line ); if ( !freeval ) ber_memfree( line );
return( -1 ); return( -1 );
} }
byte = value = s; byte = value->bv_val = s;
for ( p = s, vlen = 0; p < d; p += 4, vlen += 3 ) { for ( p = s, value->bv_len = 0; p < d; p += 4, value->bv_len += 3 ) {
int i; int i;
for ( i = 0; i < 4; i++ ) { for ( i = 0; i < 4; i++ ) {
if ( p[i] != '=' && (p[i] & 0x80 || if ( p[i] != '=' && (p[i] & 0x80 ||
@ -201,7 +206,7 @@ ldif_parse_line2(
_("ldif_parse_line: %s: invalid base64 encoding" _("ldif_parse_line: %s: invalid base64 encoding"
" char (%c) 0x%x\n"), " char (%c) 0x%x\n"),
type, p[i], p[i] ); type, p[i], p[i] );
if ( !alloc ) ber_memfree( line ); if ( !freeval ) ber_memfree( line );
return( -1 ); return( -1 );
} }
} }
@ -215,7 +220,7 @@ ldif_parse_line2(
byte[1] = (nib & RIGHT4) << 4; byte[1] = (nib & RIGHT4) << 4;
/* third digit */ /* third digit */
if ( p[2] == '=' ) { if ( p[2] == '=' ) {
vlen += 1; value->bv_len += 1;
break; break;
} }
nib = b642nib[ p[2] & 0x7f ]; nib = b642nib[ p[2] & 0x7f ];
@ -223,7 +228,7 @@ ldif_parse_line2(
byte[2] = (nib & RIGHT2) << 6; byte[2] = (nib & RIGHT2) << 6;
/* fourth digit */ /* fourth digit */
if ( p[3] == '=' ) { if ( p[3] == '=' ) {
vlen += 2; value->bv_len += 2;
break; break;
} }
nib = b642nib[ p[3] & 0x7f ]; nib = b642nib[ p[3] & 0x7f ];
@ -231,63 +236,59 @@ ldif_parse_line2(
byte += 3; byte += 3;
} }
s[ vlen ] = '\0'; s[ value->bv_len ] = '\0';
} else if ( url ) { } else if ( url ) {
if ( *s == '\0' ) { if ( *s == '\0' ) {
/* no value is present, error out */ /* no value is present, error out */
ber_pvt_log_printf( LDAP_DEBUG_PARSE, ldif_debug, ber_pvt_log_printf( LDAP_DEBUG_PARSE, ldif_debug,
_("ldif_parse_line: %s missing URL value\n"), type ); _("ldif_parse_line: %s missing URL value\n"), type );
if ( !alloc ) ber_memfree( line ); if ( !freeval ) ber_memfree( line );
return( -1 ); return( -1 );
} }
if( ldif_fetch_url( s, &value, &vlen ) ) { if( ldif_fetch_url( s, &value->bv_val, &value->bv_len ) ) {
ber_pvt_log_printf( LDAP_DEBUG_ANY, ldif_debug, ber_pvt_log_printf( LDAP_DEBUG_ANY, ldif_debug,
_("ldif_parse_line: %s: URL \"%s\" fetch failed\n"), _("ldif_parse_line: %s: URL \"%s\" fetch failed\n"),
type, s ); type, s );
if ( !alloc ) ber_memfree( line ); if ( !freeval ) ber_memfree( line );
return( -1 ); return( -1 );
} }
if ( alloc ) *alloc = 1; if ( freeval ) *freeval = 1;
} else { } else {
value = s; value->bv_val = s;
vlen = (int) (d - s); value->bv_len = (int) (d - s);
} }
if ( !alloc ) { if ( !freeval ) {
type = ber_strdup( type ); struct berval bv = *type;
if( type == NULL ) { ber_dupbv( type, &bv );
if( BER_BVISNULL( type )) {
ber_pvt_log_printf( LDAP_DEBUG_ANY, ldif_debug, ber_pvt_log_printf( LDAP_DEBUG_ANY, ldif_debug,
_("ldif_parse_line: type malloc failed\n")); _("ldif_parse_line: type malloc failed\n"));
if( url ) ber_memfree( value ); if( url ) ber_memfree( value->bv_val );
ber_memfree( line ); ber_memfree( line );
return( -1 ); return( -1 );
} }
if( !url ) { if( !url ) {
p = ber_memalloc( vlen + 1 ); bv = *value;
if( p == NULL ) { ber_dupbv( value, &bv );
if( BER_BVISNULL( value )) {
ber_pvt_log_printf( LDAP_DEBUG_ANY, ldif_debug, ber_pvt_log_printf( LDAP_DEBUG_ANY, ldif_debug,
_("ldif_parse_line: value malloc failed\n")); _("ldif_parse_line: value malloc failed\n"));
ber_memfree( type ); ber_memfree( type->bv_val );
ber_memfree( line ); ber_memfree( line );
return( -1 ); return( -1 );
} }
AC_MEMCPY( p, value, vlen );
p[vlen] = '\0';
value = p;
} }
ber_memfree( line ); ber_memfree( line );
} }
*typep = type;
*valuep = value;
*vlenp = vlen;
return( 0 ); return( 0 );
} }

View file

@ -47,6 +47,8 @@ const Entry slap_entry_root = {
NOID, { 0, "" }, { 0, "" }, NULL, 0, { 0, "" }, NULL NOID, { 0, "" }, { 0, "" }, NULL, 0, { 0, "" }, NULL
}; };
static const struct berval dn_bv = BER_BVC("dn");
int entry_destroy(void) int entry_destroy(void)
{ {
if ( ebuf ) free( ebuf ); if ( ebuf ) free( ebuf );
@ -62,7 +64,7 @@ str2entry( char *s )
{ {
int rc; int rc;
Entry *e; Entry *e;
char *type; struct berval type;
struct berval vals[2]; struct berval vals[2];
struct berval nvals[2], *nvalsp; struct berval nvals[2], *nvalsp;
AttributeDescription *ad, *ad_prev; AttributeDescription *ad, *ad_prev;
@ -115,14 +117,14 @@ str2entry( char *s )
break; break;
} }
if ( ldif_parse_line2( s, &type, &vals[0].bv_val, &vals[0].bv_len, if ( ldif_parse_line2( s, &type, vals, &freeval ) != 0 ) {
&freeval ) != 0 ) {
Debug( LDAP_DEBUG_TRACE, Debug( LDAP_DEBUG_TRACE,
"<= str2entry NULL (parse_line)\n", 0, 0, 0 ); "<= str2entry NULL (parse_line)\n", 0, 0, 0 );
continue; continue;
} }
if ( strcasecmp( type, "dn" ) == 0 ) { if ( type.bv_len == dn_bv.bv_len &&
strcasecmp( type.bv_val, dn_bv.bv_val ) == 0 ) {
if ( e->e_dn != NULL ) { if ( e->e_dn != NULL ) {
Debug( LDAP_DEBUG_ANY, "str2entry: " Debug( LDAP_DEBUG_ANY, "str2entry: "
@ -147,23 +149,23 @@ str2entry( char *s )
ad_prev = ad; ad_prev = ad;
ad = NULL; ad = NULL;
rc = slap_str2ad( type, &ad, &text ); rc = slap_bv2ad( &type, &ad, &text );
if( rc != LDAP_SUCCESS ) { if( rc != LDAP_SUCCESS ) {
Debug( slapMode & SLAP_TOOL_MODE Debug( slapMode & SLAP_TOOL_MODE
? LDAP_DEBUG_ANY : LDAP_DEBUG_TRACE, ? LDAP_DEBUG_ANY : LDAP_DEBUG_TRACE,
"<= str2entry: str2ad(%s): %s\n", type, text, 0 ); "<= str2entry: str2ad(%s): %s\n", type.bv_val, text, 0 );
if( slapMode & SLAP_TOOL_MODE ) { if( slapMode & SLAP_TOOL_MODE ) {
entry_free( e ); entry_free( e );
if ( freeval ) free( vals[0].bv_val ); if ( freeval ) free( vals[0].bv_val );
return NULL; return NULL;
} }
rc = slap_str2undef_ad( type, &ad, &text ); rc = slap_bv2undef_ad( &type, &ad, &text );
if( rc != LDAP_SUCCESS ) { if( rc != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_ANY, Debug( LDAP_DEBUG_ANY,
"<= str2entry: str2undef_ad(%s): %s\n", "<= str2entry: str2undef_ad(%s): %s\n",
type, text, 0 ); type.bv_val, text, 0 );
entry_free( e ); entry_free( e );
if ( freeval ) free( vals[0].bv_val ); if ( freeval ) free( vals[0].bv_val );
return NULL; return NULL;