Rationalise g_htoi() / xrdp_wm_htoi()

xrdp contains two functions which do similar things:-
- g_htoi() converts a hex string to an integer, ignoring unrecognised
  characters
- xrdp_wm_htoi() converts a hex string to an integer, ignoring leading
  whitespace, but terminating on unrecognised characters

An analysis of the uses of g_htoi() shows that the only place where
unrecognised characters might be encountered is parsing lines from
xrdp_keyboard.ini, where all values have an '0x' prefix (i.e. the 'x'
is unrecognised)

An analysis of xrdp_wm_htoi() shows that the functionality to ignore
leading whitespace is not used.

Both functions are replaced with a re-written g_htoi() which is const-
correct and provided with test cases. This function behaves in
the same way as the atoi() library function, in that it terminates on
an unexpected character.

The use of g_htoi() in parsing lines from xrdp_keyboard.ini is replaced
with a call to g_atoix() which handles the '0x' prefix correctly.
This commit is contained in:
matt335672
2025-03-31 15:36:51 +01:00
parent 267443e90d
commit bc0e169451
7 changed files with 82 additions and 135 deletions
+22 -72
View File
@@ -502,82 +502,32 @@ size_t strlcpy(char *dst, const char *src, size_t dsize)
#endif
/*****************************************************************************/
int
g_htoi(char *str)
unsigned int
g_htoi(const char *str)
{
int len;
int index;
int rv;
int val;
int shift;
rv = 0;
len = strlen(str);
index = len - 1;
shift = 0;
while (index >= 0)
unsigned int rv = 0;
while (*str != '\0')
{
val = 0;
switch (str[index])
char c = *str;
unsigned int val;
if (c >= '0' && c <= '9')
{
case '1':
val = 1;
break;
case '2':
val = 2;
break;
case '3':
val = 3;
break;
case '4':
val = 4;
break;
case '5':
val = 5;
break;
case '6':
val = 6;
break;
case '7':
val = 7;
break;
case '8':
val = 8;
break;
case '9':
val = 9;
break;
case 'a':
case 'A':
val = 10;
break;
case 'b':
case 'B':
val = 11;
break;
case 'c':
case 'C':
val = 12;
break;
case 'd':
case 'D':
val = 13;
break;
case 'e':
case 'E':
val = 14;
break;
case 'f':
case 'F':
val = 15;
break;
val = c - '0';
}
rv = rv | (val << shift);
index--;
shift += 4;
else if (c >= 'A' && c <= 'F')
{
val = (c - 'A' + 10);
}
else if (c >= 'a' && c <= 'f')
{
val = (c - 'a' + 10);
}
else
{
break; // Unrecognised character
}
rv = (rv << 4) | val;
++str;
}
return rv;
+9 -1
View File
@@ -310,7 +310,15 @@ size_t strlcpy(char *dst, const char *src, size_t dsize);
* @return int Integer expression of a string
*/
int g_atoix(const char *str);
int g_htoi(char *str);
/**
* Converts a hex string to an integer
* @param str pointer to Hex string containing only hex digits
* @return value, converted from hex
*
* This function is intended to be used as an analogue to the standard
* function atoi(). It performs no error checking of its own
*/
unsigned int g_htoi(const char *str);
int g_bytes_to_hexstr(const void *bytes, int num_bytes, char *out_str,
int bytes_out_str);
int g_pos(const char *str, const char *to_find);