diff options
author | Thomas Haller <thaller@redhat.com> | 2019-01-11 13:26:44 +0100 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2019-01-22 16:30:23 +0100 |
commit | 035c4ad45d75d4ac10c6da5b4138ecd55da6c5f8 (patch) | |
tree | d7be76b5d2b3c88c11ccd4962a981260400cc820 /shared/nm-utils | |
parent | d7d2dafc1b25bc02a51c32e9660b66e4a987befe (diff) | |
download | NetworkManager-035c4ad45d75d4ac10c6da5b4138ecd55da6c5f8.tar.gz |
shared: suppress -Wstringop-truncation warning in nm_strndup_a()
The compiler is too smart for nm_strndup_a(). The code is correct,
suppress "-Wstringop-truncation" warning.
Diffstat (limited to 'shared/nm-utils')
-rw-r--r-- | shared/nm-utils/nm-shared-utils.h | 9 | ||||
-rw-r--r-- | shared/nm-utils/tests/test-shared-general.c | 53 |
2 files changed, 61 insertions, 1 deletions
diff --git a/shared/nm-utils/nm-shared-utils.h b/shared/nm-utils/nm-shared-utils.h index 8106371d0a..93868726e8 100644 --- a/shared/nm-utils/nm-shared-utils.h +++ b/shared/nm-utils/nm-shared-utils.h @@ -255,10 +255,12 @@ nm_memdup (gconstpointer data, gsize size) static inline char * _nm_strndup_a_step (char *s, const char *str, gsize len) { + NM_PRAGMA_WARNING_DISABLE ("-Wstringop-truncation"); if (len > 0) strncpy (s, str, len); s[len] = '\0'; return s; + NM_PRAGMA_WARNING_REENABLE; } /* Similar to g_strndup(), however, if the string (including the terminating @@ -269,7 +271,12 @@ _nm_strndup_a_step (char *s, const char *str, gsize len) * * In case malloc() is necessary, @out_str_free will be set (this string * must be freed afterwards). It is permissible to pass %NULL as @out_str_free, - * if you ensure that len < alloca_maxlen. */ + * if you ensure that len < alloca_maxlen. + * + * Note that just like g_strndup(), this always returns a buffer with @len + 1 + * bytes, even if strlen(@str) is shorter than that (NUL terminated early). We fill + * the buffer with strncpy(), which means, that @str is copied up to the first + * NUL character and then filled with NUL characters. */ #define nm_strndup_a(alloca_maxlen, str, len, out_str_free) \ ({ \ const gsize _alloca_maxlen = (alloca_maxlen); \ diff --git a/shared/nm-utils/tests/test-shared-general.c b/shared/nm-utils/tests/test-shared-general.c index d7df46dc52..7d22e56d99 100644 --- a/shared/nm-utils/tests/test-shared-general.c +++ b/shared/nm-utils/tests/test-shared-general.c @@ -152,6 +152,58 @@ test_nm_strdup_int (void) /*****************************************************************************/ +static void +test_nm_strndup_a (void) +{ + int run; + + for (run = 0; run < 20; run++) { + gs_free char *input = NULL; + char ch; + gsize i, l; + + input = g_strnfill (nmtst_get_rand_int () % 20, 'x'); + + for (i = 0; input[i]; i++) { + while ((ch = ((char) nmtst_get_rand_int ())) == '\0') { + /* repeat. */ + } + input[i] = ch; + } + + { + gs_free char *dup_free = NULL; + const char *dup; + + l = strlen (input) + 1; + dup = nm_strndup_a (10, input, l - 1, &dup_free); + g_assert_cmpstr (dup, ==, input); + if (strlen (dup) < 10) + g_assert (!dup_free); + else + g_assert (dup == dup_free); + } + + { + gs_free char *dup_free = NULL; + const char *dup; + + l = nmtst_get_rand_int () % 23; + dup = nm_strndup_a (10, input, l, &dup_free); + g_assert (strncmp (dup, input, l) == 0); + g_assert (strlen (dup) <= l); + if (l < 10) + g_assert (!dup_free); + else + g_assert (dup == dup_free); + if (strlen (input) < l) + g_assert (nm_utils_memeqzero (&dup[strlen (input)], l - strlen (input))); + } + } +} + +/*****************************************************************************/ + NMTST_DEFINE (); int main (int argc, char **argv) @@ -162,6 +214,7 @@ int main (int argc, char **argv) g_test_add_func ("/general/test_nmhash", test_nmhash); g_test_add_func ("/general/test_nm_make_strv", test_make_strv); g_test_add_func ("/general/test_nm_strdup_int", test_nm_strdup_int); + g_test_add_func ("/general/test_nm_strndup_a", test_nm_strndup_a); return g_test_run (); } |