| 754 | } |
| 755 | |
| 756 | static int opt_set_array(void *obj, void *target_obj, const AVOption *o, |
| 757 | const char *val, void *dst) |
| 758 | { |
| 759 | const AVOptionArrayDef *arr = o->default_val.arr; |
| 760 | const size_t elem_size = opt_type_desc[TYPE_BASE(o->type)].size; |
| 761 | const uint8_t sep = opt_array_sep(o); |
| 762 | uint8_t *str = NULL; |
| 763 | |
| 764 | void *elems = NULL; |
| 765 | unsigned nb_elems = 0; |
| 766 | int ret; |
| 767 | |
| 768 | if (val && *val) { |
| 769 | str = av_malloc(strlen(val) + 1); |
| 770 | if (!str) |
| 771 | return AVERROR(ENOMEM); |
| 772 | } |
| 773 | |
| 774 | // split and unescape the string |
| 775 | while (val && *val) { |
| 776 | uint8_t *p = str; |
| 777 | void *tmp; |
| 778 | |
| 779 | if (arr && arr->size_max && nb_elems >= arr->size_max) { |
| 780 | av_log(obj, AV_LOG_ERROR, |
| 781 | "Cannot assign more than %u elements to array option %s\n", |
| 782 | arr->size_max, o->name); |
| 783 | ret = AVERROR(EINVAL); |
| 784 | goto fail; |
| 785 | } |
| 786 | |
| 787 | for (; *val; val++, p++) { |
| 788 | if (*val == '\\' && val[1]) |
| 789 | val++; |
| 790 | else if (*val == sep) { |
| 791 | val++; |
| 792 | break; |
| 793 | } |
| 794 | *p = *val; |
| 795 | } |
| 796 | *p = 0; |
| 797 | |
| 798 | tmp = av_realloc_array(elems, nb_elems + 1, elem_size); |
| 799 | if (!tmp) { |
| 800 | ret = AVERROR(ENOMEM); |
| 801 | goto fail; |
| 802 | } |
| 803 | elems = tmp; |
| 804 | |
| 805 | tmp = opt_array_pelem(o, elems, nb_elems); |
| 806 | memset(tmp, 0, elem_size); |
| 807 | |
| 808 | ret = opt_set_elem(obj, target_obj, o, str, tmp); |
| 809 | if (ret < 0) |
| 810 | goto fail; |
| 811 | nb_elems++; |
| 812 | } |
| 813 | av_freep(&str); |
no test coverage detected