Simplify s_char_to_int and align DECODE_V macro #804

Open
opened 2026-09-03 07:29:49 -05:00 by headscott · 0 comments
headscott commented 2026-09-03 07:29:49 -05:00 (Migrated from github.com)

The current implementation uses a switch with ten cases:

static LTC_INLINE int s_char_to_int(unsigned char x)
{
   switch (x)  {
      case '0': return 0;
      case '1': return 1;
      case '2': return 2;
      case '3': return 3;
      case '4': return 4;
      case '5': return 5;
      case '6': return 6;
      case '7': return 7;
      case '8': return 8;
      case '9': return 9;
      default:  return 100;
   }
}

This could be simplified to a range check and subtraction:

static LTC_INLINE int s_char_to_int(unsigned char x)
{
   if(x < '0' || '9' < x)
      return 100;
   return (int) x - '0';
}

This is shorter, clearer, and should be equally efficient. If you simplify it like that, remember to do so in src/pk/asn1/der/utctime/der_decode_utctime.c but also in src/pk/asn1/der/generalizedtime/der_decode_generalizedtime.c

You could also align the definition of DECODE_V in der_decode_utctime.c with the one in der_decode_generalizedtime.c by wrapping it in do { ... } while (0):
From:

#define DECODE_V(y, max) \
   if (x + 2 > declen) return CRYPT_INVALID_PACKET;     \
   y  = s_char_to_int(buf[x])*10 + s_char_to_int(buf[x+1]); \
   if (y >= max) return CRYPT_INVALID_PACKET;           \
   x += 2;

To:

#define DECODE_V(y, max) do {\
   if (x + 2 > declen) return CRYPT_INVALID_PACKET; \
   y  = s_char_to_int(buf[x])*10 + s_char_to_int(buf[x+1]); \
   if (y >= max) return CRYPT_INVALID_PACKET;           \
   x += 2; \
} while(0)
The current implementation uses a switch with ten cases: ```c static LTC_INLINE int s_char_to_int(unsigned char x) { switch (x) { case '0': return 0; case '1': return 1; case '2': return 2; case '3': return 3; case '4': return 4; case '5': return 5; case '6': return 6; case '7': return 7; case '8': return 8; case '9': return 9; default: return 100; } } ``` This could be simplified to a range check and subtraction: ```c static LTC_INLINE int s_char_to_int(unsigned char x) { if(x < '0' || '9' < x) return 100; return (int) x - '0'; } ``` This is shorter, clearer, and should be equally efficient. If you simplify it like that, remember to do so in [src/pk/asn1/der/utctime/der_decode_utctime.c](https://github.com/libtom/libtomcrypt/blob/6c6d5104de66f3ca0dfd7b68540ef86869982b07/src/pk/asn1/der/utctime/der_decode_utctime.c#L14) but also in [src/pk/asn1/der/generalizedtime/der_decode_generalizedtime.c](https://github.com/libtom/libtomcrypt/blob/6c6d5104de66f3ca0dfd7b68540ef86869982b07/src/pk/asn1/der/generalizedtime/der_decode_generalizedtime.c#L15) You could also align the definition of `DECODE_V` in `der_decode_utctime.c` with the one in `der_decode_generalizedtime.c` by wrapping it in `do { ... } while (0`): From: ```c #define DECODE_V(y, max) \ if (x + 2 > declen) return CRYPT_INVALID_PACKET; \ y = s_char_to_int(buf[x])*10 + s_char_to_int(buf[x+1]); \ if (y >= max) return CRYPT_INVALID_PACKET; \ x += 2; ``` To: ```c #define DECODE_V(y, max) do {\ if (x + 2 > declen) return CRYPT_INVALID_PACKET; \ y = s_char_to_int(buf[x])*10 + s_char_to_int(buf[x+1]); \ if (y >= max) return CRYPT_INVALID_PACKET; \ x += 2; \ } while(0) ```
Sign in to join this conversation.
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
gh-libtom/libtomcrypt#804
No description provided.