From 5dca72fe67aec5f98bfb68257c34ff133b59d22a Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Mon, 12 Dec 2011 18:56:21 +0000 Subject: [PATCH] GOptionContext test: free all arguments, not just the remaining ones On success, g_option_context_parse alters argv by removing options that it understood, so g_strfreev is insufficient. Instead, take a shallow copy and free all of the arguments in that, then free the array argv but not its contents. Also, improve the checks in error cases, by checking that argv has not been altered in this way. Signed-off-by: Simon McVittie Bug: https://bugzilla.gnome.org/show_bug.cgi?id=666115 Reviewed-by: Matthias Clasen --- glib/tests/option-context.c | 353 +++++++++++++++++++++++++++--------- 1 file changed, 265 insertions(+), 88 deletions(-) diff --git a/glib/tests/option-context.c b/glib/tests/option-context.c index 7cccddcb8..20b1ee327 100644 --- a/glib/tests/option-context.c +++ b/glib/tests/option-context.c @@ -233,6 +233,22 @@ copy_stringv (char **argv, int argc) return g_memdup (argv, sizeof (char *) * (argc + 1)); } +static void +check_identical_stringv (gchar **before, gchar **after) +{ + guint i; + + /* Not only is it the same string... */ + for (i = 0; before[i] != NULL; i++) + g_assert_cmpstr (before[i], ==, after[i]); + + /* ... it is actually the same pointer */ + for (i = 0; before[i] != NULL; i++) + g_assert (before[i] == after[i]); + + g_assert (after[i] == NULL); +} + static gboolean error_test1_pre_parse (GOptionContext *context, @@ -266,6 +282,7 @@ error_test1 (void) gboolean retval; GError *error = NULL; gchar **argv; + gchar **argv_copy; int argc; GOptionGroup *main_group; GOptionEntry entries [] = @@ -284,14 +301,20 @@ error_test1 (void) /* Now try parsing */ argv = split_string ("program --test 20", &argc); + argv_copy = copy_stringv (argv, argc); retval = g_option_context_parse (context, &argc, &argv, &error); g_assert (retval == FALSE); + g_assert (error != NULL); + /* An error occurred, so argv has not been changed */ + check_identical_stringv (argv_copy, argv); + g_clear_error (&error); /* On failure, values should be reset */ g_assert (error_test1_int == 0x12345678); - - g_strfreev (argv); + + g_strfreev (argv_copy); + g_free (argv); g_option_context_free (context); } @@ -327,6 +350,7 @@ error_test2 (void) gboolean retval; GError *error = NULL; gchar **argv; + gchar **argv_copy; int argc; GOptionGroup *main_group; GOptionEntry entries [] = @@ -345,14 +369,18 @@ error_test2 (void) /* Now try parsing */ argv = split_string ("program --test bar", &argc); + argv_copy = copy_stringv (argv, argc); retval = g_option_context_parse (context, &argc, &argv, &error); - g_error_free (error); g_assert (retval == FALSE); + g_assert (error != NULL); + check_identical_stringv (argv_copy, argv); + g_clear_error (&error); g_assert (strcmp (error_test2_string, "foo") == 0); - - g_strfreev (argv); + + g_strfreev (argv_copy); + g_free (argv); g_option_context_free (context); } @@ -388,6 +416,7 @@ error_test3 (void) gboolean retval; GError *error = NULL; gchar **argv; + gchar **argv_copy; int argc; GOptionGroup *main_group; GOptionEntry entries [] = @@ -406,14 +435,18 @@ error_test3 (void) /* Now try parsing */ argv = split_string ("program --test", &argc); + argv_copy = copy_stringv (argv, argc); retval = g_option_context_parse (context, &argc, &argv, &error); - g_error_free (error); g_assert (retval == FALSE); + g_assert (error != NULL); + check_identical_stringv (argv_copy, argv); + g_clear_error (&error); g_assert (!error_test3_boolean); - - g_strfreev (argv); + + g_strfreev (argv_copy); + g_free (argv); g_option_context_free (context); } @@ -424,6 +457,7 @@ arg_test1 (void) gboolean retval; GError *error = NULL; gchar **argv; + gchar **argv_copy; int argc; GOptionEntry entries [] = { { "test", 0, 0, G_OPTION_ARG_INT, &arg_test1_int, NULL, NULL }, @@ -434,6 +468,7 @@ arg_test1 (void) /* Now try parsing */ argv = split_string ("program --test 20 --test 30", &argc); + argv_copy = copy_stringv (argv, argc); retval = g_option_context_parse (context, &argc, &argv, &error); g_assert_no_error (error); @@ -442,7 +477,11 @@ arg_test1 (void) /* Last arg specified is the one that should be stored */ g_assert (arg_test1_int == 30); - g_strfreev (argv); + /* We free all of the strings in a copy of argv, because now argv is a + * subset - some have been removed in-place + */ + g_strfreev (argv_copy); + g_free (argv); g_option_context_free (context); } @@ -453,6 +492,7 @@ arg_test2 (void) gboolean retval; GError *error = NULL; gchar **argv; + gchar **argv_copy; int argc; GOptionEntry entries [] = { { "test", 0, 0, G_OPTION_ARG_STRING, &arg_test2_string, NULL, NULL }, @@ -463,7 +503,8 @@ arg_test2 (void) /* Now try parsing */ argv = split_string ("program --test foo --test bar", &argc); - + argv_copy = copy_stringv (argv, argc); + retval = g_option_context_parse (context, &argc, &argv, &error); g_assert_no_error (error); g_assert (retval); @@ -472,8 +513,9 @@ arg_test2 (void) g_assert (strcmp (arg_test2_string, "bar") == 0); g_free (arg_test2_string); - - g_strfreev (argv); + + g_strfreev (argv_copy); + g_free (argv); g_option_context_free (context); } @@ -484,6 +526,7 @@ arg_test3 (void) gboolean retval; GError *error = NULL; gchar **argv; + gchar **argv_copy; int argc; GOptionEntry entries [] = { { "test", 0, 0, G_OPTION_ARG_FILENAME, &arg_test3_filename, NULL, NULL }, @@ -494,7 +537,8 @@ arg_test3 (void) /* Now try parsing */ argv = split_string ("program --test foo.txt", &argc); - + argv_copy = copy_stringv (argv, argc); + retval = g_option_context_parse (context, &argc, &argv, &error); g_assert_no_error (error); g_assert (retval); @@ -503,8 +547,9 @@ arg_test3 (void) g_assert (strcmp (arg_test3_filename, "foo.txt") == 0); g_free (arg_test3_filename); - - g_strfreev (argv); + + g_strfreev (argv_copy); + g_free (argv); g_option_context_free (context); } @@ -515,6 +560,7 @@ arg_test4 (void) GOptionContext *context; gboolean retval; GError *error = NULL; + gchar **argv_copy; gchar **argv; int argc; GOptionEntry entries [] = @@ -526,6 +572,7 @@ arg_test4 (void) /* Now try parsing */ argv = split_string ("program --test 20.0 --test 30.03", &argc); + argv_copy = copy_stringv (argv, argc); retval = g_option_context_parse (context, &argc, &argv, &error); g_assert_no_error (error); @@ -534,7 +581,8 @@ arg_test4 (void) /* Last arg specified is the one that should be stored */ g_assert (arg_test4_double == 30.03); - g_strfreev (argv); + g_strfreev (argv_copy); + g_free (argv); g_option_context_free (context); } @@ -545,6 +593,7 @@ arg_test5 (void) gboolean retval; GError *error = NULL; gchar **argv; + gchar **argv_copy; int argc; char *old_locale, *current_locale; const char *locale = "de_DE"; @@ -557,6 +606,7 @@ arg_test5 (void) /* Now try parsing */ argv = split_string ("program --test 20,0 --test 30,03", &argc); + argv_copy = copy_stringv (argv, argc); /* set it to some locale that uses commas instead of decimal points */ @@ -579,7 +629,8 @@ arg_test5 (void) setlocale (LC_NUMERIC, old_locale); g_free (old_locale); - g_strfreev (argv); + g_strfreev (argv_copy); + g_free (argv); g_option_context_free (context); } @@ -590,6 +641,7 @@ arg_test6 (void) gboolean retval; GError *error = NULL; gchar **argv; + gchar **argv_copy; int argc; GOptionEntry entries [] = { { "test", 0, 0, G_OPTION_ARG_INT64, &arg_test6_int64, NULL, NULL }, @@ -601,6 +653,7 @@ arg_test6 (void) /* Now try parsing */ argv = split_string ("program --test 4294967297 --test 4294967296 --test2 0xfffffffff", &argc); + argv_copy = copy_stringv (argv, argc); retval = g_option_context_parse (context, &argc, &argv, &error); g_assert_no_error (error); @@ -610,7 +663,8 @@ arg_test6 (void) g_assert (arg_test6_int64 == G_GINT64_CONSTANT(4294967296)); g_assert (arg_test6_int64_2 == G_GINT64_CONSTANT(0xfffffffff)); - g_strfreev (argv); + g_strfreev (argv_copy); + g_free (argv); g_option_context_free (context); } @@ -629,6 +683,7 @@ callback_test1 (void) gboolean retval; GError *error = NULL; gchar **argv; + gchar **argv_copy; int argc; GOptionEntry entries [] = { { "test", 0, 0, G_OPTION_ARG_CALLBACK, callback_parse1, NULL, NULL }, @@ -639,7 +694,8 @@ callback_test1 (void) /* Now try parsing */ argv = split_string ("program --test foo.txt", &argc); - + argv_copy = copy_stringv (argv, argc); + retval = g_option_context_parse (context, &argc, &argv, &error); g_assert_no_error (error); g_assert (retval); @@ -647,8 +703,9 @@ callback_test1 (void) g_assert (strcmp (callback_test1_string, "foo.txt") == 0); g_free (callback_test1_string); - - g_strfreev (argv); + + g_strfreev (argv_copy); + g_free (argv); g_option_context_free (context); } @@ -667,6 +724,7 @@ callback_test2 (void) gboolean retval; GError *error = NULL; gchar **argv; + gchar **argv_copy; int argc; GOptionEntry entries [] = { { "test", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, callback_parse2, NULL, NULL }, @@ -677,14 +735,16 @@ callback_test2 (void) /* Now try parsing */ argv = split_string ("program --test --test", &argc); - + argv_copy = copy_stringv (argv, argc); + retval = g_option_context_parse (context, &argc, &argv, &error); g_assert_no_error (error); g_assert (retval); g_assert (callback_test2_int == 2); - - g_strfreev (argv); + + g_strfreev (argv_copy); + g_free (argv); g_option_context_free (context); } @@ -707,6 +767,7 @@ callback_test_optional_1 (void) gboolean retval; GError *error = NULL; gchar **argv; + gchar **argv_copy; int argc; GOptionEntry entries [] = { { "test", 0, G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, @@ -718,7 +779,8 @@ callback_test_optional_1 (void) /* Now try parsing */ argv = split_string ("program --test foo.txt", &argc); - + argv_copy = copy_stringv (argv, argc); + retval = g_option_context_parse (context, &argc, &argv, &error); g_assert_no_error (error); g_assert (retval); @@ -728,8 +790,9 @@ callback_test_optional_1 (void) g_assert (callback_test_optional_boolean); g_free (callback_test_optional_string); - - g_strfreev (argv); + + g_strfreev (argv_copy); + g_free (argv); g_option_context_free (context); } @@ -740,6 +803,7 @@ callback_test_optional_2 (void) gboolean retval; GError *error = NULL; gchar **argv; + gchar **argv_copy; int argc; GOptionEntry entries [] = { { "test", 0, G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, @@ -751,7 +815,8 @@ callback_test_optional_2 (void) /* Now try parsing */ argv = split_string ("program --test", &argc); - + argv_copy = copy_stringv (argv, argc); + retval = g_option_context_parse (context, &argc, &argv, &error); g_assert_no_error (error); g_assert (retval); @@ -761,8 +826,9 @@ callback_test_optional_2 (void) g_assert (callback_test_optional_boolean); g_free (callback_test_optional_string); - - g_strfreev (argv); + + g_strfreev (argv_copy); + g_free (argv); g_option_context_free (context); } @@ -772,6 +838,7 @@ callback_test_optional_3 (void) GOptionContext *context; gboolean retval; GError *error = NULL; + gchar **argv_copy; gchar **argv; int argc; GOptionEntry entries [] = @@ -784,7 +851,8 @@ callback_test_optional_3 (void) /* Now try parsing */ argv = split_string ("program -t foo.txt", &argc); - + argv_copy = copy_stringv (argv, argc); + retval = g_option_context_parse (context, &argc, &argv, &error); g_assert_no_error (error); g_assert (retval); @@ -794,8 +862,9 @@ callback_test_optional_3 (void) g_assert (callback_test_optional_boolean); g_free (callback_test_optional_string); - - g_strfreev (argv); + + g_strfreev (argv_copy); + g_free (argv); g_option_context_free (context); } @@ -807,6 +876,7 @@ callback_test_optional_4 (void) gboolean retval; GError *error = NULL; gchar **argv; + gchar **argv_copy; int argc; GOptionEntry entries [] = { { "test", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, @@ -818,7 +888,8 @@ callback_test_optional_4 (void) /* Now try parsing */ argv = split_string ("program -t", &argc); - + argv_copy = copy_stringv (argv, argc); + retval = g_option_context_parse (context, &argc, &argv, &error); g_assert_no_error (error); g_assert (retval); @@ -828,8 +899,9 @@ callback_test_optional_4 (void) g_assert (callback_test_optional_boolean); g_free (callback_test_optional_string); - - g_strfreev (argv); + + g_strfreev (argv_copy); + g_free (argv); g_option_context_free (context); } @@ -841,6 +913,7 @@ callback_test_optional_5 (void) gboolean retval; GError *error = NULL; gchar **argv; + gchar **argv_copy; int argc; GOptionEntry entries [] = { { "dummy", 'd', 0, G_OPTION_ARG_NONE, &dummy, NULL }, @@ -853,7 +926,8 @@ callback_test_optional_5 (void) /* Now try parsing */ argv = split_string ("program --test --dummy", &argc); - + argv_copy = copy_stringv (argv, argc); + retval = g_option_context_parse (context, &argc, &argv, &error); g_assert_no_error (error); g_assert (retval); @@ -863,8 +937,9 @@ callback_test_optional_5 (void) g_assert (callback_test_optional_boolean); g_free (callback_test_optional_string); - - g_strfreev (argv); + + g_strfreev (argv_copy); + g_free (argv); g_option_context_free (context); } @@ -876,6 +951,7 @@ callback_test_optional_6 (void) gboolean retval; GError *error = NULL; gchar **argv; + gchar **argv_copy; int argc; GOptionEntry entries [] = { { "dummy", 'd', 0, G_OPTION_ARG_NONE, &dummy, NULL }, @@ -888,7 +964,8 @@ callback_test_optional_6 (void) /* Now try parsing */ argv = split_string ("program -t -d", &argc); - + argv_copy = copy_stringv (argv, argc); + retval = g_option_context_parse (context, &argc, &argv, &error); g_assert_no_error (error); g_assert (retval); @@ -898,8 +975,9 @@ callback_test_optional_6 (void) g_assert (callback_test_optional_boolean); g_free (callback_test_optional_string); - - g_strfreev (argv); + + g_strfreev (argv_copy); + g_free (argv); g_option_context_free (context); } @@ -911,6 +989,7 @@ callback_test_optional_7 (void) gboolean retval; GError *error = NULL; gchar **argv; + gchar **argv_copy; int argc; GOptionEntry entries [] = { { "dummy", 'd', 0, G_OPTION_ARG_NONE, &dummy, NULL }, @@ -923,7 +1002,8 @@ callback_test_optional_7 (void) /* Now try parsing */ argv = split_string ("program -td", &argc); - + argv_copy = copy_stringv (argv, argc); + retval = g_option_context_parse (context, &argc, &argv, &error); g_assert_no_error (error); g_assert (retval); @@ -933,8 +1013,9 @@ callback_test_optional_7 (void) g_assert (callback_test_optional_boolean); g_free (callback_test_optional_string); - - g_strfreev (argv); + + g_strfreev (argv_copy); + g_free (argv); g_option_context_free (context); } @@ -946,6 +1027,7 @@ callback_test_optional_8 (void) gboolean retval; GError *error = NULL; gchar **argv; + gchar **argv_copy; int argc; GOptionEntry entries [] = { { "dummy", 'd', 0, G_OPTION_ARG_NONE, &dummy, NULL }, @@ -958,7 +1040,8 @@ callback_test_optional_8 (void) /* Now try parsing */ argv = split_string ("program -dt foo.txt", &argc); - + argv_copy = copy_stringv (argv, argc); + retval = g_option_context_parse (context, &argc, &argv, &error); g_assert_no_error (error); g_assert (retval); @@ -968,8 +1051,9 @@ callback_test_optional_8 (void) g_assert (callback_test_optional_boolean); g_free (callback_test_optional_string); - - g_strfreev (argv); + + g_strfreev (argv_copy); + g_free (argv); g_option_context_free (context); } @@ -980,6 +1064,7 @@ callback_test_optional_9 (void) gboolean retval; GError *error = NULL; gchar **argv; + gchar **argv_copy; int argc; gchar *string = NULL; GOptionEntry entries [] = @@ -992,14 +1077,17 @@ callback_test_optional_9 (void) /* Now try parsing */ argv = split_string ("program -t", &argc); + argv_copy = copy_stringv (argv, argc); retval = g_option_context_parse (context, &argc, &argv, &error); g_assert_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE); g_assert (!retval); g_assert (string == NULL); + check_identical_stringv (argv_copy, argv); g_error_free (error); - g_strfreev (argv); + g_strfreev (argv_copy); + g_free (argv); g_option_context_free (context); } @@ -1010,6 +1098,7 @@ callback_test_optional_10 (void) gboolean retval; GError *error = NULL; gchar **argv; + gchar **argv_copy; int argc; gchar *string = NULL; GOptionEntry entries [] = @@ -1022,14 +1111,17 @@ callback_test_optional_10 (void) /* Now try parsing */ argv = split_string ("program --test", &argc); + argv_copy = copy_stringv (argv, argc); retval = g_option_context_parse (context, &argc, &argv, &error); g_assert_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE); g_assert (!retval); g_assert (string == NULL); + check_identical_stringv (argv_copy, argv); g_error_free (error); - g_strfreev (argv); + g_strfreev (argv_copy); + g_free (argv); g_option_context_free (context); } @@ -1049,6 +1141,7 @@ callback_remaining_test1 (void) gboolean retval; GError *error = NULL; gchar **argv; + gchar **argv_copy; int argc; GOptionEntry entries [] = { { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_CALLBACK, callback_remaining_test1_callback, NULL, NULL }, @@ -1060,7 +1153,8 @@ callback_remaining_test1 (void) /* Now try parsing */ argv = split_string ("program foo.txt blah.txt", &argc); - + argv_copy = copy_stringv (argv, argc); + retval = g_option_context_parse (context, &argc, &argv, &error); g_assert_no_error (error); g_assert (retval); @@ -1071,8 +1165,9 @@ callback_remaining_test1 (void) g_ptr_array_foreach (callback_remaining_args, (GFunc) g_free, NULL); g_ptr_array_free (callback_remaining_args, TRUE); - - g_strfreev (argv); + + g_strfreev (argv_copy); + g_free (argv); g_option_context_free (context); } @@ -1091,6 +1186,7 @@ callback_returns_false (void) gboolean retval; GError *error = NULL; gchar **argv; + gchar **argv_copy; int argc; GOptionEntry entries [] = { { "error", 0, 0, G_OPTION_ARG_CALLBACK, callback_error, NULL, NULL }, @@ -1103,52 +1199,68 @@ callback_returns_false (void) /* Now try parsing */ argv = split_string ("program --error value", &argc); - + argv_copy = copy_stringv (argv, argc); + retval = g_option_context_parse (context, &argc, &argv, &error); g_assert_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE); g_assert (retval == FALSE); + check_identical_stringv (argv_copy, argv); g_option_context_free (context); g_clear_error (&error); + g_strfreev (argv_copy); + g_free (argv); /* And again, this time with a no-arg variant */ context = g_option_context_new (NULL); g_option_context_add_main_entries (context, entries, NULL); argv = split_string ("program --error-no-arg", &argc); - + argv_copy = copy_stringv (argv, argc); + retval = g_option_context_parse (context, &argc, &argv, &error); g_assert_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE); g_assert (retval == FALSE); + check_identical_stringv (argv_copy, argv); g_option_context_free (context); g_clear_error (&error); + g_strfreev (argv_copy); + g_free (argv); /* And again, this time with a optional arg variant, with argument */ context = g_option_context_new (NULL); g_option_context_add_main_entries (context, entries, NULL); argv = split_string ("program --error-optional-arg value", &argc); - + argv_copy = copy_stringv (argv, argc); + retval = g_option_context_parse (context, &argc, &argv, &error); g_assert_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE); g_assert (retval == FALSE); + check_identical_stringv (argv_copy, argv); g_option_context_free (context); g_clear_error (&error); + g_strfreev (argv_copy); + g_free (argv); /* And again, this time with a optional arg variant, without argument */ context = g_option_context_new (NULL); g_option_context_add_main_entries (context, entries, NULL); argv = split_string ("program --error-optional-arg", &argc); - + argv_copy = copy_stringv (argv, argc); + retval = g_option_context_parse (context, &argc, &argv, &error); g_assert_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE); g_assert (retval == FALSE); + check_identical_stringv (argv_copy, argv); g_option_context_free (context); g_clear_error (&error); + g_strfreev (argv_copy); + g_free (argv); } @@ -1194,6 +1306,7 @@ ignore_test2 (void) gboolean retval; GError *error = NULL; gchar **argv; + gchar **argv_copy; int argc; gchar *arg; GOptionEntry entries [] = @@ -1206,7 +1319,8 @@ ignore_test2 (void) /* Now try parsing */ argv = split_string ("program -test", &argc); - + argv_copy = copy_stringv (argv, argc); + retval = g_option_context_parse (context, &argc, &argv, &error); g_assert_no_error (error); g_assert (retval); @@ -1216,7 +1330,8 @@ ignore_test2 (void) g_assert (strcmp (arg, "program -es") == 0); g_free (arg); - g_strfreev (argv); + g_strfreev (argv_copy); + g_free (argv); g_option_context_free (context); } @@ -1265,6 +1380,7 @@ static array_test1 (void) gboolean retval; GError *error = NULL; gchar **argv; + gchar **argv_copy; int argc; GOptionEntry entries [] = { { "test", 0, 0, G_OPTION_ARG_STRING_ARRAY, &array_test1_array, NULL, NULL }, @@ -1275,7 +1391,8 @@ static array_test1 (void) /* Now try parsing */ argv = split_string ("program --test foo --test bar", &argc); - + argv_copy = copy_stringv (argv, argc); + retval = g_option_context_parse (context, &argc, &argv, &error); g_assert_no_error (error); g_assert (retval); @@ -1287,7 +1404,8 @@ static array_test1 (void) g_strfreev (array_test1_array); - g_strfreev (argv); + g_strfreev (argv_copy); + g_free (argv); g_option_context_free (context); } @@ -1345,6 +1463,7 @@ rest_test1 (void) gboolean retval; GError *error = NULL; gchar **argv; + gchar **argv_copy; int argc; GOptionEntry entries [] = { { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL }, @@ -1356,7 +1475,8 @@ rest_test1 (void) /* Now try parsing */ argv = split_string ("program foo --test bar", &argc); - + argv_copy = copy_stringv (argv, argc); + retval = g_option_context_parse (context, &argc, &argv, &error); g_assert_no_error (error); g_assert (retval); @@ -1368,7 +1488,8 @@ rest_test1 (void) g_assert (strcmp (argv[2], "bar") == 0); g_assert (argv[3] == NULL); - g_strfreev (argv); + g_strfreev (argv_copy); + g_free (argv); g_option_context_free (context); } @@ -1380,6 +1501,7 @@ rest_test2 (void) gboolean retval; GError *error = NULL; gchar **argv; + gchar **argv_copy; int argc; GOptionEntry entries [] = { { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL }, @@ -1391,7 +1513,8 @@ rest_test2 (void) /* Now try parsing */ argv = split_string ("program foo --test -- -bar", &argc); - + argv_copy = copy_stringv (argv, argc); + retval = g_option_context_parse (context, &argc, &argv, &error); g_assert_no_error (error); g_assert (retval); @@ -1404,7 +1527,8 @@ rest_test2 (void) g_assert (strcmp (argv[3], "-bar") == 0); g_assert (argv[4] == NULL); - g_strfreev (argv); + g_strfreev (argv_copy); + g_free (argv); g_option_context_free (context); } @@ -1416,6 +1540,7 @@ rest_test2a (void) gboolean retval; GError *error = NULL; gchar **argv; + gchar **argv_copy; int argc; GOptionEntry entries [] = { { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL }, @@ -1427,7 +1552,8 @@ rest_test2a (void) /* Now try parsing */ argv = split_string ("program foo --test -- bar", &argc); - + argv_copy = copy_stringv (argv, argc); + retval = g_option_context_parse (context, &argc, &argv, &error); g_assert_no_error (error); g_assert (retval); @@ -1439,7 +1565,8 @@ rest_test2a (void) g_assert (strcmp (argv[2], "bar") == 0); g_assert (argv[3] == NULL); - g_strfreev (argv); + g_strfreev (argv_copy); + g_free (argv); g_option_context_free (context); } @@ -1450,6 +1577,7 @@ rest_test2b (void) gboolean retval; GError *error = NULL; gchar **argv; + gchar **argv_copy; int argc; GOptionEntry entries [] = { { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL }, @@ -1462,7 +1590,8 @@ rest_test2b (void) /* Now try parsing */ argv = split_string ("program foo --test -bar --", &argc); - + argv_copy = copy_stringv (argv, argc); + retval = g_option_context_parse (context, &argc, &argv, &error); g_assert_no_error (error); g_assert (retval); @@ -1474,7 +1603,8 @@ rest_test2b (void) g_assert (strcmp (argv[2], "-bar") == 0); g_assert (argv[3] == NULL); - g_strfreev (argv); + g_strfreev (argv_copy); + g_free (argv); g_option_context_free (context); } @@ -1485,6 +1615,7 @@ rest_test2c (void) gboolean retval; GError *error = NULL; gchar **argv; + gchar **argv_copy; int argc; GOptionEntry entries [] = { { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL }, @@ -1496,7 +1627,8 @@ rest_test2c (void) /* Now try parsing */ argv = split_string ("program --test foo -- bar", &argc); - + argv_copy = copy_stringv (argv, argc); + retval = g_option_context_parse (context, &argc, &argv, &error); g_assert_no_error (error); g_assert (retval); @@ -1508,7 +1640,8 @@ rest_test2c (void) g_assert (strcmp (argv[2], "bar") == 0); g_assert (argv[3] == NULL); - g_strfreev (argv); + g_strfreev (argv_copy); + g_free (argv); g_option_context_free (context); } @@ -1519,6 +1652,7 @@ rest_test2d (void) gboolean retval; GError *error = NULL; gchar **argv; + gchar **argv_copy; int argc; GOptionEntry entries [] = { { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL }, @@ -1530,7 +1664,8 @@ rest_test2d (void) /* Now try parsing */ argv = split_string ("program --test -- -bar", &argc); - + argv_copy = copy_stringv (argv, argc); + retval = g_option_context_parse (context, &argc, &argv, &error); g_assert_no_error (error); g_assert (retval); @@ -1542,7 +1677,8 @@ rest_test2d (void) g_assert (strcmp (argv[2], "-bar") == 0); g_assert (argv[3] == NULL); - g_strfreev (argv); + g_strfreev (argv_copy); + g_free (argv); g_option_context_free (context); } @@ -1555,6 +1691,7 @@ rest_test3 (void) gboolean retval; GError *error = NULL; gchar **argv; + gchar **argv_copy; int argc; GOptionEntry entries [] = { { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL }, @@ -1567,7 +1704,8 @@ rest_test3 (void) /* Now try parsing */ argv = split_string ("program foo --test bar", &argc); - + argv_copy = copy_stringv (argv, argc); + retval = g_option_context_parse (context, &argc, &argv, &error); g_assert_no_error (error); g_assert (retval); @@ -1579,8 +1717,9 @@ rest_test3 (void) g_assert (array_test1_array[2] == NULL); g_strfreev (array_test1_array); - - g_strfreev (argv); + + g_strfreev (argv_copy); + g_free (argv); g_option_context_free (context); } @@ -1593,6 +1732,7 @@ rest_test4 (void) gboolean retval; GError *error = NULL; gchar **argv; + gchar **argv_copy; int argc; GOptionEntry entries [] = { { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL }, @@ -1605,7 +1745,8 @@ rest_test4 (void) /* Now try parsing */ argv = split_string ("program foo --test -- -bar", &argc); - + argv_copy = copy_stringv (argv, argc); + retval = g_option_context_parse (context, &argc, &argv, &error); g_assert_no_error (error); g_assert (retval); @@ -1617,8 +1758,9 @@ rest_test4 (void) g_assert (array_test1_array[2] == NULL); g_strfreev (array_test1_array); - - g_strfreev (argv); + + g_strfreev (argv_copy); + g_free (argv); g_option_context_free (context); } @@ -1630,6 +1772,7 @@ rest_test5 (void) gboolean retval; GError *error = NULL; gchar **argv; + gchar **argv_copy; int argc; GOptionEntry entries [] = { { "test", 0, 0, G_OPTION_ARG_NONE, &ignore_test1_boolean, NULL, NULL }, @@ -1642,7 +1785,8 @@ rest_test5 (void) /* Now try parsing */ argv = split_string ("program foo --test bar", &argc); - + argv_copy = copy_stringv (argv, argc); + retval = g_option_context_parse (context, &argc, &argv, &error); g_assert_no_error (error); g_assert (retval); @@ -1654,8 +1798,9 @@ rest_test5 (void) g_assert (array_test1_array[2] == NULL); g_strfreev (array_test1_array); - - g_strfreev (argv); + + g_strfreev (argv_copy); + g_free (argv); g_option_context_free (context); } @@ -1666,6 +1811,7 @@ unknown_short_test (void) gboolean retval; GError *error = NULL; gchar **argv; + gchar **argv_copy; int argc; GOptionEntry entries [] = { { NULL } }; @@ -1676,11 +1822,15 @@ unknown_short_test (void) /* Now try parsing */ argv = split_string ("program -0", &argc); + argv_copy = copy_stringv (argv, argc); retval = g_option_context_parse (context, &argc, &argv, &error); g_assert (!retval); + g_assert (error != NULL); + g_clear_error (&error); - g_strfreev (argv); + g_strfreev (argv_copy); + g_free (argv); g_option_context_free (context); } @@ -1692,6 +1842,7 @@ lonely_dash_test (void) gboolean retval; GError *error = NULL; gchar **argv; + gchar **argv_copy; int argc; g_test_bug ("168008"); @@ -1700,6 +1851,7 @@ lonely_dash_test (void) /* Now try parsing */ argv = split_string ("program -", &argc); + argv_copy = copy_stringv (argv, argc); retval = g_option_context_parse (context, &argc, &argv, &error); g_assert_no_error (error); @@ -1707,7 +1859,8 @@ lonely_dash_test (void) g_assert (argv[1] && strcmp (argv[1], "-") == 0); - g_strfreev (argv); + g_strfreev (argv_copy); + g_free (argv); g_option_context_free (context); } @@ -1718,6 +1871,7 @@ missing_arg_test (void) gboolean retval; GError *error = NULL; gchar **argv; + gchar **argv_copy; int argc; gchar *arg = NULL; GOptionEntry entries [] = @@ -1731,20 +1885,31 @@ missing_arg_test (void) /* Now try parsing */ argv = split_string ("program --test", &argc); + argv_copy = copy_stringv (argv, argc); retval = g_option_context_parse (context, &argc, &argv, &error); g_assert (retval == FALSE); + g_assert (error != NULL); + /* An error occurred, so argv has not been changed */ + check_identical_stringv (argv_copy, argv); g_clear_error (&error); - g_strfreev (argv); + g_strfreev (argv_copy); + g_free (argv); /* Try parsing again */ argv = split_string ("program -t", &argc); + argv_copy = copy_stringv (argv, argc); retval = g_option_context_parse (context, &argc, &argv, &error); g_assert (retval == FALSE); + g_assert (error != NULL); + /* An error occurred, so argv has not been changed */ + check_identical_stringv (argv_copy, argv); + g_clear_error (&error); - g_strfreev (argv); + g_strfreev (argv_copy); + g_free (argv); g_option_context_free (context); } @@ -1766,6 +1931,7 @@ dash_arg_test (void) gboolean retval; GError *error = NULL; gchar **argv; + gchar **argv_copy; int argc; gboolean argb = FALSE; GOptionEntry entries [] = @@ -1780,6 +1946,7 @@ dash_arg_test (void) /* Now try parsing */ argv = split_string ("program --test=-3", &argc); + argv_copy = copy_stringv (argv, argc); test_arg = NULL; error = NULL; @@ -1788,12 +1955,14 @@ dash_arg_test (void) g_assert_no_error (error); g_assert_cmpstr (test_arg, ==, "-3"); - g_strfreev (argv); + g_strfreev (argv_copy); + g_free (argv); g_free (test_arg); test_arg = NULL; /* Try parsing again */ argv = split_string ("program --test -3", &argc); + argv_copy = copy_stringv (argv, argc); error = NULL; retval = g_option_context_parse (context, &argc, &argv, &error); @@ -1802,6 +1971,8 @@ dash_arg_test (void) g_assert_cmpstr (test_arg, ==, NULL); g_option_context_free (context); + g_strfreev (argv_copy); + g_free (argv); } static void @@ -1874,6 +2045,7 @@ test_error_hook (void) { NULL } }; GOptionGroup *group; gchar **argv; + gchar **argv_copy; gint argc; gboolean retval; GError *error = NULL; @@ -1886,14 +2058,19 @@ test_error_hook (void) error_func); argv = split_string ("program --test", &argc); + argv_copy = copy_stringv (argv, argc); retval = g_option_context_parse (context, &argc, &argv, &error); g_assert (retval == FALSE); + g_assert (error != NULL); + /* An error occurred, so argv has not been changed */ + check_identical_stringv (argv_copy, argv); g_clear_error (&error); g_assert (error_func_called); - g_strfreev (argv); + g_strfreev (argv_copy); + g_free (argv); g_option_context_free (context); }