Commit eb6566cf authored by Birte Kristina Friesel's avatar Birte Kristina Friesel
Browse files

feh_parse_options_from_string: allocate argv list on stack

This fixes a really weird bug where continued theme definitions containing
just one option/value pair caused feh to mis-parse parts of the following
line.

Apparently, subsequent realloc calls mixed with strdups in another function
caused parts of the list (argv) content to be overwritten by the content of
the list pointer itself. I wasn't able to find out the exact causes /
conditions.
parent 3be31437
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -31,6 +31,9 @@ git HEAD
      and not just the default for new windows
    * The zoom_default key now works fine with --scale-down
      <http://github.com/derf/feh/issues/41>
    * Fix access of uninitialized memory / malloc/realloc clash in continued
      theme definition handling.  Having a theme line with just one
      option/value pair used to produce undefined behaviour

Sat, 23 Apr 2011 22:00:27 +0200  Daniel Friesel <derf@finalrewind.org>

+2 −8
Original line number Diff line number Diff line
@@ -223,7 +223,7 @@ static void feh_load_options_for_theme(char *theme)
/* FIXME This function is a crufty bitch ;) */
static void feh_parse_options_from_string(char *opts)
{
	char **list = NULL;
	char *list[sizeof(char *) * 64];
	int num = 0;
	char *s;
	char *t;
@@ -235,21 +235,17 @@ static void feh_parse_options_from_string(char *opts)
	   getopt_long function to do this parsing as well. This means it has to
	   look like the real argv ;) */

	list = malloc(sizeof(char *));

	list[num++] = estrdup(PACKAGE);

	for (s = opts, t = opts;; t++) {
		if ((*t == ' ') && !(inquote)) {
			*t = '\0';
			num++;
			list = erealloc(list, sizeof(char *) * num);

			list[num - 1] = feh_string_normalize(s);
			s = t + 1;
		} else if (*t == '\0') {
			num++;
			list = erealloc(list, sizeof(char *) * num);

			list[num - 1] = feh_string_normalize(s);
			break;
@@ -263,8 +259,6 @@ static void feh_parse_options_from_string(char *opts)
	for (i = 0; i < num; i++)
		if (list[i])
			free(list[i]);
	if (list)
		free(list);
	return;
}

@@ -291,7 +285,7 @@ char *feh_string_normalize(char *str)

		last = *s;
	}
	if (i && ret[i - 1] == '\"')
	if (i && (ret[i - 1] == '\"'))
		ret[i - 1] = '\0';
	else
		ret[i] = '\0';