Coverage Report

Created: 2023-03-20 06:28

/src/dropbear/libtommath/bn_mp_read_radix.c
Line
Count
Source (jump to first uncovered line)
1
#include "tommath_private.h"
2
#ifdef BN_MP_READ_RADIX_C
3
/* LibTomMath, multiple-precision integer library -- Tom St Denis */
4
/* SPDX-License-Identifier: Unlicense */
5
6
256
#define MP_TOUPPER(c) ((((c) >= 'a') && ((c) <= 'z')) ? (((c) + 'A') - 'a') : (c))
7
8
/* read a string [ASCII] in a given radix */
9
mp_err mp_read_radix(mp_int *a, const char *str, int radix)
10
4
{
11
4
   mp_err   err;
12
4
   int      y;
13
4
   mp_sign  neg;
14
4
   unsigned pos;
15
4
   char     ch;
16
17
   /* zero the digit bignum */
18
4
   mp_zero(a);
19
20
   /* make sure the radix is ok */
21
4
   if ((radix < 2) || (radix > 64)) {
22
0
      return MP_VAL;
23
0
   }
24
25
   /* if the leading digit is a
26
    * minus set the sign to negative.
27
    */
28
4
   if (*str == '-') {
29
0
      ++str;
30
0
      neg = MP_NEG;
31
4
   } else {
32
4
      neg = MP_ZPOS;
33
4
   }
34
35
   /* set the integer to the default of zero */
36
4
   mp_zero(a);
37
38
   /* process each digit of the string */
39
260
   while (*str != '\0') {
40
      /* if the radix <= 36 the conversion is case insensitive
41
       * this allows numbers like 1AB and 1ab to represent the same  value
42
       * [e.g. in hex]
43
       */
44
256
      ch = (radix <= 36) ? (char)MP_TOUPPER((int)*str) : *str;
45
256
      pos = (unsigned)(ch - '(');
46
256
      if (mp_s_rmap_reverse_sz < pos) {
47
0
         break;
48
0
      }
49
256
      y = (int)mp_s_rmap_reverse[pos];
50
51
      /* if the char was found in the map
52
       * and is less than the given radix add it
53
       * to the number, otherwise exit the loop.
54
       */
55
256
      if ((y == 0xff) || (y >= radix)) {
56
0
         break;
57
0
      }
58
256
      if ((err = mp_mul_d(a, (mp_digit)radix, a)) != MP_OKAY) {
59
0
         return err;
60
0
      }
61
256
      if ((err = mp_add_d(a, (mp_digit)y, a)) != MP_OKAY) {
62
0
         return err;
63
0
      }
64
256
      ++str;
65
256
   }
66
67
   /* if an illegal character was found, fail. */
68
4
   if (!((*str == '\0') || (*str == '\r') || (*str == '\n'))) {
69
0
      mp_zero(a);
70
0
      return MP_VAL;
71
0
   }
72
73
   /* set the sign only if a != 0 */
74
4
   if (!MP_IS_ZERO(a)) {
75
4
      a->sign = neg;
76
4
   }
77
4
   return MP_OKAY;
78
4
}
79
#endif