diff --git a/CHANGES b/CHANGES index 69592ab..f3f554a 100644 --- a/CHANGES +++ b/CHANGES @@ -16,6 +16,7 @@ fix typo breaking buffer_GETC in buffer (Marcus Winkler) fix typo breaking fmt_long for dest==NULL add fmt_*longlong() + add range check to scan_ulong, scan_ulonglong 0.14: avoid bus errors in byte_copy diff --git a/scan.h b/scan.h index 41a62f2..60cd562 100644 --- a/scan.h +++ b/scan.h @@ -27,6 +27,11 @@ extern unsigned int scan_8long(const char *src,unsigned long *dest); * and return the number of bytes that were parsed */ extern unsigned int scan_long(const char *src,signed long *dest); +extern unsigned int scan_longlong(const char *src,signed long long *dest); +extern unsigned int scan_ulonglong(const char *src,unsigned long long *dest); +extern unsigned int scan_xlonglong(const char *src,unsigned long long *dest); +extern unsigned int scan_8longlong(const char *src,unsigned long long *dest); + extern unsigned int scan_uint(const char *src,unsigned int *dest); extern unsigned int scan_xint(const char *src,unsigned int *dest); extern unsigned int scan_8int(const char *src,unsigned int *dest); diff --git a/scan/scan_long.c b/scan/scan_long.c index 497c919..53aef1c 100644 --- a/scan/scan_long.c +++ b/scan/scan_long.c @@ -2,7 +2,7 @@ unsigned int scan_long(const char *src,long *dest) { register const char *tmp; - register int l; + register long int l; register unsigned char c; int neg; tmp=src; l=0; neg=0; diff --git a/scan/scan_ulong.c b/scan/scan_ulong.c index 02d3f2b..385f98e 100644 --- a/scan/scan_ulong.c +++ b/scan/scan_ulong.c @@ -1,11 +1,13 @@ #include "scan.h" -unsigned int scan_ulong(const char *src,unsigned long *dest) { +unsigned int scan_ulong(const char* src,unsigned long int* dest) { register const char *tmp=src; - register int l=0; + register unsigned long int l=0; register unsigned char c; while ((c=*tmp-'0')<10) { + unsigned long int m=l; l=l*10+c; + if ((l>>3) < m) break; ++tmp; } *dest=l; diff --git a/test/fmt_longlong.c b/test/fmt_longlong.c index 7a4014e..357d3dd 100644 --- a/test/fmt_longlong.c +++ b/test/fmt_longlong.c @@ -4,18 +4,24 @@ main() { char buf[1024]; + long long l; assert(fmt_longlong(0,12345)==5); assert(fmt_longlong(0,-12345)==6); assert(fmt_longlong(buf,12345)==5); buf[5]=0; assert(str_equal(buf,"12345")); + assert(scan_longlong(buf,&l)==5); assert(l==12345); assert(fmt_longlong(buf,-12345)==6); buf[6]=0; assert(str_equal(buf,"-12345")); + assert(scan_longlong(buf,&l)==6); assert(l==-12345); assert(fmt_longlong(0,1234567890)==10); assert(fmt_longlong(0,-1234567890)==11); assert(fmt_longlong(buf,1234567890)==10); buf[10]=0; assert(str_equal(buf,"1234567890")); + assert(scan_longlong(buf,&l)==10); assert(l==1234567890); + assert(fmt_longlong(buf,-1234567890)==11); buf[11]=0; assert(str_equal(buf,"-1234567890")); + assert(scan_longlong(buf,&l)==11); assert(l==-1234567890); }