X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=src%2Finternal%2Fintparse.c;h=fba38c0ac6371370b407ca8eacd40519b52358ca;hb=bef7a85e45ccc4b40958ca6d94894ca0d27e8291;hp=fd403b589320633744d58fff0a17c3c7b366d9d4;hpb=47d027ee1a44829819c345287623fe75374893ab;p=musl diff --git a/src/internal/intparse.c b/src/internal/intparse.c index fd403b58..fba38c0a 100644 --- a/src/internal/intparse.c +++ b/src/internal/intparse.c @@ -25,12 +25,12 @@ static const unsigned char digits[] = { }; #define SLIM (UINT_MAX/36-1) -#define LLIM (UINTMAX_MAX/36-1) int __intparse(struct intparse *v, const void *buf, size_t n) { const unsigned char *s = buf; int d, b = v->base; + uintmax_t llim; v->cnt += n; for (; n; n--, s++) switch (v->state) { @@ -70,6 +70,8 @@ int __intparse(struct intparse *v, const void *buf, size_t n) for (; n && *s-'0'<10U && v->small<=SLIM; n--, s++) v->small = v->small * 10 + (*s-'0'); } else if ((b&-b) == b) { + /* Compute bitshift for power-of-two bases + * using a De Bruijn B(2,3) sequence. */ int bs = "\0\1\2\4\7\3\6\5"[(0x17*b)>>5&7]; for (; n && (d=digits[*s])small<=SLIM; n--, s++) v->small = (v->small<state++; v->val = v->small; case 5: - for (; n && (d=digits[*s])val<=LLIM; n--, s++) - v->val = v->val * b + d; + if (b==10) { + for (; n && *s-'0'<10U && v->val<=UINTMAX_MAX/10 && (*s-'0')<=UINTMAX_MAX-10*v->val; n--, s++) + v->val = v->val * 10 + (*s-'0'); + } else if ((b&-b) == b) { + int bs = "\0\1\2\4\7\3\6\5"[(0x17*b)>>5&7]; + llim = UINTMAX_MAX>>bs; + for (; n && (d=digits[*s])val<=llim; n--, s++) + v->val = (v->val<val<=llim && d<=UINTMAX_MAX-b*v->val; n--, s++) + v->val = v->val * b + d; + } if (!n) return 1; if (d >= b) goto finished; - if (v->val < (UINTMAX_MAX-d)/b) - v->val = v->val * b + d; - else - v->err = ERANGE; v->state++; - n--; s++; case 6: if (n && digits[*s]err = ERANGE;