input: fix use after free with legacy commands

To handle legacy commands, string replacement is used; the modified
string is returned by parse_cmd_str(), but it also frees all temporary
memory, which includes the replaced string.

Closes #1075.
This commit is contained in:
wm4
2014-09-08 15:13:11 +02:00
parent 3b5f28bd0f
commit 4ef531f815

View File

@@ -242,27 +242,28 @@ error:
return NULL; return NULL;
} }
static struct mp_cmd *parse_cmd_str(struct mp_log *log, bstr *str, const char *loc) static struct mp_cmd *parse_cmd_str(struct mp_log *log, void *tmp,
bstr *str, const char *loc)
{ {
struct parse_ctx ctx = { struct parse_ctx ctx = {
.log = log, .log = log,
.loc = loc, .loc = loc,
.tmp = talloc_new(NULL), .tmp = tmp,
.str = *str, .str = *str,
.start = *str, .start = *str,
}; };
struct mp_cmd *res = parse_cmd(&ctx, MP_ON_OSD_AUTO | MP_EXPAND_PROPERTIES); struct mp_cmd *res = parse_cmd(&ctx, MP_ON_OSD_AUTO | MP_EXPAND_PROPERTIES);
talloc_free(ctx.tmp);
*str = ctx.str; *str = ctx.str;
return res; return res;
} }
mp_cmd_t *mp_input_parse_cmd_(struct mp_log *log, bstr str, const char *loc) mp_cmd_t *mp_input_parse_cmd_(struct mp_log *log, bstr str, const char *loc)
{ {
void *tmp = talloc_new(NULL);
bstr original = str; bstr original = str;
struct mp_cmd *cmd = parse_cmd_str(log, &str, loc); struct mp_cmd *cmd = parse_cmd_str(log, tmp, &str, loc);
if (!cmd) if (!cmd)
return NULL; goto done;
// Handle "multi" commands // Handle "multi" commands
struct mp_cmd **p_prev = NULL; struct mp_cmd **p_prev = NULL;
@@ -287,16 +288,19 @@ mp_cmd_t *mp_input_parse_cmd_(struct mp_log *log, bstr str, const char *loc)
p_prev = &cmd->queue_next; p_prev = &cmd->queue_next;
cmd = list; cmd = list;
} }
struct mp_cmd *sub = parse_cmd_str(log, &str, loc); struct mp_cmd *sub = parse_cmd_str(log, tmp, &str, loc);
if (!sub) { if (!sub) {
talloc_free(cmd); talloc_free(cmd);
return NULL; cmd = NULL;
goto done;
} }
talloc_steal(cmd, sub); talloc_steal(cmd, sub);
*p_prev = sub; *p_prev = sub;
p_prev = &sub->queue_next; p_prev = &sub->queue_next;
} }
done:
talloc_free(tmp);
return cmd; return cmd;
} }