struct concat_nodes *nodes; ///< list of nodes to concat
size_t length; ///< number of cat'ed nodes
size_t current; ///< index of currently read node
+ uint64_t total_size;
};
static av_cold int concat_close(URLContext *h)
struct concat_nodes *nodes = data->nodes;
for (i = 0; i != data->length; i++)
- err |= ffurl_close(nodes[i].uc);
+ err |= ffurl_closep(&nodes[i].uc);
av_freep(&data->nodes);
{
char *node_uri = NULL;
int err = 0;
- int64_t size;
+ int64_t size, total_size = 0;
size_t len, i;
URLContext *uc;
struct concat_data *data = h->priv_data;
for (i = 0, len = 1; uri[i]; i++) {
if (uri[i] == *AV_CAT_SEPARATOR) {
- /* integer overflow */
- if (++len == UINT_MAX / sizeof(*nodes)) {
- av_freep(&h->priv_data);
- return AVERROR(ENAMETOOLONG);
- }
+ len++;
}
}
- if (!(nodes = av_realloc(NULL, sizeof(*nodes) * len)))
+ if (!(nodes = av_realloc_array(NULL, len, sizeof(*nodes))))
return AVERROR(ENOMEM);
else
data->nodes = nodes;
/* assembling */
nodes[i].uc = uc;
nodes[i].size = size;
+ total_size += size;
}
av_free(node_uri);
data->length = i;
err = AVERROR(ENOMEM);
} else
data->nodes = nodes;
+ data->total_size = total_size;
return err;
}
struct concat_nodes *nodes = data->nodes;
size_t i;
+ if ((whence & AVSEEK_SIZE))
+ return data->total_size;
switch (whence) {
case SEEK_END:
for (i = data->length - 1; i && pos < -nodes[i].size; i--)