Browse Source

improve range check

master
Felix von Leitner 18 years ago
parent
commit
1c8392ab3e
3 changed files with 30 additions and 6 deletions
  1. +7
    -3
      scan/scan_ulong.c
  2. +7
    -3
      scan/scan_ulonglong.c
  3. +16
    -0
      test/scan.c

+ 7
- 3
scan/scan_ulong.c View File

@ -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;


+ 7
- 3
scan/scan_ulonglong.c View File

@ -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
- 0
test/scan.c View 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…
Cancel
Save