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.
This commit is contained in:
@@ -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;
|
||||
gsize len;
|
||||
|
||||
g_return_val_if_fail (hex != NULL, NULL);
|
||||
|
||||
if (hex[0] == '0' && hex[1] == 'x')
|
||||
hex += 2;
|
||||
|
||||
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);
|
||||
|
Reference in New Issue
Block a user