History

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.

Nicolas George committed 14 years ago

Commit e021eeb1 parent 4e6fa5b1 file · +17 −18Browse files

Unified · Split

libavutil/opt.c+17−18
@@ -829,31 +829,27 @@ static int is_key_char(char c) · 828 unmodified lines
829 * Read a key from a string.829 * Read a key from a string.
830 *830 *
831 * The key consists of is_key_char characters and must be terminated by a831 * The key consists of is_key_char characters and must be terminated by a
832 * character from the delim string; spaces are ignored. The key buffer must832 * character from the delim string; spaces are ignored.
833 * be 4 bytes larger than the longest acceptable key. If the key is too
834 * long, an ellipsis will be written at the end.
835 *833 *
836 * @return 0 for success (even with ellipsis), <0 for failure834 * @return 0 for success (even with ellipsis), <0 for failure
837 */835 */
838static int get_key(const char **ropts, const char *delim, char *key, unsigned key_size)836static int get_key(const char **ropts, const char *delim, char **rkey)
839{837{
840 unsigned key_pos = 0;
841 const char *opts = *ropts;838 const char *opts = *ropts;
839 const char *key_start, *key_end;
842 840
843 opts += strspn(opts, WHITESPACES);841 key_start = opts += strspn(opts, WHITESPACES);
844 while (is_key_char(*opts)) {842 while (is_key_char(*opts))
845 key[key_pos++] = *opts;843 opts++;
846 if (key_pos == key_size)844 key_end = opts;
847 key_pos--;
848 (opts)++;
849 }
850 opts += strspn(opts, WHITESPACES);845 opts += strspn(opts, WHITESPACES);
851 if (!*opts || !strchr(delim, *opts))846 if (!*opts || !strchr(delim, *opts))
852 return AVERROR(EINVAL);847 return AVERROR(EINVAL);
853 opts++;848 opts++;
854 key[key_pos++] = 0;849 if (!(*rkey = av_malloc(key_end - key_start + 1)))
855 if (key_pos == key_size)850 return AVERROR(ENOMEM);
856 key[key_pos - 4] = key[key_pos - 3] = key[key_pos - 2] = '.';851 memcpy(*rkey, key_start, key_end - key_start);
852 (*rkey)[key_end - key_start] = 0;
857 *ropts = opts;853 *ropts = opts;
858 return 0;854 return 0;
859}855}
@@ -864,7 +860,7 @@ int av_opt_set_from_string(void *ctx, const char *opts, · 4 unmodified lines
864{860{
865 int ret, count = 0;861 int ret, count = 0;
866 const char *dummy_shorthand = NULL;862 const char *dummy_shorthand = NULL;
867 char key_buf[68], *value;863 char *parsed_key, *value;
868 const char *key;864 const char *key;
869 865
870 if (!opts)866 if (!opts)
@@ -873,7 +869,8 @@ int av_opt_set_from_string(void *ctx, const char *opts, · 2 unmodified lines
873 shorthand = &dummy_shorthand;869 shorthand = &dummy_shorthand;
874 870
875 while (*opts) {871 while (*opts) {
876 if ((ret = get_key(&opts, key_val_sep, key_buf, sizeof(key_buf))) < 0) {872 parsed_key = NULL; /* so we can free it anyway */
873 if ((ret = get_key(&opts, key_val_sep, &parsed_key)) < 0) {
877 if (*shorthand) {874 if (*shorthand) {
878 key = *(shorthand++);875 key = *(shorthand++);
879 } else {876 } else {
@@ -881,7 +878,7 @@ int av_opt_set_from_string(void *ctx, const char *opts, · 1 unmodified line
881 return AVERROR(EINVAL);878 return AVERROR(EINVAL);
882 }879 }
883 } else {880 } else {
884 key = key_buf;881 key = parsed_key;
885 while (*shorthand) /* discard all remaining shorthand */882 while (*shorthand) /* discard all remaining shorthand */
886 shorthand++;883 shorthand++;
887 }884 }
@@ -896,10 +893,12 @@ int av_opt_set_from_string(void *ctx, const char *opts, · 8 unmodified lines
896 if (ret == AVERROR_OPTION_NOT_FOUND)893 if (ret == AVERROR_OPTION_NOT_FOUND)
897 av_log(ctx, AV_LOG_ERROR, "Option '%s' not found\n", key);894 av_log(ctx, AV_LOG_ERROR, "Option '%s' not found\n", key);
898 av_free(value);895 av_free(value);
896 av_free(parsed_key);
899 return ret;897 return ret;
900 }898 }
901 899
902 av_free(value);900 av_free(value);
901 av_free(parsed_key);
903 count++;902 count++;
904 }903 }
905 return count;904 return count;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t