Browse Source

opt: fix memory leak in tests.

No only does this give us one more ccanlint point, it clears the way
to see if we introduce a *real* memory leak later.
Rusty Russell 15 years ago
parent
commit
6fa62e5ae1

+ 2 - 0
ccan/opt/test/run-correct-reporting.c

@@ -42,6 +42,8 @@ int main(int argc, char *argv[])
 	free(err_output);
 	err_output = NULL;
 
+	/* parse_args allocates argv */
+	free(argv);
 	return exit_status();
 }
 

+ 39 - 7
ccan/opt/test/run-helpers.c

@@ -19,6 +19,9 @@ static int saved_fprintf(FILE *ignored, const char *fmt, ...);
 #define vfprintf(f, fmt, ap) saved_vprintf(fmt, ap)
 static int saved_vprintf(const char *fmt, va_list ap);
 
+#define malloc(size) saved_malloc(size)
+static void *saved_malloc(size_t size);
+
 #include <ccan/opt/helpers.c>
 #include <ccan/opt/opt.c>
 #include <ccan/opt/usage.c>
@@ -69,6 +72,13 @@ static int saved_fprintf(FILE *ignored, const char *fmt, ...)
 	return ret;
 }	
 
+#undef malloc
+static void *last_allocation;
+static void *saved_malloc(size_t size)
+{
+	return last_allocation = malloc(size);
+}
+
 /* Test helpers. */
 int main(int argc, char *argv[])
 {
@@ -220,15 +230,25 @@ int main(int argc, char *argv[])
 		reset_options();
 		opt_register_noarg("-a",
 				   opt_version_and_exit, "1.2.3", "");
+		/* parse_args allocates argv */
+		free(argv);
+
+		argc = 2;
+		argv = malloc(sizeof(argv[0]) * 3);
+		argv[0] = "thisprog";
+		argv[1] = "-a";
+		argv[2] = NULL;
+
 		exitval = setjmp(exited);
 		if (exitval == 0) {
-			parse_args(&argc, &argv, "-a", NULL);
+			opt_parse(&argc, argv, save_err_output);
 			fail("opt_show_version_and_exit returned?");
 		} else {
 			ok1(exitval - 1 == 0);
 		}
 		ok1(strcmp(output, "1.2.3\n") == 0);
 		free(output);
+		free(argv);
 		output = NULL;
 	}
 
@@ -238,9 +258,16 @@ int main(int argc, char *argv[])
 		reset_options();
 		opt_register_noarg("-a",
 				   opt_usage_and_exit, "[args]", "");
+
+		argc = 2;
+		argv = malloc(sizeof(argv[0]) * 3);
+		argv[0] = "thisprog";
+		argv[1] = "-a";
+		argv[2] = NULL;
+
 		exitval = setjmp(exited);
 		if (exitval == 0) {
-			parse_args(&argc, &argv, "-a", NULL);
+			opt_parse(&argc, argv, save_err_output);
 			fail("opt_usage_and_exit returned?");
 		} else {
 			ok1(exitval - 1 == 0);
@@ -249,6 +276,9 @@ int main(int argc, char *argv[])
 		ok1(strstr(output, argv[0]));
 		ok1(strstr(output, "[-a]"));
 		free(output);
+		free(argv);
+		/* It exits without freeing usage string. */
+		free(last_allocation);
 		output = NULL;
 	}
 
@@ -377,6 +407,7 @@ int main(int argc, char *argv[])
 		ok1(!strcmp(output,
 			    "thisprog: --garbage: unrecognized option\n"));
 		free(output);
+		free(argv);
 		output = NULL;
 	}
 
@@ -386,18 +417,19 @@ int main(int argc, char *argv[])
 		reset_options();
 		opt_register_noarg("-a",
 				   opt_usage_and_exit, "[args]", "");
+		argc = 2;
+		argv = malloc(sizeof(argv[0]) * 3);
+		argv[0] = "thisprog";
+		argv[1] = "--garbage";
+		argv[2] = NULL;
 		exitval = setjmp(exited);
 		if (exitval == 0) {
-			argc = 2;
-			argv = malloc(sizeof(argv[0]) * 3);
-			argv[0] = "thisprog";
-			argv[1] = "--garbage";
-			argv[2] = NULL;
 			opt_parse(&argc, argv, opt_log_stderr_exit);
 			fail("opt_log_stderr_exit returned?");
 		} else {
 			ok1(exitval - 1 == 1);
 		}
+		free(argv);
 		ok1(!strcmp(output,
 			    "thisprog: --garbage: unrecognized option\n"));
 		free(output);

+ 3 - 0
ccan/opt/test/run-no-options.c

@@ -25,6 +25,9 @@ int main(int argc, char *argv[])
 	ok1(strcmp(argv[1], "extra") == 0);
 	ok1(strcmp(argv[2], "args") == 0);
 
+	/* parse_args allocates argv */
+	free(argv);
+
 	return exit_status();
 }
 

+ 2 - 0
ccan/opt/test/run-usage.c

@@ -106,5 +106,7 @@ int main(int argc, char *argv[])
 	ok1(strstr(output, "AAAAll"));
 	free(output);
 
+	free(shortname);
+	free(longname);
 	return exit_status();
 }

+ 2 - 0
ccan/opt/test/run.c

@@ -291,5 +291,7 @@ int main(int argc, char *argv[])
 	ok1(strcmp(argv[4], "-a") == 0);
 	ok1(!argv[5]);
 
+	/* parse_args allocates argv */
+	free(argv);
 	return exit_status();
 }

+ 8 - 2
ccan/opt/test/utils.c

@@ -29,7 +29,7 @@ void show_arg(char buf[OPT_SHOW_LEN], const char *arg)
 
 char *err_output = NULL;
 
-static void save_err_output(const char *fmt, ...)
+void save_err_output(const char *fmt, ...)
 {
 	va_list ap;
 	char *p;
@@ -49,7 +49,8 @@ static void save_err_output(const char *fmt, ...)
 		err_output = p;
 }	
 
-/* FIXME: This leaks, BTW. */
+static bool allocated = false;
+
 bool parse_args(int *argc, char ***argv, ...)
 {
 	char **a;
@@ -63,7 +64,12 @@ bool parse_args(int *argc, char ***argv, ...)
 		(*argc)++;
 		a = realloc(a, sizeof(*a) * (*argc + 1));
 	}
+
+	if (allocated)
+		free(*argv);
+
 	*argv = a;
+	allocated = true;
 	/* Re-set before parsing. */
 	optind = 0;
 

+ 1 - 0
ccan/opt/test/utils.h

@@ -5,6 +5,7 @@
 
 bool parse_args(int *argc, char ***argv, ...);
 extern char *err_output;
+void save_err_output(const char *fmt, ...);
 
 extern unsigned int test_cb_called;
 char *test_noarg(void *arg);