diff --git a/ldap.h b/ldap.h index 6ef0324..c2536cf 100644 --- a/ldap.h +++ b/ldap.h @@ -34,10 +34,12 @@ struct Substring { struct Substring* next; }; +enum FilterType { + AND=0, OR=1, NOT=2, EQUAL=3, SUBSTRING=4, GREATEQUAL=5, LESSEQUAL=6, PRESENT=7, APPROX=8, EXTENSIBLE=9 +}; + struct Filter { - enum { - AND=0, OR=1, NOT=2, EQUAL=3, SUBSTRING=4, GREATEQUAL=5, LESSEQUAL=6, PRESENT=7, APPROX=8, EXTENSIBLE=9 - } type; + enum FilterType type; struct AttributeValueAssertion ava; uint32 attrofs; /* offset of attribute name in index */ uint32 attrflag; /* "case sensitivity" flag from index */ diff --git a/ldap_match_mapped.c b/ldap_match_mapped.c index 6ea8965..537cd90 100644 --- a/ldap_match_mapped.c +++ b/ldap_match_mapped.c @@ -68,6 +68,7 @@ uint32 ldap_find_attr_value(uint32 ofs,uint32 attrofs) { static inline int matchint(struct Filter* f,const char* t) { int r; + if (f->attrflag&1) r=matchcasestring(&f->ava.value,t); else diff --git a/scan_ldapsearchfilterstring.c b/scan_ldapsearchfilterstring.c index c7bd693..6e75177 100644 --- a/scan_ldapsearchfilterstring.c +++ b/scan_ldapsearchfilterstring.c @@ -14,7 +14,9 @@ scan_filterlist: s+=scan_ldapsearchfilterstring(s,&(*f)->x); n=&(*f)->x->next; while (*s!=')') { - s+=scan_ldapsearchfilterstring(s,n); + unsigned long l=scan_ldapsearchfilterstring(s,n); + if (!l) return 0; + s+=l; n=&(*n)->next; } } diff --git a/tinyldap.c b/tinyldap.c index 062ea54..7002afb 100644 --- a/tinyldap.c +++ b/tinyldap.c @@ -285,16 +285,18 @@ static inline int isset(unsigned long* r,unsigned long bit) { * for all records that match the value in s. Set the corresponding * bits to 1 in bitfield. */ static void tagmatches(uint32* index,unsigned int elements,struct string* s, - unsigned long* bitfield,int (*match)(struct string* s,const char* c),uint32 index_type) { + unsigned long* bitfield,int (*match)(struct string* s,const char* c), + uint32 index_type,enum FilterType ft) { uint32 bottom=0; uint32 top=elements; + uint32 mid,k,m; + long rec; emptyset(bitfield); while ((top>=bottom)) { - uint32 mid=(top+bottom)/2; - uint32 k; int l; + mid=(top+bottom)/2; k=uint32_read((char*)(&index[mid])); #ifdef DEBUG buffer_puts(buffer_2,"match["); @@ -309,8 +311,6 @@ static void tagmatches(uint32* index,unsigned int elements,struct string* s, #endif if ((l=match(s,map+k))==0) { /* match! */ - long rec; - uint32 m; #ifdef DEBUG buffer_putsflush(buffer_2,"MATCH!\n"); #endif @@ -330,7 +330,7 @@ static void tagmatches(uint32* index,unsigned int elements,struct string* s, * Look before and after mid, too */ for (k=mid-1; k>0; --k) { m=uint32_read((char*)(&index[k])); - if ((l=match(s,map+m))==0) { + if ((ft==LESSEQUAL) || (l=match(s,map+m))==0) { if (index_type==0) rec=findrec(m); else if (index_type==1) @@ -341,7 +341,7 @@ static void tagmatches(uint32* index,unsigned int elements,struct string* s, } for (k=mid+1; k=0) + setbit(bitfield,rec); + } + } else if (ft==LESSEQUAL) { + for (k=0; k<=mid; ++k) { + m=uint32_read((char*)(&index[k])); + if (index_type==0) + rec=findrec(m); + else if (index_type==1) + rec=uint32_read((char*)(&index[k+elements])); + if (rec>=0) + setbit(bitfield,rec); + } + } } /* Use the indices to answer a query with the given filter. @@ -429,7 +452,7 @@ static int useindex(struct Filter* f,unsigned long* bitfield) { if (index_type<=1) if (!matchstring(&f->ava.desc,map+indexed_attribute)) { tagmatches((uint32*)(map+ofs+12),(next-ofs-12)/(4<substrings->s,bitfield, - f->attrflag&1?matchcaseprefix:matchprefix,index_type); + f->attrflag&1?matchcaseprefix:matchprefix,index_type,f->type); return 1; } ofs=next; @@ -451,6 +474,8 @@ static int useindex(struct Filter* f,unsigned long* bitfield) { } return 1; } + case LESSEQUAL: + case GREATEQUAL: case EQUAL: { uint32 ofs; @@ -462,7 +487,7 @@ static int useindex(struct Filter* f,unsigned long* bitfield) { if (index_type<=1) if (!matchstring(&f->ava.desc,map+indexed_attribute)) { tagmatches((uint32*)(map+ofs+12),(next-ofs-12)/(4<ava.value,bitfield, - f->attrflag&1?matchcasestring:matchstring,index_type); + f->attrflag&1?matchcasestring:matchstring,index_type,f->type); return 1; } ofs=next;