improve range check
This commit is contained in:
parent
674a60b278
commit
7f3c1ccc0c
@ -5,9 +5,13 @@ unsigned int scan_ulong(const char* src,unsigned long int* dest) {
|
||||
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;
|
||||
unsigned long int n;
|
||||
/* division is very slow on most architectures */
|
||||
n=l<<3; if ((n>>3)!=l) break;
|
||||
if (n+(l<<1) < n) break;
|
||||
n+=l<<1;
|
||||
if (n+c < n) break;
|
||||
l=n+c;
|
||||
++tmp;
|
||||
}
|
||||
*dest=l;
|
||||
|
@ -5,9 +5,13 @@ unsigned int scan_ulonglong(const char *src,unsigned long long *dest) {
|
||||
register unsigned long long l=0;
|
||||
register unsigned char c;
|
||||
while ((c=*tmp-'0')<10) {
|
||||
unsigned long long m=l;
|
||||
l=l*10+c;
|
||||
if ((l>>3) < m) break;
|
||||
unsigned long long n;
|
||||
/* division is very slow on most architectures */
|
||||
n=l<<3; if ((n>>3)!=l) break;
|
||||
if (n+(l<<1) < n) break;
|
||||
n+=l<<1;
|
||||
if (n+c < n) break;
|
||||
l=n+c;
|
||||
++tmp;
|
||||
}
|
||||
*dest=l;
|
||||
|
16
test/scan.c
Normal file
16
test/scan.c
Normal file
@ -0,0 +1,16 @@
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
#include "scan.h"
|
||||
|
||||
int main() {
|
||||
unsigned long l;
|
||||
char buf[100];
|
||||
assert(scan_ulong("12345",&l)==5 && l==12345);
|
||||
assert(scan_ulong("-12345",&l)==0);
|
||||
assert(scan_ulong("4294967295",&l)==10 && l==4294967295ul);
|
||||
if (sizeof(unsigned long)==4) {
|
||||
assert(scan_ulong("4294967296",&l)==9 && l==429496729);
|
||||
assert(scan_ulong("42949672950",&l)==10 && l==4294967295ul);
|
||||
assert(scan_ulong("5294967295",&l)==9 && l==529496729);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user