You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-08-15 14:13:16 +02:00
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.
This commit is contained in:
@@ -829,31 +829,27 @@ static int is_key_char(char c)
|
|||||||
* Read a key from a string.
|
* Read a key from a string.
|
||||||
*
|
*
|
||||||
* The key consists of is_key_char characters and must be terminated by a
|
* 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
|
* character from the delim string; spaces are ignored.
|
||||||
* be 4 bytes larger than the longest acceptable key. If the key is too
|
|
||||||
* long, an ellipsis will be written at the end.
|
|
||||||
*
|
*
|
||||||
* @return 0 for success (even with ellipsis), <0 for failure
|
* @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 *opts = *ropts;
|
||||||
|
const char *key_start, *key_end;
|
||||||
|
|
||||||
opts += strspn(opts, WHITESPACES);
|
key_start = opts += strspn(opts, WHITESPACES);
|
||||||
while (is_key_char(*opts)) {
|
while (is_key_char(*opts))
|
||||||
key[key_pos++] = *opts;
|
opts++;
|
||||||
if (key_pos == key_size)
|
key_end = opts;
|
||||||
key_pos--;
|
|
||||||
(opts)++;
|
|
||||||
}
|
|
||||||
opts += strspn(opts, WHITESPACES);
|
opts += strspn(opts, WHITESPACES);
|
||||||
if (!*opts || !strchr(delim, *opts))
|
if (!*opts || !strchr(delim, *opts))
|
||||||
return AVERROR(EINVAL);
|
return AVERROR(EINVAL);
|
||||||
opts++;
|
opts++;
|
||||||
key[key_pos++] = 0;
|
if (!(*rkey = av_malloc(key_end - key_start + 1)))
|
||||||
if (key_pos == key_size)
|
return AVERROR(ENOMEM);
|
||||||
key[key_pos - 4] = key[key_pos - 3] = key[key_pos - 2] = '.';
|
memcpy(*rkey, key_start, key_end - key_start);
|
||||||
|
(*rkey)[key_end - key_start] = 0;
|
||||||
*ropts = opts;
|
*ropts = opts;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -864,7 +860,7 @@ int av_opt_set_from_string(void *ctx, const char *opts,
|
|||||||
{
|
{
|
||||||
int ret, count = 0;
|
int ret, count = 0;
|
||||||
const char *dummy_shorthand = NULL;
|
const char *dummy_shorthand = NULL;
|
||||||
char key_buf[68], *value;
|
char *parsed_key, *value;
|
||||||
const char *key;
|
const char *key;
|
||||||
|
|
||||||
if (!opts)
|
if (!opts)
|
||||||
@@ -873,7 +869,8 @@ int av_opt_set_from_string(void *ctx, const char *opts,
|
|||||||
shorthand = &dummy_shorthand;
|
shorthand = &dummy_shorthand;
|
||||||
|
|
||||||
while (*opts) {
|
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) {
|
if (*shorthand) {
|
||||||
key = *(shorthand++);
|
key = *(shorthand++);
|
||||||
} else {
|
} else {
|
||||||
@@ -881,7 +878,7 @@ int av_opt_set_from_string(void *ctx, const char *opts,
|
|||||||
return AVERROR(EINVAL);
|
return AVERROR(EINVAL);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
key = key_buf;
|
key = parsed_key;
|
||||||
while (*shorthand) /* discard all remaining shorthand */
|
while (*shorthand) /* discard all remaining shorthand */
|
||||||
shorthand++;
|
shorthand++;
|
||||||
}
|
}
|
||||||
@@ -896,10 +893,12 @@ int av_opt_set_from_string(void *ctx, const char *opts,
|
|||||||
if (ret == AVERROR_OPTION_NOT_FOUND)
|
if (ret == AVERROR_OPTION_NOT_FOUND)
|
||||||
av_log(ctx, AV_LOG_ERROR, "Option '%s' not found\n", key);
|
av_log(ctx, AV_LOG_ERROR, "Option '%s' not found\n", key);
|
||||||
av_free(value);
|
av_free(value);
|
||||||
|
av_free(parsed_key);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
av_free(value);
|
av_free(value);
|
||||||
|
av_free(parsed_key);
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
|
Reference in New Issue
Block a user