Commit da8b97878517587906a81dce0beb6c911558f38e

Steffen Jaeckel 2019-10-28T15:29:30

Merge pull request #426 from libtom/rework-read-radix mp_read_radix and mp_fread should behave the same

diff --git a/mp_fread.c b/mp_fread.c
index 34dd1e7..767e5a3 100644
--- a/mp_fread.c
+++ b/mp_fread.c
@@ -8,15 +8,19 @@
 mp_err mp_fread(mp_int *a, int radix, FILE *stream)
 {
    mp_err err;
-   mp_sign neg;
+   mp_sign neg = MP_ZPOS;
+   int ch;
+
+   /* make sure the radix is ok */
+   if ((radix < 2) || (radix > 64)) {
+      return MP_VAL;
+   }
 
    /* if first digit is - then set negative */
-   int ch = fgetc(stream);
+   ch = fgetc(stream);
    if (ch == (int)'-') {
       neg = MP_NEG;
       ch = fgetc(stream);
-   } else {
-      neg = MP_ZPOS;
    }
 
    /* no digits, return error */
@@ -29,7 +33,9 @@ mp_err mp_fread(mp_int *a, int radix, FILE *stream)
 
    do {
       int y;
-      unsigned pos = (unsigned)(ch - (int)'(');
+      unsigned pos;
+      ch = (radix <= 36) ? MP_TOUPPER(ch) : ch;
+      pos = (unsigned)(ch - (int)'(');
       if (MP_RMAP_REVERSE_SIZE < pos) {
          break;
       }
@@ -49,7 +55,7 @@ mp_err mp_fread(mp_int *a, int radix, FILE *stream)
       }
    } while ((ch = fgetc(stream)) != EOF);
 
-   if (a->used != 0) {
+   if (!mp_iszero(a)) {
       a->sign = neg;
    }
 
diff --git a/mp_read_radix.c b/mp_read_radix.c
index 0e4f848..d4a3d1e 100644
--- a/mp_read_radix.c
+++ b/mp_read_radix.c
@@ -3,19 +3,11 @@
 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
 /* SPDX-License-Identifier: Unlicense */
 
-#define MP_TOUPPER(c) ((((c) >= 'a') && ((c) <= 'z')) ? (((c) + 'A') - 'a') : (c))
-
 /* read a string [ASCII] in a given radix */
 mp_err mp_read_radix(mp_int *a, const char *str, int radix)
 {
    mp_err   err;
-   int      y;
-   mp_sign  neg;
-   unsigned pos;
-   char     ch;
-
-   /* zero the digit bignum */
-   mp_zero(a);
+   mp_sign  neg = MP_ZPOS;
 
    /* make sure the radix is ok */
    if ((radix < 2) || (radix > 64)) {
@@ -28,8 +20,6 @@ mp_err mp_read_radix(mp_int *a, const char *str, int radix)
    if (*str == '-') {
       ++str;
       neg = MP_NEG;
-   } else {
-      neg = MP_ZPOS;
    }
 
    /* set the integer to the default of zero */
@@ -41,8 +31,9 @@ mp_err mp_read_radix(mp_int *a, const char *str, int radix)
        * this allows numbers like 1AB and 1ab to represent the same  value
        * [e.g. in hex]
        */
-      ch = (radix <= 36) ? (char)MP_TOUPPER((int)*str) : *str;
-      pos = (unsigned)(ch - '(');
+      int y;
+      char ch = (radix <= 36) ? (char)MP_TOUPPER((int)*str) : *str;
+      unsigned pos = (unsigned)(ch - '(');
       if (MP_RMAP_REVERSE_SIZE < pos) {
          break;
       }
@@ -66,7 +57,6 @@ mp_err mp_read_radix(mp_int *a, const char *str, int radix)
 
    /* if an illegal character was found, fail. */
    if (!((*str == '\0') || (*str == '\r') || (*str == '\n'))) {
-      mp_zero(a);
       return MP_VAL;
    }
 
diff --git a/tommath_private.h b/tommath_private.h
index 2dbdca8..0f5ac93 100644
--- a/tommath_private.h
+++ b/tommath_private.h
@@ -146,6 +146,8 @@ extern void MP_FREE(void *mem, size_t size);
 #define MP_MIN(x, y) (((x) < (y)) ? (x) : (y))
 #define MP_MAX(x, y) (((x) > (y)) ? (x) : (y))
 
+#define MP_TOUPPER(c) ((((c) >= 'a') && ((c) <= 'z')) ? (((c) + 'A') - 'a') : (c))
+
 /* Static assertion */
 #define MP_STATIC_ASSERT(msg, cond) typedef char mp_static_assert_##msg[(cond) ? 1 : -1];