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,
-
- 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
- };
-
- out->bv_len = 0;
- out->bv_val = NULL;
-
- if( in->bv_len == 0 ) return 0;
+ return ldap_bv2escaped_filter_value_x( in, out, 0, NULL );
+}
+
+int
+ldap_bv2escaped_filter_value_x( struct berval *in, struct berval *out, int inplace, void *ctx )
+{
+ ber_len_t i, l;
+
+ assert( in != NULL );
+ assert( out != NULL );
+
+ BER_BVZERO( out );
+
+ 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;
}
unique_data *ud,
AttributeDescription *ad,
BerVarray b,
- char *kp
+ char *kp,
+ void *ctx
)
{
unique_attrs *up;
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 );
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, ")");
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, ")");
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, ")");