Commit be6c7fa5 authored by Thomas Haller's avatar Thomas Haller

libnm: cleanup _nm_utils_hexstr2bin*() helper

Add 3 variants of _nm_utils_hexstr2bin*():

  - _nm_utils_hexstr2bin_full(), which takes a preallocated
    buffer and fills it.
  - _nm_utils_hexstr2bin_alloc() which returns a malloc'ed
    buffer
  - _nm_utils_hexstr2bin_buf(), which fills a preallocated
    buffer of a specific size.
parent b537c038
......@@ -214,13 +214,25 @@ const char *nm_utils_hwaddr_ntoa_buf (gconstpointer addr, gsize addr_len, gboole
char *_nm_utils_bin2hexstr_full (gconstpointer addr, gsize length, const char delimiter, gboolean upper_case, char *out);
guint8 *_nm_utils_hexstr2bin_full (const char *asc,
guint8 *_nm_utils_hexstr2bin_full (const char *hexstr,
gboolean allow_0x_prefix,
gboolean delimiter_required,
const char *delimiter_candidates,
gsize required_len,
guint8 *buffer,
gsize buffer_length,
gsize buffer_len,
gsize *out_len);
#define _nm_utils_hexstr2bin_buf(hexstr, allow_0x_prefix, delimiter_required, delimiter_candidates, buffer) \
_nm_utils_hexstr2bin_full ((hexstr), (allow_0x_prefix), (delimiter_required), (delimiter_candidates), G_N_ELEMENTS (buffer), (buffer), G_N_ELEMENTS (buffer), NULL)
guint8 *_nm_utils_hexstr2bin_alloc (const char *hexstr,
gboolean allow_0x_prefix,
gboolean delimiter_required,
const char *delimiter_candidates,
gsize required_len,
gsize *out_len);
GSList * _nm_utils_hash_values_to_slist (GHashTable *hash);
GHashTable *_nm_utils_copy_strdict (GHashTable *strdict);
......
......@@ -3527,60 +3527,68 @@ nm_utils_hwaddr_len (int type)
}
guint8 *
_nm_utils_hexstr2bin_full (const char *asc,
_nm_utils_hexstr2bin_full (const char *hexstr,
gboolean allow_0x_prefix,
gboolean delimiter_required,
const char *delimiter_candidates,
gsize required_len,
guint8 *buffer,
gsize buffer_length,
gsize buffer_len,
gsize *out_len)
{
const char *in = asc;
const char *in = hexstr;
guint8 *out = buffer;
gboolean delimiter_has = TRUE;
guint8 delimiter = '\0';
gsize len;
nm_assert (asc);
nm_assert (hexstr);
nm_assert (buffer);
nm_assert (buffer_length);
nm_assert (out_len);
nm_assert (required_len > 0 || out_len);
if ( allow_0x_prefix
&& in[0] == '0'
&& in[1] == 'x')
in += 2;
while (TRUE) {
const guint8 d1 = in[0];
guint8 d2;
int i1, i2;
if (!g_ascii_isxdigit (d1))
return NULL;
#define HEXVAL(c) ((c) <= '9' ? (c) - '0' : ((c) & 0x4F) - ('A' - 10))
i1 = nm_utils_hexchar_to_int (d1);
if (i1 < 0)
goto fail;
/* If there's no leading zero (ie "aa:b:cc") then fake it */
d2 = in[1];
if (d2 && g_ascii_isxdigit (d2)) {
*out++ = (HEXVAL (d1) << 4) + HEXVAL (d2);
if ( d2
&& (i2 = nm_utils_hexchar_to_int (d2)) >= 0) {
*out++ = (i1 << 4) + i2;
d2 = in[2];
if (!d2)
break;
in += 2;
} else {
/* Fake leading zero */
*out++ = HEXVAL (d1);
*out++ = i1;
if (!d2) {
if (!delimiter_has) {
/* when using no delimiter, there must be pairs of hex chars */
return NULL;
goto fail;
}
break;
}
in += 1;
}
if (--buffer_length == 0)
return NULL;
if (--buffer_len == 0)
goto fail;
if (delimiter_has) {
if (d2 != delimiter) {
if (delimiter)
return NULL;
goto fail;
if (delimiter_candidates) {
while (delimiter_candidates[0]) {
if (delimiter_candidates++[0] == d2)
......@@ -3589,7 +3597,7 @@ _nm_utils_hexstr2bin_full (const char *asc,
}
if (!delimiter) {
if (delimiter_required)
return NULL;
goto fail;
delimiter_has = FALSE;
continue;
}
......@@ -3598,11 +3606,66 @@ _nm_utils_hexstr2bin_full (const char *asc,
}
}
*out_len = out - buffer;
return buffer;
len = out - buffer;
if ( required_len == 0
|| len == required_len) {
NM_SET_OUT (out_len, len);
return buffer;
}
fail:
NM_SET_OUT (out_len, 0);
return NULL;
}
#define hwaddr_aton(asc, buffer, buffer_length, out_len) _nm_utils_hexstr2bin_full ((asc), TRUE, ":-", (buffer), (buffer_length), (out_len))
guint8 *
_nm_utils_hexstr2bin_alloc (const char *hexstr,
gboolean allow_0x_prefix,
gboolean delimiter_required,
const char *delimiter_candidates,
gsize required_len,
gsize *out_len)
{
guint8 *buffer;
gsize buffer_len, len;
g_return_val_if_fail (hexstr, NULL);
nm_assert (required_len > 0 || out_len);
if ( allow_0x_prefix
&& hexstr[0] == '0'
&& hexstr[1] == 'x')
hexstr += 2;
if (!hexstr[0])
goto fail;
if (required_len > 0)
buffer_len = required_len;
else
buffer_len = strlen (hexstr) / 2 + 3;
buffer = g_malloc (buffer_len);
if (_nm_utils_hexstr2bin_full (hexstr,
FALSE,
delimiter_required,
delimiter_candidates,
required_len,
buffer,
buffer_len,
&len)) {
NM_SET_OUT (out_len, len);
return buffer;
}
g_free (buffer);
fail:
NM_SET_OUT (out_len, 0);
return NULL;
}
/**
* nm_utils_hexstr2bin:
......@@ -3619,23 +3682,17 @@ GBytes *
nm_utils_hexstr2bin (const char *hex)
{
guint8 *buffer;
gsize buffer_length, len;
g_return_val_if_fail (hex != NULL, NULL);
if (hex[0] == '0' && hex[1] == 'x')
hex += 2;
gsize len;
buffer_length = strlen (hex) / 2 + 3;
buffer = g_malloc (buffer_length);
if (!_nm_utils_hexstr2bin_full (hex, FALSE, ":", buffer, buffer_length, &len)) {
g_free (buffer);
buffer = _nm_utils_hexstr2bin_alloc (hex, TRUE, FALSE, ":", 0, &len);
if (!buffer)
return NULL;
}
buffer = g_realloc (buffer, len);
return g_bytes_new_take (buffer, len);
}
#define hwaddr_aton(asc, buffer, buffer_len, out_len) _nm_utils_hexstr2bin_full ((asc), FALSE, TRUE, ":-", 0, (buffer), (buffer_len), (out_len))
/**
* nm_utils_hwaddr_atoba:
* @asc: the ASCII representation of a hardware address
......@@ -4514,7 +4571,7 @@ _nm_utils_dhcp_duid_valid (const char *duid, GBytes **out_duid_bin)
return TRUE;
}
if (_nm_utils_hexstr2bin_full (duid, FALSE, ":", duid_arr, sizeof (duid_arr), &duid_len)) {
if (_nm_utils_hexstr2bin_full (duid, FALSE, FALSE, ":", 0, duid_arr, sizeof (duid_arr), &duid_len)) {
/* MAX DUID length is 128 octects + the type code (2 octects). */
if ( duid_len > 2
&& duid_len <= (128 + 2)) {
......
......@@ -189,7 +189,7 @@ _secret_password_raw_to_bytes (const char *ifcfg_key,
password_raw += 2;
secret = nm_secret_buf_new (strlen (password_raw) / 2 + 3);
if (!_nm_utils_hexstr2bin_full (password_raw, FALSE, ":", secret->bin, secret->len, &len)) {
if (!_nm_utils_hexstr2bin_full (password_raw, FALSE, FALSE, ":", 0, secret->bin, secret->len, &len)) {
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
"Invalid hex password in %s",
ifcfg_key);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment