100% unit test coverage

This commit is contained in:
leitner
2022-01-08 00:45:08 +00:00
parent 3cb4e4b695
commit 5c30e3ea61
8 changed files with 235 additions and 4 deletions

View File

@@ -25,3 +25,36 @@ size_t scan_asn1BITSTRING(const char* src,const char* max,const char** s,size_t*
}
return 0;
}
#ifdef UNITTEST
#include <string.h>
#include <assert.h>
#undef UNITTEST
#include "scan_asn1tag.c"
#include "scan_asn1tagint.c"
#include "scan_asn1length.c"
#include "scan_asn1string.c"
int main() {
char buf[100];
const char* s;
size_t l;
strcpy(buf,"\x03\x02\x07\x01"); // 0x03 = UNIVERSAL PRIMITIVE BIT_STRING, 0x02 = length 5, 0x07 = unused bits in last octet, 0x01 = 1
assert(scan_asn1BITSTRING(buf,buf+4,&s,&l)==4 && s==buf+2 && l==2);
assert(scan_asn1BITSTRING(buf,buf+3,&s,&l)==0); // short input, make scan_asn1string fail
buf[0]=0x13; // 0x13 = UNIVERSAL PRIMITIVE PrintableString
assert(scan_asn1BITSTRING(buf,buf+4,&s,&l)==0); // scan_asn1string succeeds but line 9 fails
buf[0]=0x03; buf[2]=8;
assert(scan_asn1BITSTRING(buf,buf+4,&s,&l)==0); // scan_asn1string succeeds but line 12 fails
buf[2]=7; buf[1]=0;
assert(scan_asn1BITSTRING(buf,buf+4,&s,&l)==0); // scan_asn1string succeeds but line 11 fails
strcpy(buf,"\x03\x01\x00"); // length 0 bit string
assert(scan_asn1BITSTRING(buf,buf+3,&s,&l)==3 && s==buf+2 && l==1);
buf[2]=1;
assert(scan_asn1BITSTRING(buf,buf+3,&s,&l)==0); // length 0 but says it has unused bits, return 0 in line 17
strcpy(buf,"\x03\x02\x07\x81"); // 0x03 = UNIVERSAL PRIMITIVE BIT_STRING, 0x02 = length 5, 0x07 = unused bits in last octet, 0x01 = 1
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 */
}
#endif

View File

@@ -14,3 +14,30 @@ size_t scan_asn1BOOLEAN(const char* src,const char* max,unsigned long* val) {
}
return 0;
}
#ifdef UNITTEST
#include <string.h>
#include <assert.h>
#undef UNITTEST
#include "scan_asn1tag.c"
#include "scan_asn1tagint.c"
#include "scan_asn1length.c"
#include "scan_asn1rawint.c"
#include "scan_asn1int.c"
int main() {
char buf[100];
unsigned long l;
strcpy(buf,"\x01\x01\x00"); // 0x01 = UNIVERSAL + CONSTRUCTED + BOOLEAN, 0x01 = length 1, 0x00 = false
assert(scan_asn1BOOLEAN(buf,buf+3,&l)==3 && l==0);
assert(scan_asn1BOOLEAN(buf,buf+2,&l)==0); // not enough input
buf[2]=1;
assert(scan_asn1BOOLEAN(buf,buf+3,&l)==3 && l==1);
buf[2]=2;
assert(scan_asn1BOOLEAN(buf,buf+3,&l)==0); // only 0 and 1 are valid values for BOOLEAN
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 */
}
#endif

View File

@@ -13,3 +13,26 @@ size_t scan_asn1ENUMERATED(const char* src,const char* max,unsigned long* val) {
}
return 0;
}
#ifdef UNITTEST
#include <string.h>
#include <assert.h>
#undef UNITTEST
#include "scan_asn1tag.c"
#include "scan_asn1tagint.c"
#include "scan_asn1length.c"
#include "scan_asn1rawint.c"
#include "scan_asn1int.c"
int main() {
char buf[100];
unsigned long l;
strcpy(buf,"\x0a\x01\x17"); // 0x0a = UNIVERSAL + CONSTRUCTED + ENUMERATED, 0x01 = length 1, 0x17 = value
assert(scan_asn1ENUMERATED(buf,buf+3,&l)==3 && l==23);
assert(scan_asn1ENUMERATED(buf,buf+2,&l)==0); // not enough input
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 */
}
#endif

