mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-12-23 08:09:34 -05:00
Use a single malloc'd block for all the temporary IDL storage in the
filter processing, to avoid runtime stack blowout. Also removes the need for gigantic thread stacks.
This commit is contained in:
parent
bad62d2167
commit
cc21d814b3
3 changed files with 34 additions and 26 deletions
|
|
@ -39,14 +39,16 @@ static int list_candidates(
|
|||
Filter *flist,
|
||||
int ftype,
|
||||
ID *ids,
|
||||
ID *tmp );
|
||||
ID *tmp,
|
||||
ID *stack );
|
||||
|
||||
int
|
||||
bdb_filter_candidates(
|
||||
Backend *be,
|
||||
Filter *f,
|
||||
ID *ids,
|
||||
ID *tmp )
|
||||
ID *tmp,
|
||||
ID *stack )
|
||||
{
|
||||
int rc = -1;
|
||||
#ifdef NEW_LOGGING
|
||||
|
|
@ -146,7 +148,7 @@ bdb_filter_candidates(
|
|||
Debug( LDAP_DEBUG_FILTER, "\tAND\n", 0, 0, 0 );
|
||||
#endif
|
||||
rc = list_candidates( be,
|
||||
f->f_and, LDAP_FILTER_AND, ids, tmp );
|
||||
f->f_and, LDAP_FILTER_AND, ids, tmp, stack );
|
||||
break;
|
||||
|
||||
case LDAP_FILTER_OR:
|
||||
|
|
@ -156,7 +158,7 @@ bdb_filter_candidates(
|
|||
Debug( LDAP_DEBUG_FILTER, "\tOR\n", 0, 0, 0 );
|
||||
#endif
|
||||
rc = list_candidates( be,
|
||||
f->f_or, LDAP_FILTER_OR, ids, tmp );
|
||||
f->f_or, LDAP_FILTER_OR, ids, tmp, stack );
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -187,20 +189,13 @@ list_candidates(
|
|||
Filter *flist,
|
||||
int ftype,
|
||||
ID *ids,
|
||||
ID *tmp )
|
||||
ID *tmp,
|
||||
ID *save )
|
||||
{
|
||||
struct bdb_info *bdb = (struct bdb_info *) be->be_private;
|
||||
int rc = 0;
|
||||
Filter *f;
|
||||
|
||||
/* Systems that can't increase thread stack size will die with these
|
||||
* structures allocated on the stack. */
|
||||
#if !defined(LDAP_PVT_THREAD_STACK_SIZE) || (LDAP_PVT_THREAD_STACK_SIZE == 0)
|
||||
ID *save = ch_malloc(BDB_IDL_UM_SIZEOF);
|
||||
#else
|
||||
ID save[BDB_IDL_UM_SIZE];
|
||||
#endif
|
||||
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG (( "filterindex", LDAP_LEVEL_ARGS, "=> bdb_list_candidates: 0x%x\n", ftype));
|
||||
#else
|
||||
|
|
@ -215,7 +210,8 @@ list_candidates(
|
|||
}
|
||||
|
||||
for ( f = flist; f != NULL; f = f->f_next ) {
|
||||
rc = bdb_filter_candidates( be, f, save, tmp );
|
||||
rc = bdb_filter_candidates( be, f, save, tmp,
|
||||
save+BDB_IDL_UM_SIZE );
|
||||
|
||||
if ( rc != 0 ) {
|
||||
if ( ftype == LDAP_FILTER_AND ) {
|
||||
|
|
@ -235,10 +231,6 @@ list_candidates(
|
|||
}
|
||||
}
|
||||
|
||||
#if !defined(LDAP_PVT_THREAD_STACK_SIZE) || (LDAP_PVT_THREAD_STACK_SIZE == 0)
|
||||
free(save);
|
||||
#endif
|
||||
|
||||
if( rc ) {
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG (( "filterindex", LDAP_LEVEL_RESULTS, "<= bdb_list_candidates: id=%ld first=%ld last=%ld\n", (long) ids[0], (long) BDB_IDL_FIRST( ids ), (long) BDB_IDL_LAST( ids ) ));
|
||||
|
|
|
|||
|
|
@ -120,7 +120,8 @@ int bdb_filter_candidates(
|
|||
Backend *be,
|
||||
Filter *f,
|
||||
ID *ids,
|
||||
ID *tmp );
|
||||
ID *tmp,
|
||||
ID *stack );
|
||||
|
||||
/*
|
||||
* group.c
|
||||
|
|
|
|||
|
|
@ -541,14 +541,19 @@ static int base_candidate(
|
|||
}
|
||||
|
||||
/* Is "objectClass=xx" mentioned anywhere in this filter? Presence
|
||||
* doesn't count, we're looking for explicit values.
|
||||
* doesn't count, we're looking for explicit values. Also count depth
|
||||
* of filter tree while we're at it.
|
||||
*/
|
||||
static int oc_filter(
|
||||
Filter *f
|
||||
Filter *f,
|
||||
int cur,
|
||||
int *max
|
||||
)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if( cur > *max ) *max = cur;
|
||||
|
||||
switch(f->f_choice) {
|
||||
case LDAP_FILTER_EQUALITY:
|
||||
case LDAP_FILTER_APPROX:
|
||||
|
|
@ -563,8 +568,9 @@ static int oc_filter(
|
|||
|
||||
case LDAP_FILTER_AND:
|
||||
case LDAP_FILTER_OR:
|
||||
cur++;
|
||||
for (f=f->f_and; f; f=f->f_next)
|
||||
if ((rc = oc_filter(f)))
|
||||
if ((rc = oc_filter(f, cur, max)))
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
|
|
@ -582,9 +588,9 @@ static int search_candidates(
|
|||
int deref,
|
||||
ID *ids )
|
||||
{
|
||||
int rc;
|
||||
int rc, depth = 1;
|
||||
Filter f, scopef, rf, xf;
|
||||
ID tmp[BDB_IDL_UM_SIZE];
|
||||
ID *stack;
|
||||
AttributeAssertion aa_ref;
|
||||
#ifdef BDB_SUBENTRIES
|
||||
Filter sf;
|
||||
|
|
@ -618,7 +624,7 @@ static int search_candidates(
|
|||
/* If the user's filter doesn't mention objectClass, or if
|
||||
* it just uses objectClass=*, these clauses are redundant.
|
||||
*/
|
||||
if (oc_filter(filter) && !get_subentries_visibility(op) ) {
|
||||
if (oc_filter(filter, 1, &depth) && !get_subentries_visibility(op) ) {
|
||||
if( !get_manageDSAit(op) ) { /* match referrals */
|
||||
struct berval bv_ref = { sizeof("REFERRAL")-1, "REFERRAL" };
|
||||
rf.f_choice = LDAP_FILTER_EQUALITY;
|
||||
|
|
@ -640,6 +646,8 @@ static int search_candidates(
|
|||
xf.f_or = ⁡
|
||||
}
|
||||
#endif
|
||||
/* We added one of these clauses, filter depth increased */
|
||||
if( xf.f_or != filter ) depth++;
|
||||
}
|
||||
|
||||
f.f_next = NULL;
|
||||
|
|
@ -650,6 +658,8 @@ static int search_candidates(
|
|||
: SLAPD_FILTER_DN_ONE;
|
||||
scopef.f_dn = &e->e_nname;
|
||||
scopef.f_next = xf.f_or == filter ? filter : &xf ;
|
||||
/* Filter depth increased again, adding scope clause */
|
||||
depth++;
|
||||
|
||||
#ifdef BDB_SUBENTRIES
|
||||
if( get_subentries_visibility( op ) ) {
|
||||
|
|
@ -663,7 +673,12 @@ static int search_candidates(
|
|||
}
|
||||
#endif
|
||||
|
||||
rc = bdb_filter_candidates( be, &f, ids, tmp );
|
||||
/* Allocate IDL stack, plus 1 more for former tmp */
|
||||
stack = malloc( (depth + 1) * BDB_IDL_UM_SIZE * sizeof( ID ) );
|
||||
|
||||
rc = bdb_filter_candidates( be, &f, ids, stack, stack+BDB_IDL_UM_SIZE );
|
||||
|
||||
free( stack );
|
||||
|
||||
if( rc ) {
|
||||
#ifdef NEW_LOGGING
|
||||
|
|
|
|||
Loading…
Reference in a new issue