summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2017-10-05 14:27:24 +0200
committerThomas Haller <thaller@redhat.com>2017-10-06 11:08:39 +0200
commitf1009bcde35937a7a22cb0c1b73d40e98c37b85a (patch)
treec70056168294ead0462e5ba9c549815f5aa93904
parentdccf9f3a6150a323f2bcb563dc0c068746045135 (diff)
downloadNetworkManager-f1009bcde35937a7a22cb0c1b73d40e98c37b85a.tar.gz
shared: add nm_strquote() util
We already have nm_strquote_a(). That is useful, but uses alloca(), hence it is ill suited to be called from a macro, inside a loop, or from a function that should be inlined. Instead, add nm_strquote() that has the same purpose but writes to a provided string buffer.
-rw-r--r--libnm-core/tests/test-general.c83
-rw-r--r--shared/nm-utils/nm-shared-utils.c72
-rw-r--r--shared/nm-utils/nm-shared-utils.h2
3 files changed, 157 insertions, 0 deletions
diff --git a/libnm-core/tests/test-general.c b/libnm-core/tests/test-general.c
index 08d55555be..257fdad5a1 100644
--- a/libnm-core/tests/test-general.c
+++ b/libnm-core/tests/test-general.c
@@ -4852,6 +4852,88 @@ test_hexstr2bin (void)
/*****************************************************************************/
+static void
+_do_strquote (const char *str, gsize buf_len, const char *expected)
+{
+ char canary = (char) nmtst_get_rand_int ();
+ gs_free char *buf_full = g_malloc (buf_len + 2);
+ char *buf = &buf_full[1];
+ const char *b;
+
+ buf[-1] = canary;
+ buf[buf_len] = canary;
+
+ if (buf_len == 0) {
+ b = nm_strquote (NULL, 0, str);
+ g_assert (b == NULL);
+ g_assert (expected == NULL);
+ b = nm_strquote (buf, 0, str);
+ g_assert (b == buf);
+ } else {
+ b = nm_strquote (buf, buf_len, str);
+ g_assert (b == buf);
+ g_assert (strlen (b) < buf_len);
+ g_assert_cmpstr (expected, ==, b);
+ }
+
+ g_assert (buf[-1] == canary);
+ g_assert (buf[buf_len] == canary);
+}
+
+static void
+test_nm_strquote (void)
+{
+ _do_strquote (NULL, 0, NULL);
+ _do_strquote ("", 0, NULL);
+ _do_strquote ("a", 0, NULL);
+ _do_strquote ("ab", 0, NULL);
+
+ _do_strquote (NULL, 1, "");
+ _do_strquote (NULL, 2, "(");
+ _do_strquote (NULL, 3, "(n");
+ _do_strquote (NULL, 4, "(nu");
+ _do_strquote (NULL, 5, "(nul");
+ _do_strquote (NULL, 6, "(null");
+ _do_strquote (NULL, 7, "(null)");
+ _do_strquote (NULL, 8, "(null)");
+ _do_strquote (NULL, 100, "(null)");
+
+ _do_strquote ("", 1, "");
+ _do_strquote ("", 2, "^");
+ _do_strquote ("", 3, "\"\"");
+ _do_strquote ("", 4, "\"\"");
+ _do_strquote ("", 5, "\"\"");
+ _do_strquote ("", 100, "\"\"");
+
+ _do_strquote ("a", 1, "");
+ _do_strquote ("a", 2, "^");
+ _do_strquote ("a", 3, "\"^");
+ _do_strquote ("a", 4, "\"a\"");
+ _do_strquote ("a", 5, "\"a\"");
+ _do_strquote ("a", 6, "\"a\"");
+ _do_strquote ("a", 100, "\"a\"");
+
+ _do_strquote ("ab", 1, "");
+ _do_strquote ("ab", 2, "^");
+ _do_strquote ("ab", 3, "\"^");
+ _do_strquote ("ab", 4, "\"a^");
+ _do_strquote ("ab", 5, "\"ab\"");
+ _do_strquote ("ab", 6, "\"ab\"");
+ _do_strquote ("ab", 7, "\"ab\"");
+ _do_strquote ("ab", 100, "\"ab\"");
+
+ _do_strquote ("abc", 1, "");
+ _do_strquote ("abc", 2, "^");
+ _do_strquote ("abc", 3, "\"^");
+ _do_strquote ("abc", 4, "\"a^");
+ _do_strquote ("abc", 5, "\"ab^");
+ _do_strquote ("abc", 6, "\"abc\"");
+ _do_strquote ("abc", 7, "\"abc\"");
+ _do_strquote ("abc", 100, "\"abc\"");
+}
+
+/*****************************************************************************/
+
#define UUID_NIL "00000000-0000-0000-0000-000000000000"
#define UUID_NS_DNS "6ba7b810-9dad-11d1-80b4-00c04fd430c8"
@@ -6366,6 +6448,7 @@ int main (int argc, char **argv)
g_test_add_func ("/core/general/test_setting_user_data", test_setting_user_data);
g_test_add_func ("/core/general/hexstr2bin", test_hexstr2bin);
+ g_test_add_func ("/core/general/nm_strquote", test_nm_strquote);
g_test_add_func ("/core/general/test_nm_utils_uuid_generate_from_string", test_nm_utils_uuid_generate_from_string);
g_test_add_func ("/core/general/_nm_utils_uuid_generate_from_strings", test_nm_utils_uuid_generate_from_strings);
diff --git a/shared/nm-utils/nm-shared-utils.c b/shared/nm-utils/nm-shared-utils.c
index 3be5550b74..16066d7085 100644
--- a/shared/nm-utils/nm-shared-utils.c
+++ b/shared/nm-utils/nm-shared-utils.c
@@ -115,6 +115,78 @@ nm_utils_strbuf_append (char **buf, gsize *len, const char *format, ...)
/*****************************************************************************/
+/**
+ * nm_strquote:
+ * @buf: the output buffer of where to write the quoted @str argument.
+ * @buf_len: the size of @buf.
+ * @str: (allow-none): the string to quote.
+ *
+ * Writes @str to @buf with quoting. The resulting buffer
+ * is always NUL terminated, unless @buf_len is zero.
+ * If @str is %NULL, it writes "(null)".
+ *
+ * If @str needs to be truncated, the closing quote is '^' instead
+ * of '"'.
+ *
+ * This is similar to nm_strquote_a(), which however uses alloca()
+ * to allocate a new buffer. Also, here @buf_len is the size of @buf,
+ * while nm_strquote_a() has the number of characters to print. The latter
+ * doesn't include the quoting.
+ *
+ * Returns: the input buffer with the quoted string. */
+const char *
+nm_strquote (char *buf, gsize buf_len, const char *str)
+{
+ const char *const buf0 = buf;
+
+ if (!str) {
+ nm_utils_strbuf_append_str (&buf, &buf_len, "(null)");
+ goto out;
+ }
+
+ if (G_UNLIKELY (buf_len <= 2)) {
+ switch (buf_len) {
+ case 2:
+ *(buf++) = '^';
+ /* fall-through*/
+ case 1:
+ *(buf++) = '\0';
+ break;
+ }
+ goto out;
+ }
+
+ *(buf++) = '"';
+ buf_len--;
+
+ nm_utils_strbuf_append_str (&buf, &buf_len, str);
+
+ /* if the string was too long we indicate truncation with a
+ * '^' instead of a closing quote. */
+ if (G_UNLIKELY (buf_len <= 1)) {
+ switch (buf_len) {
+ case 1:
+ buf[-1] = '^';
+ break;
+ case 0:
+ buf[-2] = '^';
+ break;
+ default:
+ nm_assert_not_reached ();
+ break;
+ }
+ } else {
+ nm_assert (buf_len >= 2);
+ *(buf++) = '"';
+ *(buf++) = '\0';
+ }
+
+out:
+ return buf0;
+}
+
+/*****************************************************************************/
+
char _nm_utils_to_string_buffer[];
void
diff --git a/shared/nm-utils/nm-shared-utils.h b/shared/nm-utils/nm-shared-utils.h
index 98cac9afcd..af1d22c832 100644
--- a/shared/nm-utils/nm-shared-utils.h
+++ b/shared/nm-utils/nm-shared-utils.h
@@ -166,6 +166,8 @@ void nm_utils_strbuf_append (char **buf, gsize *len, const char *format, ...) _n
void nm_utils_strbuf_append_c (char **buf, gsize *len, char c);
void nm_utils_strbuf_append_str (char **buf, gsize *len, const char *str);
+const char *nm_strquote (char *buf, gsize buf_len, const char *str);
+
/*****************************************************************************/
const char **nm_utils_strsplit_set (const char *str, const char *delimiters);