View File

@@ -10,3 +10,43 @@ size_t scan_asn1INTEGER(const char* src,const char* max,signed long* val) {
return tmp;
return 0;
}
#ifdef UNITTEST
#include <string.h>
#include <assert.h>
#undef UNITTEST
#include "scan_asn1tag.c"
#include "scan_asn1tagint.c"
#include "scan_asn1length.c"
#include "scan_asn1rawint.c"
#include "scan_asn1int.c"
int main() {
char buf[100];
unsigned long l;
strcpy(buf,"\x02\x01\x17"); // 0x02 = UNIVERSAL + CONSTRUCTED + INTEGER, 0x01 = length 1, 0x17 = value
assert(scan_asn1INTEGER(buf,buf+3,&l)==3 && l==23);
assert(scan_asn1INTEGER(buf,buf+2,&l)==0); // not enough input
buf[0]=0x01;
assert(scan_asn1INTEGER(buf,buf+3,&l)==0); // 0x01 = BOOLEAN, fails line 9
// we only care for 100% coverage of this file, the others have their own unit tests */
// let's do a few more to leave sample values here
strcpy(buf,"\x02\x01\xff"); // 0x02 = UNIVERSAL + CONSTRUCTED + INTEGER, 0x01 = length 1, 0xff = value (-1)
assert(scan_asn1INTEGER(buf,buf+3,&l)==3 && l==-1);
strcpy(buf,"\x02\x04\x12\x34\x56\x78"); // 0x02 = UNIVERSAL + CONSTRUCTED + INTEGER, 0x01 = length 4, 0x12345678 = value
assert(scan_asn1INTEGER(buf,buf+6,&l)==6 && l==0x12345678);
if (sizeof(l)==8) {
strcpy(buf,"\x02\x08\x11\x22\x33\x44\x55\x66\x77\x88");
assert(scan_asn1INTEGER(buf,buf+10,&l)==10 && l==0x1122334455667788);
strcpy(buf,"\x02\x08\xee\xdd\xcc\xbb\xaa\x99\x88\x78");
assert(scan_asn1INTEGER(buf,buf+10,&l)==10 && l==-0x1122334455667788); // two's complement
strcpy(buf,"\x02\x08\x7f\xff\xff\xff\xff\xff\xff\xff"); // LONG_MAX
assert(scan_asn1INTEGER(buf,buf+10,&l)==10 && l==0x7ffffffffffffffful);
memcpy(buf,"\x02\x08\x80\x00\x00\x00\x00\x00\x00\x00",10); // LONG_MIN
assert(scan_asn1INTEGER(buf,buf+10,&l)==10 && l==-0x8000000000000000ul);
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
}
}
#endif

View File

@@ -12,3 +12,28 @@ size_t scan_asn1SEQUENCE(const char* src,const char* max,size_t* len) {
return res;
return 0;
}
#ifdef UNITTEST
#include <string.h>
#include <assert.h>
#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(buf,buf+3,&l)==2 && l==1);
assert(scan_asn1SEQUENCE(buf,buf,&l)==0); // not enough input, first return 0
assert(scan_asn1SEQUENCE(buf,buf+2,&l)==0); // not enough input, second return 0
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 */
}
#endif

View File

