mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-08-21 16:38:54 +02:00
Merge branch 'vasprintf-leak-fix' into 'main'
gprintf: Fix a memory leak with an invalid format in g_vasprintf() See merge request GNOME/glib!2547
This commit is contained in:
@@ -295,7 +295,8 @@ g_vsnprintf (gchar *string,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* g_vasprintf:
|
* g_vasprintf:
|
||||||
* @string: (not optional) (nullable): the return location for the newly-allocated string.
|
* @string: (not optional) (nullable): the return location for the newly-allocated string,
|
||||||
|
* which will be %NULL if (and only if) this function fails
|
||||||
* @format: (not nullable): a standard printf() format string, but notice
|
* @format: (not nullable): a standard printf() format string, but notice
|
||||||
* [string precision pitfalls][string-precision]
|
* [string precision pitfalls][string-precision]
|
||||||
* @args: the list of arguments to insert in the output.
|
* @args: the list of arguments to insert in the output.
|
||||||
@@ -312,7 +313,7 @@ g_vsnprintf (gchar *string,
|
|||||||
*
|
*
|
||||||
* `glib/gprintf.h` must be explicitly included in order to use this function.
|
* `glib/gprintf.h` must be explicitly included in order to use this function.
|
||||||
*
|
*
|
||||||
* Returns: the number of bytes printed.
|
* Returns: the number of bytes printed, or `-1` on failure
|
||||||
*
|
*
|
||||||
* Since: 2.4
|
* Since: 2.4
|
||||||
**/
|
**/
|
||||||
@@ -356,6 +357,12 @@ g_vasprintf (gchar **string,
|
|||||||
|
|
||||||
len = _g_vsprintf (*string, format, args2);
|
len = _g_vsprintf (*string, format, args2);
|
||||||
va_end (args2);
|
va_end (args2);
|
||||||
|
|
||||||
|
if (len < 0)
|
||||||
|
{
|
||||||
|
g_free (*string);
|
||||||
|
*string = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -215,6 +215,44 @@ test_string_append (void)
|
|||||||
g_string_free (string, TRUE);
|
g_string_free (string, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void string_append_vprintf_va (GString *string,
|
||||||
|
const gchar *format,
|
||||||
|
...) G_GNUC_PRINTF (2, 3);
|
||||||
|
|
||||||
|
/* Wrapper around g_string_append_vprintf() which takes varargs */
|
||||||
|
static void
|
||||||
|
string_append_vprintf_va (GString *string,
|
||||||
|
const gchar *format,
|
||||||
|
...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
va_start (args, format);
|
||||||
|
g_string_append_vprintf (string, format, args);
|
||||||
|
va_end (args);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_string_append_vprintf (void)
|
||||||
|
{
|
||||||
|
GString *string;
|
||||||
|
|
||||||
|
/* append */
|
||||||
|
string = g_string_new ("firsthalf");
|
||||||
|
|
||||||
|
string_append_vprintf_va (string, "some %s placeholders", "format");
|
||||||
|
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wformat"
|
||||||
|
#pragma GCC diagnostic ignored "-Wformat-extra-args"
|
||||||
|
string_append_vprintf_va (string, "%l", "invalid");
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
|
g_assert_cmpstr (string->str, ==, "firsthalfsome format placeholders");
|
||||||
|
|
||||||
|
g_string_free (string, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_string_prepend_c (void)
|
test_string_prepend_c (void)
|
||||||
{
|
{
|
||||||
@@ -571,6 +609,7 @@ main (int argc,
|
|||||||
g_test_add_func ("/string/test-string-assign", test_string_assign);
|
g_test_add_func ("/string/test-string-assign", test_string_assign);
|
||||||
g_test_add_func ("/string/test-string-append-c", test_string_append_c);
|
g_test_add_func ("/string/test-string-append-c", test_string_append_c);
|
||||||
g_test_add_func ("/string/test-string-append", test_string_append);
|
g_test_add_func ("/string/test-string-append", test_string_append);
|
||||||
|
g_test_add_func ("/string/test-string-append-vprintf", test_string_append_vprintf);
|
||||||
g_test_add_func ("/string/test-string-prepend-c", test_string_prepend_c);
|
g_test_add_func ("/string/test-string-prepend-c", test_string_prepend_c);
|
||||||
g_test_add_func ("/string/test-string-prepend", test_string_prepend);
|
g_test_add_func ("/string/test-string-prepend", test_string_prepend);
|
||||||
g_test_add_func ("/string/test-string-insert", test_string_insert);
|
g_test_add_func ("/string/test-string-insert", test_string_insert);
|
||||||
|
@@ -895,6 +895,44 @@ test_upper_bound (void)
|
|||||||
g_assert_cmpint (res, ==, 20);
|
g_assert_cmpint (res, ==, 20);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gint test_vasprintf_va (gchar **string,
|
||||||
|
const gchar *format,
|
||||||
|
...) G_GNUC_PRINTF (2, 3);
|
||||||
|
|
||||||
|
/* Wrapper around g_vasprintf() which takes varargs */
|
||||||
|
static gint
|
||||||
|
test_vasprintf_va (gchar **string,
|
||||||
|
const gchar *format,
|
||||||
|
...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
gint len;
|
||||||
|
|
||||||
|
va_start (args, format);
|
||||||
|
len = g_vasprintf (string, format, args);
|
||||||
|
va_end (args);
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_vasprintf_invalid_format_placeholder (void)
|
||||||
|
{
|
||||||
|
gint len = 0;
|
||||||
|
gchar *buf = "some non-null string";
|
||||||
|
|
||||||
|
g_test_summary ("Test error handling for invalid format placeholder in g_vasprintf()");
|
||||||
|
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wformat"
|
||||||
|
#pragma GCC diagnostic ignored "-Wformat-extra-args"
|
||||||
|
len = test_vasprintf_va (&buf, "%l", "nope");
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
|
g_assert_cmpint (len, ==, -1);
|
||||||
|
g_assert_null (buf);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc,
|
main (int argc,
|
||||||
char *argv[])
|
char *argv[])
|
||||||
@@ -935,5 +973,7 @@ main (int argc,
|
|||||||
g_test_add_func ("/sprintf/test-positional-params", test_positional_params3);
|
g_test_add_func ("/sprintf/test-positional-params", test_positional_params3);
|
||||||
g_test_add_func ("/sprintf/upper-bound", test_upper_bound);
|
g_test_add_func ("/sprintf/upper-bound", test_upper_bound);
|
||||||
|
|
||||||
|
g_test_add_func ("/vasprintf/invalid-format-placeholder", test_vasprintf_invalid_format_placeholder);
|
||||||
|
|
||||||
return g_test_run();
|
return g_test_run();
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user