aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas George2012-11-02 11:35:12 +0100
committerNicolas George2012-11-04 10:47:52 +0100
commite021eeb9f06f4f4d83690d07b47cdcc4172a61e1 (patch)
treebdb36e6da93836144355808d914ed1b3e58eedea
parent4e6fa5be3ce5a66e9420377dceedffb6cadfdad4 (diff)
lavu/opt: parse key into a mallocated buffer.
It removes the hardcoded limit on the key size without making the code much more complex, and it makes for a more versatile API.
-rw-r--r--libavutil/opt.c35
1 files changed, 17 insertions, 18 deletions
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;