From: Howard Chu Date: Mon, 18 Mar 2002 11:40:58 +0000 (+0000) Subject: Use a single malloc'd block for all the temporary IDL storage in the X-Git-Tag: OPENLDAP_REL_ENG_2_MP~339 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=cc21d814b3a553d57f06e8af4feb9b5eb66a444c;p=openldap 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. --- diff --git a/servers/slapd/back-bdb/filterindex.c b/servers/slapd/back-bdb/filterindex.c index 8387a702ba..4d973ce67d 100644 --- a/servers/slapd/back-bdb/filterindex.c +++ b/servers/slapd/back-bdb/filterindex.c @@ -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 ) )); diff --git a/servers/slapd/back-bdb/proto-bdb.h b/servers/slapd/back-bdb/proto-bdb.h index d29256860e..cdea9803e1 100644 --- a/servers/slapd/back-bdb/proto-bdb.h +++ b/servers/slapd/back-bdb/proto-bdb.h @@ -120,7 +120,8 @@ int bdb_filter_candidates( Backend *be, Filter *f, ID *ids, - ID *tmp ); + ID *tmp, + ID *stack ); /* * group.c diff --git a/servers/slapd/back-bdb/search.c b/servers/slapd/back-bdb/search.c index df7ce17dd2..af75427d2a 100644 --- a/servers/slapd/back-bdb/search.c +++ b/servers/slapd/back-bdb/search.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