mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-10-02 03:46:39 +02:00
Merge branch 'strfuncs_join_oob' into 'main'
strfuncs: Check for overflows when joining strings See merge request GNOME/glib!4816
This commit is contained in:
@@ -581,7 +581,8 @@ g_strconcat (const gchar *string1, ...)
|
|||||||
s = va_arg (args, gchar*);
|
s = va_arg (args, gchar*);
|
||||||
while (s)
|
while (s)
|
||||||
{
|
{
|
||||||
l += strlen (s);
|
if (!g_size_checked_add (&l, l, strlen (s)))
|
||||||
|
g_error ("%s: overflow concatenating strings", G_STRLOC);
|
||||||
s = va_arg (args, gchar*);
|
s = va_arg (args, gchar*);
|
||||||
}
|
}
|
||||||
va_end (args);
|
va_end (args);
|
||||||
@@ -2645,13 +2646,18 @@ g_strjoinv (const gchar *separator,
|
|||||||
gsize i;
|
gsize i;
|
||||||
gsize len;
|
gsize len;
|
||||||
gsize separator_len;
|
gsize separator_len;
|
||||||
|
gsize separators_len;
|
||||||
|
|
||||||
separator_len = strlen (separator);
|
separator_len = strlen (separator);
|
||||||
/* First part, getting length */
|
/* First part, getting length */
|
||||||
len = 1 + strlen (str_array[0]);
|
len = 1 + strlen (str_array[0]);
|
||||||
for (i = 1; str_array[i] != NULL; i++)
|
for (i = 1; str_array[i] != NULL; i++)
|
||||||
len += strlen (str_array[i]);
|
if (!g_size_checked_add (&len, len, strlen (str_array[i])))
|
||||||
len += separator_len * (i - 1);
|
g_error ("%s: overflow joining strings", G_STRLOC);
|
||||||
|
|
||||||
|
if (!g_size_checked_mul (&separators_len, separator_len, (i - 1)) ||
|
||||||
|
!g_size_checked_add (&len, len, separators_len))
|
||||||
|
g_error ("%s: overflow joining strings", G_STRLOC);
|
||||||
|
|
||||||
/* Second part, building string */
|
/* Second part, building string */
|
||||||
string = g_new (gchar, len);
|
string = g_new (gchar, len);
|
||||||
@@ -2706,7 +2712,9 @@ g_strjoin (const gchar *separator,
|
|||||||
s = va_arg (args, gchar*);
|
s = va_arg (args, gchar*);
|
||||||
while (s)
|
while (s)
|
||||||
{
|
{
|
||||||
len += separator_len + strlen (s);
|
if (!g_size_checked_add (&len, len, separator_len) ||
|
||||||
|
!g_size_checked_add (&len, len, strlen (s)))
|
||||||
|
g_error ("%s: overflow joining strings", G_STRLOC);
|
||||||
s = va_arg (args, gchar*);
|
s = va_arg (args, gchar*);
|
||||||
}
|
}
|
||||||
va_end (args);
|
va_end (args);
|
||||||
|
@@ -660,6 +660,46 @@ test_strconcat (void)
|
|||||||
g_assert_null (g_strconcat (NULL, "bla", NULL));
|
g_assert_null (g_strconcat (NULL, "bla", NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Testing g_strjoinv() function with strings which cannot be joined in heap */
|
||||||
|
static void
|
||||||
|
test_strjoinv_overflow (void)
|
||||||
|
{
|
||||||
|
#if G_MAXSIZE > G_MAXUINT
|
||||||
|
g_test_skip ("Overflow joining strings requires G_MAXSIZE <= G_MAXUINT.");
|
||||||
|
#else
|
||||||
|
if (!g_test_undefined ())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (g_test_subprocess ())
|
||||||
|
{
|
||||||
|
/* compromise between memory consumption and performance */
|
||||||
|
const size_t count = 256;
|
||||||
|
gchar **array;
|
||||||
|
gchar *result;
|
||||||
|
gchar *string;
|
||||||
|
|
||||||
|
string = g_strnfill (G_MAXSIZE / ((count - 1) * 2), 'A');
|
||||||
|
array = g_malloc_n (count + 1, sizeof (*array));
|
||||||
|
|
||||||
|
for (size_t i = 0; i < count; i++)
|
||||||
|
array[i] = string;
|
||||||
|
array[count] = NULL;
|
||||||
|
|
||||||
|
result = g_strjoinv (string, array);
|
||||||
|
|
||||||
|
g_free (array);
|
||||||
|
g_free (result);
|
||||||
|
g_free (string);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT);
|
||||||
|
g_test_trap_assert_failed ();
|
||||||
|
g_test_trap_assert_stderr ("*overflow joining strings*");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/* Testing g_strjoinv() function with various positive and negative cases */
|
/* Testing g_strjoinv() function with various positive and negative cases */
|
||||||
static void
|
static void
|
||||||
test_strjoinv (void)
|
test_strjoinv (void)
|
||||||
@@ -2797,6 +2837,7 @@ main (int argc,
|
|||||||
g_test_add_func ("/strfuncs/strip-context", test_strip_context);
|
g_test_add_func ("/strfuncs/strip-context", test_strip_context);
|
||||||
g_test_add_func ("/strfuncs/strjoin", test_strjoin);
|
g_test_add_func ("/strfuncs/strjoin", test_strjoin);
|
||||||
g_test_add_func ("/strfuncs/strjoinv", test_strjoinv);
|
g_test_add_func ("/strfuncs/strjoinv", test_strjoinv);
|
||||||
|
g_test_add_func ("/strfuncs/strjoinv/overflow", test_strjoinv_overflow);
|
||||||
g_test_add_func ("/strfuncs/strlcat", test_strlcat);
|
g_test_add_func ("/strfuncs/strlcat", test_strlcat);
|
||||||
g_test_add_func ("/strfuncs/strlcpy", test_strlcpy);
|
g_test_add_func ("/strfuncs/strlcpy", test_strlcpy);
|
||||||
g_test_add_func ("/strfuncs/strncasecmp", test_strncasecmp);
|
g_test_add_func ("/strfuncs/strncasecmp", test_strncasecmp);
|
||||||
|
Reference in New Issue
Block a user