summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2022-12-14 10:37:10 +0100
committerThomas Haller <thaller@redhat.com>2022-12-19 11:29:16 +0100
commitb23c505fca64718bcb28d76d5884110ae64461cb (patch)
treeb91343e21eb72a8c0d5a16e22a9626b996ddf670
parentdf0408f0f6a9c38e8c9a4aed43efa02cb23de9b6 (diff)
downloadNetworkManager-b23c505fca64718bcb28d76d5884110ae64461cb.tar.gz
glib-aux: add "with_leading_zero" to nm_utils_bin2hexstr_full()
dhclient writes binary data as colon-separated hex strings like nm_utils_bin2hexstr_full() does. But it only writes single digits for values smaller than 0x10. Add an option to support that mode. However, there are many callers of nm_utils_bin2hexstr_full() already, and they all don't care about the new option. Maybe this should this not be a boolean argument, instead the function should accept a flags argument. That is not done for now. Just add another "fuller" variant. It's still easy to understand, because the "full" variant is just a more limited functionality of "fuller".
-rw-r--r--src/libnm-glib-aux/nm-shared-utils.c47
-rw-r--r--src/libnm-glib-aux/nm-shared-utils.h21
2 files changed, 45 insertions, 23 deletions
diff --git a/src/libnm-glib-aux/nm-shared-utils.c b/src/libnm-glib-aux/nm-shared-utils.c
index c703495e71..d2e989841f 100644
--- a/src/libnm-glib-aux/nm-shared-utils.c
+++ b/src/libnm-glib-aux/nm-shared-utils.c
@@ -4368,7 +4368,7 @@ nm_utils_memeqzero(gconstpointer data, gsize length)
}
/**
- * nm_utils_bin2hexstr_full:
+ * nm_utils_bin2hexstr_fuller:
* @addr: pointer of @length bytes. If @length is zero, this may
* also be %NULL.
* @length: number of bytes in @addr. May also be zero, in which
@@ -4376,12 +4376,17 @@ nm_utils_memeqzero(gconstpointer data, gsize length)
* @delimiter: either '\0', otherwise the output string will have the
* given delimiter character between each two hex numbers.
* @upper_case: if TRUE, use upper case ASCII characters for hex.
+ * @with_leading_zero: if TRUE, then the hex values from 0 to 0xf
+ * are written as "00" to "0f", respectively. Otherwise, the leading
+ * zero is dropped. With @with_leading_zero set to FALSE, the resulting
+ * string may be shorter than expected. @delimiter must be set
+ * if @with_leading_zero is FALSE.
* @out: if %NULL, the function will allocate a new buffer of
- * either (@length*2+1) or (@length*3) bytes, depending on whether
+ * either (@length*2+1) or MAX(1, (@length*3)) bytes, depending on whether
* a @delimiter is specified. In that case, the allocated buffer will
* be returned and must be freed by the caller.
* If not %NULL, the buffer must already be preallocated and contain
- * at least (@length*2+1) or (@length*3) bytes, depending on the delimiter.
+ * at least (@length*2+1) or MAX(1, (@length*3)) bytes, depending on the delimiter.
* If @length is zero, then of course at least one byte will be allocated
* or @out (if given) must contain at least room for the trailing NUL byte.
*
@@ -4391,37 +4396,43 @@ nm_utils_memeqzero(gconstpointer data, gsize length)
* an empty string is returned.
*/
char *
-nm_utils_bin2hexstr_full(gconstpointer addr,
- gsize length,
- char delimiter,
- gboolean upper_case,
- char *out)
+nm_utils_bin2hexstr_fuller(gconstpointer addr,
+ gsize length,
+ char delimiter,
+ gboolean upper_case,
+ gboolean with_leading_zero,
+ char *out)
{
const guint8 *in = addr;
const char *LOOKUP = upper_case ? "0123456789ABCDEF" : "0123456789abcdef";
char *out0;
- if (out)
- out0 = out;
- else {
- out0 = out =
- g_new(char, length == 0 ? 1u : (delimiter == '\0' ? length * 2u + 1u : length * 3u));
- }
+ nm_assert(with_leading_zero || delimiter != '\0');
- /* @out must contain at least @length*3 bytes if @delimiter is set,
+ /* @out must contain at least (MAX(1, @length*3)) bytes if @delimiter is set,
* otherwise, @length*2+1. */
+ if (!out)
+ out = g_new(char, length == 0 ? 1u : (delimiter == '\0' ? length * 2u + 1u : length * 3u));
+
+ out0 = out;
+
if (length > 0) {
nm_assert(in);
for (;;) {
const guint8 v = *in++;
+ guint8 v_hi;
- *out++ = LOOKUP[v >> 4];
+ v_hi = (v >> 4);
+ if (v_hi != 0 || with_leading_zero) {
+ nm_assert(v_hi < 16);
+ *out++ = LOOKUP[v_hi];
+ }
*out++ = LOOKUP[v & 0x0F];
length--;
- if (!length)
+ if (length == 0)
break;
- if (delimiter)
+ if (delimiter != '\0')
*out++ = delimiter;
}
}
diff --git a/src/libnm-glib-aux/nm-shared-utils.h b/src/libnm-glib-aux/nm-shared-utils.h
index b65d9e93d0..044f34abf0 100644
--- a/src/libnm-glib-aux/nm-shared-utils.h
+++ b/src/libnm-glib-aux/nm-shared-utils.h
@@ -2619,11 +2619,22 @@ nm_ascii_is_regular(char ch)
return ch >= ' ' && ch < 127;
}
-char *nm_utils_bin2hexstr_full(gconstpointer addr,
- gsize length,
- char delimiter,
- gboolean upper_case,
- char *out);
+char *nm_utils_bin2hexstr_fuller(gconstpointer addr,
+ gsize length,
+ char delimiter,
+ gboolean upper_case,
+ gboolean with_leading_zero,
+ char *out);
+
+static inline char *
+nm_utils_bin2hexstr_full(gconstpointer addr,
+ gsize length,
+ char delimiter,
+ gboolean upper_case,
+ char *out)
+{
+ return nm_utils_bin2hexstr_fuller(addr, length, delimiter, upper_case, TRUE, out);
+}
char *_nm_utils_bin2hexstr(gconstpointer src, gsize len, int final_len);