diff --git a/libavutil/opt.c b/libavutil/opt.c index 404fbac9c9..35475ebb03 100644 --- a/libavutil/opt.c +++ b/libavutil/opt.c @@ -829,31 +829,27 @@ static int is_key_char(char c) * Read a key from a string. * * The key consists of is_key_char characters and must be terminated by a - * character from the delim string; spaces are ignored. The key buffer must - * be 4 bytes larger than the longest acceptable key. If the key is too - * long, an ellipsis will be written at the end. + * character from the delim string; spaces are ignored. * * @return 0 for success (even with ellipsis), <0 for failure */ -static int get_key(const char **ropts, const char *delim, char *key, unsigned key_size) +static int get_key(const char **ropts, const char *delim, char **rkey) { - unsigned key_pos = 0; const char *opts = *ropts; + const char *key_start, *key_end; - opts += strspn(opts, WHITESPACES); - while (is_key_char(*opts)) { - key[key_pos++] = *opts; - if (key_pos == key_size) - key_pos--; - (opts)++; - } + key_start = opts += strspn(opts, WHITESPACES); + while (is_key_char(*opts)) + opts++; + key_end = opts; opts += strspn(opts, WHITESPACES); if (!*opts || !strchr(delim, *opts)) return AVERROR(EINVAL); opts++; - key[key_pos++] = 0; - if (key_pos == key_size) - key[key_pos - 4] = key[key_pos - 3] = key[key_pos - 2] = '.'; + if (!(*rkey = av_malloc(key_end - key_start + 1))) + return AVERROR(ENOMEM); + memcpy(*rkey, key_start, key_end - key_start); + (*rkey)[key_end - key_start] = 0; *ropts = opts; return 0; } @@ -864,7 +860,7 @@ int av_opt_set_from_string(void *ctx, const char *opts, { int ret, count = 0; const char *dummy_shorthand = NULL; - char key_buf[68], *value; + char *parsed_key, *value; const char *key; if (!opts) @@ -873,7 +869,8 @@ int av_opt_set_from_string(void *ctx, const char *opts, shorthand = &dummy_shorthand; while (*opts) { - if ((ret = get_key(&opts, key_val_sep, key_buf, sizeof(key_buf))) < 0) { + parsed_key = NULL; /* so we can free it anyway */ + if ((ret = get_key(&opts, key_val_sep, &parsed_key)) < 0) { if (*shorthand) { key = *(shorthand++); } else { @@ -881,7 +878,7 @@ int av_opt_set_from_string(void *ctx, const char *opts, return AVERROR(EINVAL); } } else { - key = key_buf; + key = parsed_key; while (*shorthand) /* discard all remaining shorthand */ shorthand++; } @@ -896,10 +893,12 @@ int av_opt_set_from_string(void *ctx, const char *opts, if (ret == AVERROR_OPTION_NOT_FOUND) av_log(ctx, AV_LOG_ERROR, "Option '%s' not found\n", key); av_free(value); + av_free(parsed_key); return ret; } av_free(value); + av_free(parsed_key); count++; } return count;