@@ -5,10 +5,37 @@ size_t scan_asn1SET(const char* src,const char* max,size_t* len) {
unsigned long tag;
enum asn1_tagclass tc;
enum asn1_tagtype tt;
if (!(res=scan_asn1tag(src,max,&tc,&tt,&tag))) return 0;
if (!(tmp=scan_asn1length(src+res,max,len))) return 0;
if (!(res=scan_asn1tag(src,max,&tc,&tt,&tag)))
return 0;
if (!(tmp=scan_asn1length(src+res,max,len)))
return 0;
res+=tmp;
if (tc==UNIVERSAL && tt==CONSTRUCTED && tag==SET_OF)
return res;
return 0;
}
#ifdef UNITTEST
#include <string.h>
#include <assert.h>
#undef UNITTEST
#include "scan_asn1tag.c"
#include "scan_asn1tagint.c"
#include "scan_asn1length.c"
int main() {
char buf[100];
size_t l;
strcpy(buf,"\x31\x01\x01"); // 0x31 = UNIVERSAL + CONSTRUCTED + SET_OF, 0x01 = length 1, 0x01 = dummy filler
// this function only parses the header so our test data doesn't need
// to have an actual set, only the header for one. \x01 is not a valid
// set.
assert(scan_asn1SET(buf,buf+3,&l)==2 && l==1);
assert(scan_asn1SET(buf,buf,&l)==0); // not enough input, first return 0
assert(scan_asn1SET(buf,buf+2,&l)==0); // not enough input, second return 0
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 */
}
#endif

View File

@@ -10,3 +10,26 @@ size_t scan_asn1STRING(const char* src,const char* max,const char** s,size_t* l)
return tmp;
return 0;
}
#ifdef UNITTEST
#include <string.h>
#include <assert.h>
#undef UNITTEST
#include "scan_asn1tag.c"
#include "scan_asn1tagint.c"
#include "scan_asn1length.c"
#include "scan_asn1string.c"
int main() {
char buf[100];
const char* s;
size_t l;
strcpy(buf,"\x04\x05""fnord"); // 0x04 = UNIVERSAL PRIMITIVE OCTET_STRING, 0x05 = length 5, "fnord" = the string
assert(scan_asn1STRING(buf,buf+7,&s,&l)==7 && s==buf+2 && l==5);
assert(scan_asn1STRING(buf,buf+6,&s,&l)==0); // short input, make scan_asn1string fail
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 */
}
#endif

View File

@@ -3,9 +3,11 @@
size_t scan_asn1rawoid(const char* src,const char* max,size_t* array,size_t* arraylen) {
const char* orig=src;
size_t cur=0,al;
if (!arraylen) return 0;
if (!arraylen)
return 0;
al=*arraylen; *arraylen=0;
if (max-src<1) return 0; /* there has to be at least one octet */
if (max-src<1)
return 0; /* there has to be at least one octet */
{
int a,b;
@@ -39,3 +41,34 @@ size_t scan_asn1rawoid(const char* src,const char* max,size_t* array,size_t* arr
return src-orig;
}
#ifdef UNITTEST
#include <string.h>
#include <assert.h>
#undef UNITTEST
#include "scan_asn1tagint.c"
int main() {
char buf[100];
size_t retval[10];
size_t retvals=10;
strcpy(buf,"\x55\x04\x03"); // 2.5.4.3 (commonName)
assert(scan_asn1rawoid(buf,buf+3,retval,&retvals)==3 && retvals==4 && retval[0]==2 && retval[1]==5 && retval[2]==4 && retval[3]==3);
retvals=3;
retval[3]=23;
assert(scan_asn1rawoid(buf,buf+3,retval,&retvals)==0); // oid too long for dest array, fail line 40
assert(retval[3]==23); // make sure we didn't clobber sentinel
assert(retvals==4); // make sure it told us how many elements are needed
assert(scan_asn1rawoid(buf,buf+3,retval,0)==0); // *retvals is NULL, fail line 7
strcpy(buf,"\x55\x04\x03"); // 2.5.4.3 (commonName)
retvals=10;
assert(scan_asn1rawoid(buf,buf,retval,&retvals)==0); // src=max, fail line 10
strcpy(buf,"\x55\x04\xff"); // 2.5.4.[invalid]
assert(scan_asn1rawoid(buf,buf+3,retval,&retvals)==0); // scan_asn1tagint fails, fail line 31
strcpy(buf,"\xb4\x04\x03"); // 2.100.4.3
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 */
}
#endif