summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Friesel <derf@finalrewind.org>2011-05-11 01:52:34 +0200
committerDaniel Friesel <derf@finalrewind.org>2011-05-11 01:52:34 +0200
commiteb6566cf9d1887cc5f18df58be6651579404fed4 (patch)
tree06f676ab64b82ac65c7ad279060ffa3c4ecdfde3
parent3be31437fe3493fe013659290744f590d1e23f9c (diff)
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.
-rw-r--r--ChangeLog3
-rw-r--r--src/options.c10
2 files changed, 5 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index 54334e2..c28a827 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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>
diff --git a/src/options.c b/src/options.c
index b947908..70686cc 100644
--- a/src/options.c
+++ b/src/options.c
@@ -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';