avformat/webm_chunk: support for arbitrary path lengths

Signed-off-by: Marton Balint <cus@passwd.hu>
This commit is contained in:
Marton Balint
2025-08-18 00:02:22 +02:00
parent 35ceef40ad
commit 8c1301cf9d

View File

@@ -30,13 +30,12 @@
#include "internal.h" #include "internal.h"
#include "mux.h" #include "mux.h"
#include "libavutil/bprint.h"
#include "libavutil/log.h" #include "libavutil/log.h"
#include "libavutil/mem.h" #include "libavutil/mem.h"
#include "libavutil/opt.h" #include "libavutil/opt.h"
#include "libavutil/mathematics.h" #include "libavutil/mathematics.h"
#define MAX_FILENAME_SIZE 1024
typedef struct WebMChunkContext { typedef struct WebMChunkContext {
const AVClass *class; const AVClass *class;
char *header_filename; char *header_filename;
@@ -133,16 +132,13 @@ fail:
return 0; return 0;
} }
static int get_chunk_filename(AVFormatContext *s, char filename[MAX_FILENAME_SIZE]) static int get_chunk_filename(AVFormatContext *s, AVBPrint *filename)
{ {
WebMChunkContext *wc = s->priv_data; WebMChunkContext *wc = s->priv_data;
if (!filename) { int ret = ff_bprint_get_frame_filename(filename, s->url, wc->chunk_index - 1, 0);
return AVERROR(EINVAL); if (ret < 0) {
}
if (av_get_frame_filename(filename, MAX_FILENAME_SIZE,
s->url, wc->chunk_index - 1) < 0) {
av_log(s, AV_LOG_ERROR, "Invalid chunk filename template '%s'\n", s->url); av_log(s, AV_LOG_ERROR, "Invalid chunk filename template '%s'\n", s->url);
return AVERROR(EINVAL); return ret;
} }
return 0; return 0;
} }
@@ -185,7 +181,7 @@ static int chunk_end(AVFormatContext *s, int flush)
int buffer_size; int buffer_size;
uint8_t *buffer; uint8_t *buffer;
AVIOContext *pb; AVIOContext *pb;
char filename[MAX_FILENAME_SIZE]; AVBPrint filename;
AVDictionary *options = NULL; AVDictionary *options = NULL;
if (!oc->pb) if (!oc->pb)
@@ -196,19 +192,21 @@ static int chunk_end(AVFormatContext *s, int flush)
av_write_frame(oc, NULL); av_write_frame(oc, NULL);
buffer_size = avio_close_dyn_buf(oc->pb, &buffer); buffer_size = avio_close_dyn_buf(oc->pb, &buffer);
oc->pb = NULL; oc->pb = NULL;
ret = get_chunk_filename(s, filename); av_bprint_init(&filename, 0, AV_BPRINT_SIZE_UNLIMITED);
ret = get_chunk_filename(s, &filename);
if (ret < 0) if (ret < 0)
goto fail; goto fail;
if (wc->http_method) if (wc->http_method)
if ((ret = av_dict_set(&options, "method", wc->http_method, 0)) < 0) if ((ret = av_dict_set(&options, "method", wc->http_method, 0)) < 0)
goto fail; goto fail;
ret = s->io_open(s, &pb, filename, AVIO_FLAG_WRITE, &options); ret = s->io_open(s, &pb, filename.str, AVIO_FLAG_WRITE, &options);
av_dict_free(&options); av_dict_free(&options);
if (ret < 0) if (ret < 0)
goto fail; goto fail;
avio_write(pb, buffer, buffer_size); avio_write(pb, buffer, buffer_size);
ff_format_io_close(s, &pb); ff_format_io_close(s, &pb);
fail: fail:
av_bprint_finalize(&filename, NULL);
av_free(buffer); av_free(buffer);
return (ret < 0) ? ret : 0; return (ret < 0) ? ret : 0;
} }