diff --git a/scan_asn1BITSTRING.c b/scan_asn1BITSTRING.c index def75a1..e39d0e2 100644 --- a/scan_asn1BITSTRING.c +++ b/scan_asn1BITSTRING.c @@ -59,5 +59,6 @@ int main() { strcpy(buf,"\x03\x02\x07\x81"); // 0x03 = UNIVERSAL PRIMITIVE BIT_STRING, 0x02 = length 2, 0x07 = unused bits in last octet, 0x81 = invalid assert(scan_asn1BITSTRING(buf,buf+4,&s,&l)==0); // unused bits not 0, return 0 in line 21 // we only care for 100% coverage of this file, the others have their own unit tests */ + return 0; } #endif diff --git a/scan_asn1BOOLEAN.c b/scan_asn1BOOLEAN.c index 99499bc..bdcdfef 100644 --- a/scan_asn1BOOLEAN.c +++ b/scan_asn1BOOLEAN.c @@ -40,5 +40,6 @@ int main() { buf[0]=0x30; buf[2]=1; assert(scan_asn1BOOLEAN(buf,buf+3,&l)==0); // 0x30 = SEQUENCE_OF, fails line 10 // we only care for 100% coverage of this file, the others have their own unit tests */ + return 0; } #endif diff --git a/scan_asn1ENUMERATED.c b/scan_asn1ENUMERATED.c index de117a7..ffc1b7d 100644 --- a/scan_asn1ENUMERATED.c +++ b/scan_asn1ENUMERATED.c @@ -34,5 +34,6 @@ int main() { buf[0]=0x30; assert(scan_asn1ENUMERATED(buf,buf+3,&l)==0); // 0x30 = SEQUENCE_OF, fails line 10 // we only care for 100% coverage of this file, the others have their own unit tests */ + return 0; } #endif diff --git a/scan_asn1INTEGER.c b/scan_asn1INTEGER.c index dbfd2f3..dcef9c7 100644 --- a/scan_asn1INTEGER.c +++ b/scan_asn1INTEGER.c @@ -49,5 +49,6 @@ int main() { strcpy(buf,"\x02\x08\xff\xff\xff\xff\xff\xff\xff\xff"); assert(scan_asn1INTEGER(buf,buf+10,&l)==0); // non-minimal encoding of -1 } + return 0; } #endif diff --git a/scan_asn1SEQUENCE.c b/scan_asn1SEQUENCE.c index 50c0a32..2dcfe2e 100644 --- a/scan_asn1SEQUENCE.c +++ b/scan_asn1SEQUENCE.c @@ -35,5 +35,6 @@ int main() { buf[0]=0x31; assert(scan_asn1SEQUENCE(buf,buf+3,&l)==0); // 0x31 = SET_OF, third return 0 // we only care for 100% coverage of this file, the others have their own unit tests */ + return 0; } #endif diff --git a/scan_asn1SEQUENCE_nolengthcheck.c b/scan_asn1SEQUENCE_nolengthcheck.c index 6a05240..75c1f08 100644 --- a/scan_asn1SEQUENCE_nolengthcheck.c +++ b/scan_asn1SEQUENCE_nolengthcheck.c @@ -13,4 +13,28 @@ size_t scan_asn1SEQUENCE_nolengthcheck(const char* src,const char* max,size_t* l return 0; } +#ifdef UNITTEST +#include +#include +#undef UNITTEST +#include "scan_asn1tag.c" +#include "scan_asn1tagint.c" +#include "scan_asn1length.c" + +int main() { + char buf[100]; + size_t l; + strcpy(buf,"\x30\x01\x01"); // 0x30 = UNIVERSAL + CONSTRUCTED + SEQUENCE_OF, 0x01 = length 1, 0x01 = dummy filler + // this function only parses the header so our test data doesn't need + // to have an actual sequence, only the header for one. \x01 is not a + // valid sequence. + assert(scan_asn1SEQUENCE_nolengthcheck(buf,buf+3,&l)==2 && l==1); + assert(scan_asn1SEQUENCE_nolengthcheck(buf,buf,&l)==0); // not enough input, first return 0 + assert(scan_asn1SEQUENCE_nolengthcheck(buf,buf+2,&l)==2 && l==1); // not enough input, but we used the _nolengthcheck version so expect success + buf[0]=0x31; + assert(scan_asn1SEQUENCE_nolengthcheck(buf,buf+3,&l)==0); // 0x31 = SET_OF, third return 0 + // we only care for 100% coverage of this file, the others have their own unit tests */ + return 0; +} +#endif diff --git a/scan_asn1SET.c b/scan_asn1SET.c index 47ed3e8..fbc83ae 100644 --- a/scan_asn1SET.c +++ b/scan_asn1SET.c @@ -37,5 +37,6 @@ int main() { buf[0]=0x30; assert(scan_asn1SET(buf,buf+3,&l)==0); // 0x30 = SEQUENCE_OF, third return 0 // we only care for 100% coverage of this file, the others have their own unit tests */ + return 0; } #endif diff --git a/scan_asn1STRING.c b/scan_asn1STRING.c index 540a02d..3a9b0dc 100644 --- a/scan_asn1STRING.c +++ b/scan_asn1STRING.c @@ -31,5 +31,6 @@ int main() { buf[0]=0x13; // 0x13 = UNIVERSAL PRIMITIVE PrintableString assert(scan_asn1STRING(buf,buf+7,&s,&l)==0); // scan_asn1string succeeds but line 9 fails // we only care for 100% coverage of this file, the others have their own unit tests */ + return 0; } #endif diff --git a/scan_asn1int.c b/scan_asn1int.c index 5f051b7..3cee92d 100644 --- a/scan_asn1int.c +++ b/scan_asn1int.c @@ -36,5 +36,6 @@ int main() { assert(scan_asn1int(buf,buf+3,&tc,&tt,&tag,&l)==0); // not enough input, second return 0 assert(scan_asn1int(buf,buf+4,&tc,&tt,&tag,&l)==0); // non-minimally encoded raw int, third return // we only care for 100% coverage of this file, the others have their own unit tests */ + return 0; } #endif diff --git a/scan_asn1length.c b/scan_asn1length.c index bdaae0e..28bac23 100644 --- a/scan_asn1length.c +++ b/scan_asn1length.c @@ -114,5 +114,6 @@ int main() { assert(scan_asn1length(buf,buf+10,&l)==0); // length fits, value doesn't assert(scan_asn1length(buf,buf+0x8010,&l)==3 && l==0x8000); // OK assert(scan_asn1length(buf,buf+2,&l)==0); // length doesn't fit + return 0; } #endif diff --git a/scan_asn1oid.c b/scan_asn1oid.c index 0511ba2..4a6c1de 100644 --- a/scan_asn1oid.c +++ b/scan_asn1oid.c @@ -52,5 +52,6 @@ int main() { buf[1]=3; assert(scan_asn1oid(buf,buf+6,retval,&retvals)==0); // trigger line 21 // we only care for 100% coverage of this file, the others have their own unit tests */ + return 0; } #endif diff --git a/scan_asn1rawint.c b/scan_asn1rawint.c index 6e27c93..a07b523 100644 --- a/scan_asn1rawint.c +++ b/scan_asn1rawint.c @@ -93,5 +93,6 @@ int main() { assert(scan_asn1rawint(buf, buf+sizeof(long)+1, sizeof(long)+1, &l) == 0); memcpy(buf,"\x00\xff\xff\xff\xff\xff\xff\xff\xff",9); assert(scan_asn1rawint(buf, buf+sizeof(long)+1, sizeof(long)+1, &l) == 0); + return 0; } #endif diff --git a/scan_asn1rawoid.c b/scan_asn1rawoid.c index c88dce1..8da5581 100644 --- a/scan_asn1rawoid.c +++ b/scan_asn1rawoid.c @@ -70,5 +70,6 @@ int main() { retvals=10; assert(scan_asn1rawoid(buf,buf+3,retval,&retvals)==3 && retvals==4 && retval[0]==2 && retval[1]==100 && retval[2]==4 && retval[3]==3); // we only care for 100% coverage of this file, the others have their own unit tests */ + return 0; } #endif diff --git a/scan_asn1string.c b/scan_asn1string.c index c1ae632..ba341c6 100644 --- a/scan_asn1string.c +++ b/scan_asn1string.c @@ -34,5 +34,6 @@ int main() { assert(scan_asn1string(buf,buf,&tc,&tt,&tag,&s,&l)==0); // not enough input, first return 0 assert(scan_asn1string(buf,buf+6,&tc,&tt,&tag,&s,&l)==0); // not enough input, second return 0 // we only care for 100% coverage of this file, the others have their own unit tests */ + return 0; } #endif diff --git a/scan_asn1tag.c b/scan_asn1tag.c index 28097e1..98e86c3 100644 --- a/scan_asn1tag.c +++ b/scan_asn1tag.c @@ -86,5 +86,6 @@ int main() { assert(scan_asn1tag(buf,buf+11,&tc,&tt,&tag)==0); memcpy(buf,"\x1f\x8f\xff\xff\xff\x7f",7); assert(scan_asn1tag(buf,buf+7,&tc,&tt,&tag)==6 && tc==UNIVERSAL && tt==PRIMITIVE && tag==0xffffffff); + return 0; } #endif diff --git a/scan_asn1tagint.c b/scan_asn1tagint.c index 71cd1bd..f28758f 100644 --- a/scan_asn1tagint.c +++ b/scan_asn1tagint.c @@ -77,5 +77,6 @@ int main() { memcpy(buf,"\x90\x00\x00\x00\x00",9); assert(scan_asn1tagint(buf,buf+10,&l)==0); // too large } + return 0; } #endif diff --git a/scan_ldapava.c b/scan_ldapava.c index b9332c4..d7564cd 100644 --- a/scan_ldapava.c +++ b/scan_ldapava.c @@ -2,8 +2,10 @@ size_t scan_ldapava(const char* src,const char* max,struct AttributeValueAssertion* ava) { size_t res,tmp; - if (!(res=scan_ldapstring(src,max,&ava->desc))) goto error; - if (!(tmp=scan_ldapstring(src+res,max,&ava->value))) goto error; + if (!(res=scan_ldapstring(src,max,&ava->desc))) + goto error; + if (!(tmp=scan_ldapstring(src+res,max,&ava->value))) + goto error; return res+tmp; error: return 0; diff --git a/scan_ldapbindrequest.c b/scan_ldapbindrequest.c index 0ce7e12..83f9a7e 100644 --- a/scan_ldapbindrequest.c +++ b/scan_ldapbindrequest.c @@ -4,14 +4,48 @@ size_t scan_ldapbindrequest(const char* src,const char* max, unsigned long* version,struct string* name, unsigned long* method) { size_t res,tmp; - if (!(res=scan_asn1INTEGER(src,max,(signed long*)version))) return 0; - if (!(tmp=scan_ldapstring(src+res,max,name))) return 0; + if (!(res=scan_asn1INTEGER(src,max,(signed long*)version))) + return 0; + if (!(tmp=scan_ldapstring(src+res,max,name))) + return 0; res+=tmp; { enum asn1_tagclass tc; enum asn1_tagtype tt; - if (!(tmp=scan_asn1tag(src+res,max,&tc,&tt,method))) return 0; - if (tc!=PRIVATE || tt!=PRIMITIVE) return 0; + if (!(tmp=scan_asn1tag(src+res,max,&tc,&tt,method))) + return 0; + if (tc!=PRIVATE || tt!=PRIMITIVE) + return 0; + res+=tmp; } return res; } + +#ifdef UNITTEST +#undef UNITTEST +#include +#include "scan_asn1STRING.c" +#include "scan_asn1tag.c" +#include "scan_asn1tagint.c" +#include "scan_asn1length.c" +#include "scan_asn1string.c" +#include "scan_ldapstring.c" +#include "scan_asn1rawint.c" +#include "scan_asn1int.c" +#include "scan_asn1INTEGER.c" + +int main() { + static char buf[] = "\x02\x01\x03\x04\x00\x80"; // bind request without message header + unsigned long version=0, method=0; + struct string name = { 0 }; + assert(scan_ldapbindrequest(buf, buf+6, &version, &name, &method)==6 && version==3 && name.l==0 && method==0); + assert(scan_ldapbindrequest(buf, buf+5, &version, &name, &method)==0); // too short + buf[5]=0; assert(scan_ldapbindrequest(buf, buf+6, &version, &name, &method)==0); // tc!=PRIVATE + buf[5]=0xa0; assert(scan_ldapbindrequest(buf, buf+6, &version, &name, &method)==0); // tt!=PRIMITIVE + buf[5]=0x1f; assert(scan_ldapbindrequest(buf, buf+6, &version, &name, &method)==0); // fail scan_asn1tag + buf[4]=5; assert(scan_ldapbindrequest(buf, buf+6, &version, &name, &method)==0); // fail scan_ldapstring + buf[0]=0; assert(scan_ldapbindrequest(buf, buf+6, &version, &name, &method)==0); // fail scan_asn1INTEGER + // we only care for 100% coverage of this file, the others have their own unit tests */ + return 0; +} +#endif diff --git a/scan_ldapmessage.c b/scan_ldapmessage.c index baa1173..9d469cd 100644 --- a/scan_ldapmessage.c +++ b/scan_ldapmessage.c @@ -3,19 +3,55 @@ size_t scan_ldapmessage(const char* src,const char* max, unsigned long* messageid,unsigned long* op,size_t* len) { size_t res,tmp; - if (!(res=scan_asn1SEQUENCE(src,max,len))) goto error; - if (!(tmp=scan_asn1INTEGER(src+res,max,(long*)messageid))) goto error; + if (!(res=scan_asn1SEQUENCE(src,max,len))) + goto error; + if (!(tmp=scan_asn1INTEGER(src+res,max,(long*)messageid))) + goto error; res+=tmp; { enum asn1_tagclass tc; enum asn1_tagtype tt; - if (!(tmp=scan_asn1tag(src+res,max,&tc,&tt,op))) goto error; - if (tc!=APPLICATION) goto error; + if (!(tmp=scan_asn1tag(src+res,max,&tc,&tt,op))) + goto error; + if (tc!=APPLICATION) + goto error; res+=tmp; - if (!(tmp=scan_asn1length(src+res,max,len))) goto error; + if (!(tmp=scan_asn1length(src+res,max,len))) + goto error; res+=tmp; } return res; error: return 0; } + +#ifdef UNITTEST +#undef UNITTEST +#include +#include +#include "scan_asn1SEQUENCE.c" +#include "scan_asn1INTEGER.c" +#include "scan_asn1tag.c" +#include "scan_asn1tagint.c" +#include "scan_asn1length.c" +#include "scan_asn1int.c" +#include "scan_asn1rawint.c" + +int main() { + static char buf[] = "\x30\x0c\x02\x01\x01\x60\x07\x02\x01\x03\x04\x00\x80\x00"; // an LDAP bind request + + unsigned long msgid=0, op=0; + size_t len=0; + assert(scan_ldapmessage(buf,buf+14,&msgid,&op,&len)==7 && msgid==1 && op==BindRequest && len == 7); + // trigger scan_asn1SEQUENCE error (too short) + assert(scan_ldapmessage(buf,buf+13,&msgid,&op,&len)==0); + buf[6]=8; assert(scan_ldapmessage(buf,buf+14,&msgid,&op,&len)==0); // fail scan_asn1length + buf[5]=0; assert(scan_ldapmessage(buf,buf+14,&msgid,&op,&len)==0); // fail tc==APPLICATION + buf[5]=0x80; assert(scan_ldapmessage(buf,buf+14,&msgid,&op,&len)==0); // fail scan_asn1tag + buf[2]=0; assert(scan_ldapmessage(buf,buf+14,&msgid,&op,&len)==0); // fail scan_asn1INTEGER + buf[0]=0; assert(scan_ldapmessage(buf,buf+14,&msgid,&op,&len)==0); // fail scan_asn1SEQUENCE + // we only care for 100% coverage of this file, the others have their own unit tests */ + return 0; +} + +#endif diff --git a/scan_ldapmessage_nolengthcheck.c b/scan_ldapmessage_nolengthcheck.c index 1d5e7c3..7563b63 100644 --- a/scan_ldapmessage_nolengthcheck.c +++ b/scan_ldapmessage_nolengthcheck.c @@ -3,3 +3,21 @@ size_t scan_ldapmessage_nolengthcheck(const char* src,const char* max,size_t* len) { return scan_asn1SEQUENCE_nolengthcheck(src,max,len); } + +#ifdef UNITTEST +#include +#undef UNITTEST +#include "scan_asn1tag.c" +#include "scan_asn1tagint.c" +#include "scan_asn1length.c" +#include "scan_asn1SEQUENCE_nolengthcheck.c" + +int main() { + static char buf[] = "\x30\x01\x01"; // 0x30 = UNIVERSAL + CONSTRUCTED + SEQUENCE_OF, 0x01 = length 1, 0x01 = dummy filler + size_t l; + + assert(scan_ldapmessage_nolengthcheck(buf,buf+3,&l)==2 && l==1); + // we only care for 100% coverage of this file, the others have their own unit tests */ + return 0; +} +#endif diff --git a/scan_ldapsearchfilter.c b/scan_ldapsearchfilter.c index db81e7f..606dc03 100644 --- a/scan_ldapsearchfilter.c +++ b/scan_ldapsearchfilter.c @@ -36,24 +36,27 @@ size_t scan_ldapsearchfilter(const char* src,const char* max,struct Filter** f) unsigned long tag; const char* nmax; *f=0; - if (!(res=scan_asn1tag(src,max,&tc,&tt,&tag))) goto error; - if (tc!=PRIVATE || (tt!=CONSTRUCTED && tag!=7) || tag>9) goto error; - if (!(tmp=scan_asn1length(src+res,max,&len))) goto error; + if (!(res=scan_asn1tag(src,max,&tc,&tt,&tag))) // fail01 + goto error; + if (tc!=PRIVATE || (tt!=CONSTRUCTED && tag!=7) || tag>9) // fail02 + goto error; + if (!(tmp=scan_asn1length(src+res,max,&len))) // fail03 + goto error; res+=tmp; nmax=src+res+len; - if (nmax>max) goto error; - if (!(*f=calloc(1,sizeof(struct Filter)))) goto error; +#if 0 + if (nmax>max) // already caught by scan_asn1length + goto error; +#endif + if (!(*f=calloc(1,sizeof(struct Filter)))) // fail04 + goto error; switch ((*f)->type=tag) { case 0: /* and [0] SET OF Filter, */ case 1: /* or [1] SET OF Filter, */ (*f)->x=0; while (src+resx; - if (!(tmp=scan_ldapsearchfilter(src+res,nmax,&(*f)->x))) { - if (F) { /* OK, end of sequence */ - (*f)->x=F; - break; - } + if (!(tmp=scan_ldapsearchfilter(src+res,nmax,&(*f)->x))) { // fail05 (*f)->x=F; goto error; } @@ -62,32 +65,40 @@ size_t scan_ldapsearchfilter(const char* src,const char* max,struct Filter** f) } break; case 2: /* not [2] Filter, */ - if (!(tmp=scan_ldapsearchfilter(src+res,nmax,&(*f)->x))) goto error; - if (tmp!=len) goto error; + if (!(tmp=scan_ldapsearchfilter(src+res,nmax,&(*f)->x))) // fail06 + goto error; + if (tmp!=len) // fail07 + goto error; res+=tmp; break; case 3: /* equalityMatch [3] AttributeValueAssertion, */ case 5: /* greaterOrEqual [5] AttributeValueAssertion, */ case 6: /* lessOrEqual [6] AttributeValueAssertion, */ case 8: /* approxMatch [8] AttributeValueAssertion, */ - if (!(tmp=scan_ldapava(src+res,nmax,&(*f)->ava))) goto error; + if (!(tmp=scan_ldapava(src+res,nmax,&(*f)->ava))) // fail08 + goto error; res+=tmp; break; case 4: /* substrings [4] SubstringFilter, */ { size_t len2; - if (!(tmp=scan_ldapstring(src+res,nmax,&(*f)->ava.desc))) goto error; + if (!(tmp=scan_ldapstring(src+res,nmax,&(*f)->ava.desc))) // fail09 + goto error; res+=tmp; - if (!(tmp=scan_asn1SEQUENCE(src+res,nmax,&len2))) goto error; + if (!(tmp=scan_asn1SEQUENCE(src+res,nmax,&len2))) // fail10 + goto error; res+=tmp; - if (src+res+len2!=nmax) goto error; while (src+ress.s,&s->s.l)) || x>2) { free(s); goto error; } + if (!s) // fail11 + goto error; + if (!(tmp=scan_asn1string(src+res,nmax,&tc,&tt,&x,&s->s.s,&s->s.l)) || x>2) { // fail12 + free(s); + goto error; + } s->substrtype=x; res+=tmp; s->next=(*f)->substrings; @@ -100,9 +111,9 @@ size_t scan_ldapsearchfilter(const char* src,const char* max,struct Filter** f) (*f)->ava.desc.l=len; res+=len; break; - case 9: /* extensibleMatch [9] MatchingRuleAssertion } */ + case 9: /* extensibleMatch [9] MatchingRuleAssertion */ default: - goto error; + goto error; // fail14 } return res; error: @@ -110,3 +121,116 @@ error: *f=0; return 0; } + +#ifdef UNITTEST +#undef UNITTEST +#include +#include +#include "free_ldapsearchfilter.c" +#include "scan_asn1tag.c" +#include "scan_asn1length.c" +#include "scan_ldapava.c" +#include "scan_ldapstring.c" +#include "scan_asn1STRING.c" +#include "scan_asn1tagint.c" +#include "scan_asn1string.c" +#include "scan_asn1SEQUENCE.c" + +#include + +size_t callocfail=(size_t)-1; +void* calloc(size_t a,size_t b) { + if (--callocfail==0) return 0; + size_t l; + assert(__builtin_mul_overflow(a,b,&l)==0); + void* x = malloc(l); + if (x) memset(x,0,l); + return x; +} + +int main() { + struct Filter *f = 0; + char buf[100]; + strcpy(buf,"\x87\x03""foo"); + + // type 7, PRESENT + assert(scan_ldapsearchfilter(buf, buf+100, &f) == 5); // "(foo=*)" (PRESENT) + assert(f && f->type==PRESENT && f->ava.desc.l==3 && !memcmp(f->ava.desc.s,"foo",3)); + free_ldapsearchfilter(f); f=0; + callocfail=1; assert(scan_ldapsearchfilter(buf, buf+100, &f) == 0); // fail04 + callocfail=(size_t)-1; + buf[1]=0x7e; assert(scan_ldapsearchfilter(buf, buf+100, &f)==0); // fail03 + buf[0]=0x27; assert(scan_ldapsearchfilter(buf, buf+100, &f)==0); // middle fail02 + buf[0]=0x8a; assert(scan_ldapsearchfilter(buf, buf+100, &f)==0); // right fail02 + buf[0]=0x00; assert(scan_ldapsearchfilter(buf, buf+100, &f)==0); // left fail02 + buf[0]=0x1f; assert(scan_ldapsearchfilter(buf, buf+1, &f)==0); // fail01 + + // type 2, NOT + strcpy(buf,"\xa2\x05\x87\x03""foo"); + assert(scan_ldapsearchfilter(buf, buf+100, &f) == 7); // "(!(foo=*))" (NOT + PRESENT) + assert(f && f->type==NOT && f->x->type==PRESENT); + free_ldapsearchfilter(f); f=0; + buf[1]=6; assert(scan_ldapsearchfilter(buf, buf+100, &f) == 0); // fail07 + buf[1]=5; + buf[2]=0x00; assert(scan_ldapsearchfilter(buf, buf+100, &f) == 0); // fail06 + + buf[0]=0xa9; assert(scan_ldapsearchfilter(buf, buf+100, &f) == 0); // type 9 (extensibleMatch) not implemented, should be rejected, fail14 + + // type 1, OR + strcpy(buf,"\xa1\x0d\x87\5danke\x87\4text"); + assert(scan_ldapsearchfilter(buf, buf+100, &f) == 15); + assert(f && f->type==OR && f->x->type==PRESENT && f->x->next->type==PRESENT); + free_ldapsearchfilter(f); f=0; + buf[1]=0xc; assert(scan_ldapsearchfilter(buf, buf+100, &f) == 0); // fail05 + buf[1]=0xd; buf[0]=0xa0; assert(scan_ldapsearchfilter(buf, buf+100, &f) == 15); // type 0, AND + assert(f && f->type==AND && f->x->type==PRESENT && f->x->next->type==PRESENT); + free_ldapsearchfilter(f); f=0; + + // type 3, equalityMatch + strcpy(buf,"\xa3\x06\x04\x01x\x04\x01y"); + assert(scan_ldapsearchfilter(buf, buf+100, &f) == 8); + assert(f && f->type==EQUAL && f->ava.desc.l==1 && f->ava.desc.s[0]=='x' && + f->ava.value.l==1 && f->ava.value.s[0]=='y'); + free_ldapsearchfilter(f); f=0; + // this also achieves 100% coverge of scan_ldapava: + buf[1]=5; assert(scan_ldapsearchfilter(buf, buf+100, &f) == 0); // fail08, fail 2 in scan_ldapava + buf[1]=2; assert(scan_ldapsearchfilter(buf, buf+100, &f) == 0); // fail08, fail 1 in scan_ldapava + + // type 5, greaterOrEqual + strcpy(buf,"\xa5\x06\x04\x01x\x04\x01y"); + assert(scan_ldapsearchfilter(buf, buf+100, &f) == 8); + assert(f && f->type==GREATEQUAL && f->ava.desc.l==1 && f->ava.desc.s[0]=='x' && + f->ava.value.l==1 && f->ava.value.s[0]=='y'); + free_ldapsearchfilter(f); f=0; + + // type 6, lessOrEqual + strcpy(buf,"\xa6\x06\x04\x01x\x04\x01y"); + assert(scan_ldapsearchfilter(buf, buf+100, &f) == 8); + assert(f && f->type==LESSEQUAL && f->ava.desc.l==1 && f->ava.desc.s[0]=='x' && + f->ava.value.l==1 && f->ava.value.s[0]=='y'); + free_ldapsearchfilter(f); f=0; + + // type 8, approxMatch + strcpy(buf,"\xa8\x06\x04\x01x\x04\x01y"); + assert(scan_ldapsearchfilter(buf, buf+100, &f) == 8); + assert(f && f->type==APPROX && f->ava.desc.l==1 && f->ava.desc.s[0]=='x' && + f->ava.value.l==1 && f->ava.value.s[0]=='y'); + free_ldapsearchfilter(f); f=0; + + // type 4, substrings + strcpy(buf,"\xa4\x0e\x04\5danke\x30\x05\x82\3red"); // "(danke=*red)" + assert(scan_ldapsearchfilter(buf, buf+100, &f) == 16); + assert(f && f->type==SUBSTRING && f->ava.desc.l==5 && !memcmp(f->ava.desc.s,"danke",5) && + f->substrings->substrtype==suffix && f->substrings->s.l==3 && !memcmp(f->substrings->s.s,"red",3) && + f->substrings->next==0); + free_ldapsearchfilter(f); f=0; + callocfail=2; + assert(scan_ldapsearchfilter(buf, buf+100, &f) == 0); // fail11 + callocfail=(size_t)-1; + buf[12]=4; assert(scan_ldapsearchfilter(buf, buf+100, &f) == 0); // fail12 + buf[10]++; assert(scan_ldapsearchfilter(buf, buf+100, &f) == 0); // fail10 + buf[3]=100; assert(scan_ldapsearchfilter(buf, buf+100, &f) == 0); // fail09 + + return 0; +} +#endif diff --git a/scan_ldapstring.c b/scan_ldapstring.c index c6054ee..d570b9b 100644 --- a/scan_ldapstring.c +++ b/scan_ldapstring.c @@ -3,3 +3,24 @@ size_t scan_ldapstring(const char* src,const char* max,struct string* s) { return scan_asn1STRING(src,max,&s->s,&s->l); } + +#ifdef UNITTEST +#include + +#undef UNITTEST +#include "scan_asn1STRING.c" +#include "scan_asn1tag.c" +#include "scan_asn1tagint.c" +#include "scan_asn1length.c" +#include "scan_asn1string.c" + +/* scan_asn1string already has 100% coverage */ + +int main() { + static char buf[]="\x04\x05""fnord"; + struct string s = { 0 }; + assert(scan_ldapstring(buf,buf+7,&s)==7 && s.l==5 && s.s==buf+2); + // we only care for 100% coverage of this file, the others have their own unit tests */ + return 0; +} +#endif