diff options
author | Kevin Ryde <user42@zip.com.au> | 2003-11-10 22:58:04 +0100 |
---|---|---|
committer | Kevin Ryde <user42@zip.com.au> | 2003-11-10 22:58:04 +0100 |
commit | 535317545bb0840ead2d0d52dc192ebb9e90c236 (patch) | |
tree | 1ba9df6d34b981762526a61564853ac8ca9ee8d2 /mpf | |
parent | 1ee960fba85f005d5abcca70e60faab8d9d74a75 (diff) | |
download | gmp-535317545bb0840ead2d0d52dc192ebb9e90c236.tar.gz |
* mpf/set_str.c: Don't use memcmp for decimal point testing, just a
loop is enough and avoids any chance of memcmp reading past the end of
the given string.
Diffstat (limited to 'mpf')
-rw-r--r-- | mpf/set_str.c | 21 |
1 files changed, 11 insertions, 10 deletions
diff --git a/mpf/set_str.c b/mpf/set_str.c index e300d8c8c..75af1dacb 100644 --- a/mpf/set_str.c +++ b/mpf/set_str.c @@ -115,7 +115,7 @@ mpf_set_str (mpf_ptr x, const char *str, int base) { size_t str_size; char *s, *begs; - size_t i; + size_t i, j; int c; int negative; char *dotpos = 0; @@ -123,7 +123,6 @@ mpf_set_str (mpf_ptr x, const char *str, int base) int exp_base; const char *point = GMP_DECIMAL_POINT; size_t pointlen = strlen (point); - int point0 = (unsigned char) point[0]; const unsigned char *digit_value; TMP_DECL (marker); @@ -160,8 +159,10 @@ mpf_set_str (mpf_ptr x, const char *str, int base) /* Require at least one digit, possibly after an initial decimal point. */ if (digit_value[c] >= (base == 0 ? 10 : base)) { - if (memcmp (str, point, pointlen) != 0) - return -1; + /* not a digit, must be a decimal point */ + for (i = 0; i < pointlen; i++) + if (str[i] != point[i]) + return -1; if (digit_value[(unsigned char) str[pointlen]] >= (base == 0 ? 10 : base)) return -1; } @@ -196,15 +197,14 @@ mpf_set_str (mpf_ptr x, const char *str, int base) { int dig; - /* Avoid memcmp for the usual case (point is one character). Don't - bother with str+1,point+1,pointlen-1 since those offsets would add - to the code size. */ - if (UNLIKELY (c == point0) - && (LIKELY (pointlen == 1) - || memcmp (str+1, point+1, pointlen-1) == 0)) + for (j = 0; j < pointlen; j++) + if (str[j] != point[j]) + goto not_point; + if (1) { if (dotpos != 0) { + /* already saw a decimal point, another is invalid */ TMP_FREE (marker); return -1; } @@ -214,6 +214,7 @@ mpf_set_str (mpf_ptr x, const char *str, int base) } else { + not_point: dig = digit_value[c]; if (dig >= base) { |