mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-01-06 10:46:21 +08:00
add more versatile private API for filter escaping
This commit is contained in:
parent
4297ec242a
commit
6ab23ef926
@ -212,6 +212,13 @@ ldap_pvt_find_wildcard LDAP_P(( const char *s ));
|
||||
LDAP_F( ber_slen_t )
|
||||
ldap_pvt_filter_value_unescape LDAP_P(( char *filter ));
|
||||
|
||||
LDAP_F( ber_len_t )
|
||||
ldap_bv2escaped_filter_value_len LDAP_P(( struct berval *in ));
|
||||
|
||||
LDAP_F( int )
|
||||
ldap_bv2escaped_filter_value_x LDAP_P(( struct berval *in, struct berval *out,
|
||||
int inplace, void *ctx ));
|
||||
|
||||
/* string.c */
|
||||
LDAP_F( char * )
|
||||
ldap_pvt_str2upper LDAP_P(( char *str ));
|
||||
|
@ -365,53 +365,106 @@ ldap_search_s(
|
||||
return( ldap_result2error( ld, *res, 0 ) );
|
||||
}
|
||||
|
||||
static char escape[128] = {
|
||||
1, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
1, 1, 1, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 1, 0, 0, 0,
|
||||
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
#define NEEDFLTESCAPE(c) ((c) & 0x80 || escape[ (unsigned)(c) ])
|
||||
|
||||
/*
|
||||
* compute the length of the escaped value;
|
||||
* returns ((ber_len_t)(-1)) if no escaping is required.
|
||||
*/
|
||||
ber_len_t
|
||||
ldap_bv2escaped_filter_value_len( struct berval *in )
|
||||
{
|
||||
ber_len_t i, l;
|
||||
|
||||
assert( in != NULL );
|
||||
|
||||
if ( in->bv_len == 0 ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* assume we'll escape everything */
|
||||
for( l = 0, i = 0; i < in->bv_len; l++, i++ ) {
|
||||
char c = in->bv_val[ i ];
|
||||
if ( NEEDFLTESCAPE( c ) ) {
|
||||
l += 2;
|
||||
}
|
||||
}
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
int
|
||||
ldap_bv2escaped_filter_value( struct berval *in, struct berval *out )
|
||||
{
|
||||
ber_len_t i;
|
||||
static char escape[128] = {
|
||||
1, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
return ldap_bv2escaped_filter_value_x( in, out, 0, NULL );
|
||||
}
|
||||
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
1, 1, 1, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
int
|
||||
ldap_bv2escaped_filter_value_x( struct berval *in, struct berval *out, int inplace, void *ctx )
|
||||
{
|
||||
ber_len_t i, l;
|
||||
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 1, 0, 0, 0,
|
||||
assert( in != NULL );
|
||||
assert( out != NULL );
|
||||
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
BER_BVZERO( out );
|
||||
|
||||
out->bv_len = 0;
|
||||
out->bv_val = NULL;
|
||||
|
||||
if( in->bv_len == 0 ) return 0;
|
||||
if ( in->bv_len == 0 ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* assume we'll escape everything */
|
||||
out->bv_val = LDAP_MALLOC( 3 * in->bv_len + 1 );
|
||||
if( out->bv_val == NULL ) return -1;
|
||||
l = ldap_bv2escaped_filter_value_len( in );
|
||||
if ( l == in->bv_len ) {
|
||||
if ( inplace ) {
|
||||
*out = *in;
|
||||
} else {
|
||||
ber_dupbv( out, in );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
out->bv_val = LDAP_MALLOCX( l + 1, ctx );
|
||||
if ( out->bv_val == NULL ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for( i=0; i<in->bv_len; i++ ) {
|
||||
for ( i = 0; i < in->bv_len; i++ ) {
|
||||
char c = in->bv_val[ i ];
|
||||
if (c & 0x80 || escape[ (unsigned)c ]) {
|
||||
if ( NEEDFLTESCAPE( c ) ) {
|
||||
assert( out->bv_len < l - 2 );
|
||||
out->bv_val[out->bv_len++] = '\\';
|
||||
out->bv_val[out->bv_len++] = "0123456789ABCDEF"[0x0f & (c>>4)];
|
||||
out->bv_val[out->bv_len++] = "0123456789ABCDEF"[0x0f & c];
|
||||
|
||||
} else {
|
||||
assert( out->bv_len < l );
|
||||
out->bv_val[out->bv_len++] = c;
|
||||
}
|
||||
}
|
||||
|
||||
out->bv_val[out->bv_len] = '\0';
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -301,7 +301,8 @@ static char *build_filter(
|
||||
unique_data *ud,
|
||||
AttributeDescription *ad,
|
||||
BerVarray b,
|
||||
char *kp
|
||||
char *kp,
|
||||
void *ctx
|
||||
)
|
||||
{
|
||||
unique_attrs *up;
|
||||
@ -332,9 +333,11 @@ static char *build_filter(
|
||||
for ( i = 0; b[i].bv_val; i++ ) {
|
||||
struct berval bv;
|
||||
|
||||
ldap_bv2escaped_filter_value( &b[i], &bv );
|
||||
ldap_bv2escaped_filter_value_x( &b[i], &bv, 1, ctx );
|
||||
kp += sprintf( kp, "(%s=%s)", ad->ad_cname.bv_val, bv.bv_val );
|
||||
ldap_memfree( bv.bv_val );
|
||||
if ( bv.bv_val != b[i].bv_val ) {
|
||||
ber_memfree_x( bv.bv_val, ctx );
|
||||
}
|
||||
}
|
||||
} else if ( ud->strict ) {
|
||||
kp += sprintf( kp, "(%s=*)", ad->ad_cname.bv_val );
|
||||
@ -440,7 +443,7 @@ static int unique_add(
|
||||
kp = key + sprintf(key, "(|");
|
||||
|
||||
for(a = op->ora_e->e_attrs; a; a = a->a_next) {
|
||||
kp = build_filter(ud, a->a_desc, a->a_vals, kp);
|
||||
kp = build_filter(ud, a->a_desc, a->a_vals, kp, op->o_tmpmemctx);
|
||||
}
|
||||
|
||||
sprintf(kp, ")");
|
||||
@ -492,7 +495,7 @@ static int unique_modify(
|
||||
|
||||
for(m = op->orm_modlist; m; m = m->sml_next) {
|
||||
if ((m->sml_op & LDAP_MOD_OP) == LDAP_MOD_DELETE) continue;
|
||||
kp = build_filter(ud, m->sml_desc, m->sml_values, kp);
|
||||
kp = build_filter(ud, m->sml_desc, m->sml_values, kp, op->o_tmpmemctx);
|
||||
}
|
||||
|
||||
sprintf(kp, ")");
|
||||
@ -555,7 +558,7 @@ static int unique_modrdn(
|
||||
|
||||
for(i = 0; newrdn[i]; i++) {
|
||||
bv[0] = newrdn[i]->la_value;
|
||||
kp = build_filter(ud, newrdn[i]->la_private, bv, kp);
|
||||
kp = build_filter(ud, newrdn[i]->la_private, bv, kp, op->o_tmpmemctx);
|
||||
}
|
||||
|
||||
sprintf(kp, ")");
|
||||
|
Loading…
Reference in New Issue
Block a user