PR #23477 opened by Niklas Haas (haasn) URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23477 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23477.patch
Hopefully resolving some of the issues seen recently. >From 569fd55649a944d2b1147eb892f0f9da75b0a1ee Mon Sep 17 00:00:00 2001 From: Niklas Haas <[email protected]> Date: Sun, 14 Jun 2026 12:27:58 +0200 Subject: [PATCH 1/5] avformat/http: properly re-set s->range_end before requests Otherwise this could leak stale values from a previous response. Sponsored-by: nxtedition AB Signed-off-by: Niklas Haas <[email protected]> --- libavformat/http.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavformat/http.c b/libavformat/http.c index e0cf9e7424..a0d84e5b09 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -567,6 +567,7 @@ int ff_http_do_new_request2(URLContext *h, const char *uri, AVDictionary **opts) s->end_chunked_post = 0; s->chunkend = 0; + s->range_end = 0; s->off = 0; s->icy_data_read = 0; @@ -1663,6 +1664,7 @@ static int http_connect(URLContext *h, const char *path, const char *local_path, s->off = 0; s->icy_data_read = 0; s->filesize = UINT64_MAX; + s->range_end = 0; s->willclose = 0; s->end_chunked_post = 0; s->end_header = 0; -- 2.52.0 >From 5ddb7fe915e4c5085081659104beb70f5779c97e Mon Sep 17 00:00:00 2001 From: Niklas Haas <[email protected]> Date: Sun, 14 Jun 2026 12:34:34 +0200 Subject: [PATCH 2/5] avformat/http: make short-seek logic more robust This avoids an underflow if short_seek is negative, as well as a possible underflow if the read position is somehow past range_end (e.g. if the HTTP server malicously lied about the content range but gave us more bytes anyway) Sponsored-by: nxtedition AB Signed-off-by: Niklas Haas <[email protected]> --- libavformat/http.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/libavformat/http.c b/libavformat/http.c index a0d84e5b09..e0dac4f8f8 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -2143,8 +2143,14 @@ static int64_t http_seek_internal(URLContext *h, int64_t off, int whence, int fo memcpy(old_buf, s->buf_ptr, old_buf_size); /* try to reuse existing connection for small seeks */ - uint64_t remaining = s->range_end - old_off - old_buf_size; - if (s->hd && !s->willclose && s->range_end && remaining <= ffurl_get_short_seek(h)) { + int short_seek = ffurl_get_short_seek(h); + uint64_t old_read_pos = old_off + old_buf_size; + if (s->hd && !s->willclose && s->range_end && short_seek > 0 && + old_read_pos + short_seek >= s->range_end) + { + uint64_t remaining = s->range_end - old_read_pos; + av_assert1(remaining <= short_seek); + /* drain remaining data left on the wire from previous request */ av_log(h, AV_LOG_DEBUG, "Soft-seeking to offset %"PRIu64" by draining " "%"PRIu64" remaining byte(s)\n", s->off, remaining); -- 2.52.0 >From e06a89629e212726a49f6dc2152b6370d49c8671 Mon Sep 17 00:00:00 2001 From: Niklas Haas <[email protected]> Date: Sun, 14 Jun 2026 12:53:36 +0200 Subject: [PATCH 3/5] avformat/http: don't return EOF unless we actually read all bytes Otherwise, this masquerades failure due to I/O as legitimate EOFs. Sponsored-by: nxtedition AB Signed-off-by: Niklas Haas <[email protected]> --- libavformat/http.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/http.c b/libavformat/http.c index e0dac4f8f8..30748bb28d 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -1834,7 +1834,7 @@ static int http_read_stream(URLContext *h, uint8_t *buf, int size) int conn_attempts = 1; if (!s->hd) - return AVERROR_EOF; + return s->off < s->filesize ? AVERROR(EIO) : AVERROR_EOF; if (s->end_chunked_post && !s->end_header) { err = http_read_header(h); -- 2.52.0 >From 56eb5f53a29edafbf03cc1f4f86467c19ba2f1cf Mon Sep 17 00:00:00 2001 From: Niklas Haas <[email protected]> Date: Sun, 14 Jun 2026 13:02:55 +0200 Subject: [PATCH 4/5] avformat/http: only re-use old connection if valid Otherwise, this might leak stale bytes that were already drained by the HTTP soft-seek attempt. Sponsored-by: nxtedition AB Signed-off-by: Niklas Haas <[email protected]> --- libavformat/http.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/libavformat/http.c b/libavformat/http.c index 30748bb28d..ce98c01ae4 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -2169,14 +2169,16 @@ static int64_t http_seek_internal(URLContext *h, int64_t off, int whence, int fo s->hd = NULL; } - /* if it fails, continue on old connection */ if ((ret = http_open_cnx(h, &options)) < 0) { + /* if it fails, continue on old connection if possible */ + if (old_hd) { + memcpy(s->buffer, old_buf, old_buf_size); + s->buf_ptr = s->buffer; + s->buf_end = s->buffer + old_buf_size; + s->hd = old_hd; + s->off = old_off; + } av_dict_free(&options); - memcpy(s->buffer, old_buf, old_buf_size); - s->buf_ptr = s->buffer; - s->buf_end = s->buffer + old_buf_size; - s->hd = old_hd; - s->off = old_off; return ret; } av_dict_free(&options); -- 2.52.0 >From 640164fd2d1860694f28654bf6db08e3edee4327 Mon Sep 17 00:00:00 2001 From: Niklas Haas <[email protected]> Date: Sun, 14 Jun 2026 13:03:34 +0200 Subject: [PATCH 5/5] avformat/http: properly fall back on soft seek failure If the HTTP server still has stale bytes in the TCP receive buffer, but the underlying conection was already closed, then the http_open_cnx() call might fail even though we successfully drained the previous request. In this case, there is no proper fallback to a new connection, leading to sudden truncation. Sponsored-by: nxtedition AB Signed-off-by: Niklas Haas <[email protected]> --- libavformat/http.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libavformat/http.c b/libavformat/http.c index ce98c01ae4..28158db491 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -2163,6 +2163,13 @@ static int64_t http_seek_internal(URLContext *h, int64_t off, int whence, int fo } remaining -= ret; } + + ret = http_open_cnx(h, &options); + if (ret < 0) { + /* fall back to normal reconnection */ + ffurl_closep(&s->hd); + old_hd = NULL; + } } else { /* can't soft seek; always open new connection */ old_hd = s->hd; -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
