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,11 +214,23 @@ 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);
|
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,
|
gboolean delimiter_required,
|
||||||
const char *delimiter_candidates,
|
const char *delimiter_candidates,
|
||||||
|
gsize required_len,
|
||||||
guint8 *buffer,
|
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);
|
gsize *out_len);
|
||||||
|
|
||||||
GSList * _nm_utils_hash_values_to_slist (GHashTable *hash);
|
GSList * _nm_utils_hash_values_to_slist (GHashTable *hash);
|
||||||
|
@@ -3527,60 +3527,68 @@ nm_utils_hwaddr_len (int type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
guint8 *
|
guint8 *
|
||||||
_nm_utils_hexstr2bin_full (const char *asc,
|
_nm_utils_hexstr2bin_full (const char *hexstr,
|
||||||
|
gboolean allow_0x_prefix,
|
||||||
gboolean delimiter_required,
|
gboolean delimiter_required,
|
||||||
const char *delimiter_candidates,
|
const char *delimiter_candidates,
|
||||||
|
gsize required_len,
|
||||||
guint8 *buffer,
|
guint8 *buffer,
|
||||||
gsize buffer_length,
|
gsize buffer_len,
|
||||||
gsize *out_len)
|
gsize *out_len)
|
||||||
{
|
{
|
||||||
const char *in = asc;
|
const char *in = hexstr;
|
||||||
guint8 *out = buffer;
|
guint8 *out = buffer;
|
||||||
gboolean delimiter_has = TRUE;
|
gboolean delimiter_has = TRUE;
|
||||||
guint8 delimiter = '\0';
|
guint8 delimiter = '\0';
|
||||||
|
gsize len;
|
||||||
|
|
||||||
nm_assert (asc);
|
nm_assert (hexstr);
|
||||||
nm_assert (buffer);
|
nm_assert (buffer);
|
||||||
nm_assert (buffer_length);
|
nm_assert (required_len > 0 || out_len);
|
||||||
nm_assert (out_len);
|
|
||||||
|
if ( allow_0x_prefix
|
||||||
|
&& in[0] == '0'
|
||||||
|
&& in[1] == 'x')
|
||||||
|
in += 2;
|
||||||
|
|
||||||
while (TRUE) {
|
while (TRUE) {
|
||||||
const guint8 d1 = in[0];
|
const guint8 d1 = in[0];
|
||||||
guint8 d2;
|
guint8 d2;
|
||||||
|
int i1, i2;
|
||||||
|
|
||||||
if (!g_ascii_isxdigit (d1))
|
i1 = nm_utils_hexchar_to_int (d1);
|
||||||
return NULL;
|
if (i1 < 0)
|
||||||
|
goto fail;
|
||||||
#define HEXVAL(c) ((c) <= '9' ? (c) - '0' : ((c) & 0x4F) - ('A' - 10))
|
|
||||||
|
|
||||||
/* If there's no leading zero (ie "aa:b:cc") then fake it */
|
/* If there's no leading zero (ie "aa:b:cc") then fake it */
|
||||||
d2 = in[1];
|
d2 = in[1];
|
||||||
if (d2 && g_ascii_isxdigit (d2)) {
|
if ( d2
|
||||||
*out++ = (HEXVAL (d1) << 4) + HEXVAL (d2);
|
&& (i2 = nm_utils_hexchar_to_int (d2)) >= 0) {
|
||||||
|
*out++ = (i1 << 4) + i2;
|
||||||
d2 = in[2];
|
d2 = in[2];
|
||||||
if (!d2)
|
if (!d2)
|
||||||
break;
|
break;
|
||||||
in += 2;
|
in += 2;
|
||||||
} else {
|
} else {
|
||||||
/* Fake leading zero */
|
/* Fake leading zero */
|
||||||
*out++ = HEXVAL (d1);
|
*out++ = i1;
|
||||||
if (!d2) {
|
if (!d2) {
|
||||||
if (!delimiter_has) {
|
if (!delimiter_has) {
|
||||||
/* when using no delimiter, there must be pairs of hex chars */
|
/* when using no delimiter, there must be pairs of hex chars */
|
||||||
return NULL;
|
goto fail;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
in += 1;
|
in += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (--buffer_length == 0)
|
if (--buffer_len == 0)
|
||||||
return NULL;
|
goto fail;
|
||||||
|
|
||||||
if (delimiter_has) {
|
if (delimiter_has) {
|
||||||
if (d2 != delimiter) {
|
if (d2 != delimiter) {
|
||||||
if (delimiter)
|
if (delimiter)
|
||||||
return NULL;
|
goto fail;
|
||||||
if (delimiter_candidates) {
|
if (delimiter_candidates) {
|
||||||
while (delimiter_candidates[0]) {
|
while (delimiter_candidates[0]) {
|
||||||
if (delimiter_candidates++[0] == d2)
|
if (delimiter_candidates++[0] == d2)
|
||||||
@@ -3589,7 +3597,7 @@ _nm_utils_hexstr2bin_full (const char *asc,
|
|||||||
}
|
}
|
||||||
if (!delimiter) {
|
if (!delimiter) {
|
||||||
if (delimiter_required)
|
if (delimiter_required)
|
||||||
return NULL;
|
goto fail;
|
||||||
delimiter_has = FALSE;
|
delimiter_has = FALSE;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -3598,11 +3606,66 @@ _nm_utils_hexstr2bin_full (const char *asc,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*out_len = out - buffer;
|
len = out - buffer;
|
||||||
|
if ( required_len == 0
|
||||||
|
|| len == required_len) {
|
||||||
|
NM_SET_OUT (out_len, len);
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define hwaddr_aton(asc, buffer, buffer_length, out_len) _nm_utils_hexstr2bin_full ((asc), TRUE, ":-", (buffer), (buffer_length), (out_len))
|
fail:
|
||||||
|
NM_SET_OUT (out_len, 0);
|
||||||
|
return 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)
|
||||||
|
{
|
||||||
|
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:
|
* nm_utils_hexstr2bin:
|
||||||
@@ -3619,23 +3682,17 @@ GBytes *
|
|||||||
nm_utils_hexstr2bin (const char *hex)
|
nm_utils_hexstr2bin (const char *hex)
|
||||||
{
|
{
|
||||||
guint8 *buffer;
|
guint8 *buffer;
|
||||||
gsize buffer_length, len;
|
gsize len;
|
||||||
|
|
||||||
g_return_val_if_fail (hex != NULL, NULL);
|
buffer = _nm_utils_hexstr2bin_alloc (hex, TRUE, FALSE, ":", 0, &len);
|
||||||
|
if (!buffer)
|
||||||
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);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
buffer = g_realloc (buffer, len);
|
buffer = g_realloc (buffer, len);
|
||||||
return g_bytes_new_take (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:
|
* nm_utils_hwaddr_atoba:
|
||||||
* @asc: the ASCII representation of a hardware address
|
* @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;
|
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). */
|
/* MAX DUID length is 128 octects + the type code (2 octects). */
|
||||||
if ( duid_len > 2
|
if ( duid_len > 2
|
||||||
&& duid_len <= (128 + 2)) {
|
&& duid_len <= (128 + 2)) {
|
||||||
|
@@ -189,7 +189,7 @@ _secret_password_raw_to_bytes (const char *ifcfg_key,
|
|||||||
password_raw += 2;
|
password_raw += 2;
|
||||||
|
|
||||||
secret = nm_secret_buf_new (strlen (password_raw) / 2 + 3);
|
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,
|
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
||||||
"Invalid hex password in %s",
|
"Invalid hex password in %s",
|
||||||
ifcfg_key);
|
ifcfg_key);
|
||||||
|
Reference in New Issue
Block a user