diff options
author | Rich Felker <dalias@aerifal.cx> | 2011-07-14 22:11:00 -0400 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2011-07-14 22:11:00 -0400 |
commit | 47d027ee1a44829819c345287623fe75374893ab (patch) | |
tree | 6a44b7e7c915496ea8bbefa66c91c4db5e97afa0 /src/internal/intparse.c | |
parent | d3fd192523db544e6005051f224a2d7bafabedd9 (diff) | |
download | musl-47d027ee1a44829819c345287623fe75374893ab.tar.gz musl-47d027ee1a44829819c345287623fe75374893ab.tar.bz2 musl-47d027ee1a44829819c345287623fe75374893ab.tar.xz musl-47d027ee1a44829819c345287623fe75374893ab.zip |
fix various bugs in new integer parser framework
1. my interpretation of subject sequence definition was wrong. adjust
parser to conform to the standard.
2. some code for handling tail overflow case was missing (forgot to
finish writing it).
3. typo (= instead of ==) caused ERANGE to wrongly behave like EINVAL
Diffstat (limited to 'src/internal/intparse.c')
-rw-r--r-- | src/internal/intparse.c | 11 |
1 files changed, 7 insertions, 4 deletions
diff --git a/src/internal/intparse.c b/src/internal/intparse.c index 21b07b74..fd403b58 100644 --- a/src/internal/intparse.c +++ b/src/internal/intparse.c @@ -35,6 +35,7 @@ int __intparse(struct intparse *v, const void *buf, size_t n) v->cnt += n; for (; n; n--, s++) switch (v->state) { case 0: + v->err = EINVAL; v->state++; if (*s=='+' || *s=='-') { v->neg = *s=='-'; @@ -49,6 +50,7 @@ int __intparse(struct intparse *v, const void *buf, size_t n) case 2: v->state++; if ((!b || b==16) && (*s|32) == 'x') { + v->err = 0; v->base = b = 16; continue; } @@ -57,10 +59,11 @@ int __intparse(struct intparse *v, const void *buf, size_t n) case 3: firstdigit: if (digits[*s] >= b) { - v->err = EINVAL; - return 0; + n++; + goto finished; } seconddigit: + v->err = 0; v->state++; case 4: if (b==10) { @@ -92,11 +95,11 @@ int __intparse(struct intparse *v, const void *buf, size_t n) if (n && digits[*s]<b) { v->err = ERANGE; v->val = UINTMAX_MAX; - n--; s++; + for (; n && digits[*s]<b; n--, s++); } - for (; n && digits[*s]<b; n--, s++); if (!n) return 1; + goto finished; } return 1; finished: |