Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
From: Niklas Haas via ffmpeg-devel <ffmpeg-devel@ffmpeg.org>
To: ffmpeg-devel@ffmpeg.org
Cc: Niklas Haas <code@ffmpeg.org>
Subject: [FFmpeg-devel] [PR] Various minor fixes to the HTTP protocol (PR #21765)
Date: Sun, 15 Feb 2026 17:33:32 -0000
Message-ID: <177117681341.25.2921584865392573526@009cbcb3d8cd> (raw)

PR #21765 opened by Niklas Haas (haasn)
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/21765
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/21765.patch

Mostly concerning errors and edge cases


>From a0f4118bc3e730c22a9e3e51f47dd922abfd471c Mon Sep 17 00:00:00 2001
From: Niklas Haas <git@haasn.dev>
Date: Sun, 15 Feb 2026 18:03:38 +0100
Subject: [PATCH 1/7] avformat/http: avoid int overflow

This was meant to accumulate int64_t timestamp values.

Fixes: b8daba42cdb4b91e793b91ef3055797b0b7611bd
---
 libavformat/http.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libavformat/http.c b/libavformat/http.c
index 805e3eff9f..8835bb9743 100644
--- a/libavformat/http.c
+++ b/libavformat/http.c
@@ -154,8 +154,8 @@ typedef struct HTTPContext {
     int nb_retries;
     int nb_reconnects;
     int nb_redirects;
-    int sum_latency; /* divide by nb_requests */
-    int max_latency;
+    int64_t sum_latency; /* divide by nb_requests */
+    int64_t max_latency;
 } HTTPContext;
 
 #define OFFSET(x) offsetof(HTTPContext, x)
-- 
2.52.0


>From b0fc5f315e52eff270b8dcdc99b2094bee5b802f Mon Sep 17 00:00:00 2001
From: Niklas Haas <git@haasn.dev>
Date: Sun, 15 Feb 2026 18:09:15 +0100
Subject: [PATCH 2/7] avformat/http: fix http_connect() offset mismatch error
 code

This (arbitrarily) returns -1, which happens to be AVERROR(EPERM) on my
machine. Return the more descriptive AVERORR(EIO) instead.

Also add a log message to explain what's going on.
---
 libavformat/http.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/libavformat/http.c b/libavformat/http.c
index 8835bb9743..a0ed3d5c30 100644
--- a/libavformat/http.c
+++ b/libavformat/http.c
@@ -1679,7 +1679,15 @@ static int http_connect(URLContext *h, const char *path, const char *local_path,
     if (s->new_location)
         s->off = off;
 
-    err = (off == s->off) ? 0 : -1;
+    if (off != s->off) {
+        av_log(h, AV_LOG_ERROR,
+               "Unexpected offset: expected %"PRIu64", got %"PRIu64"\n",
+               off, s->off);
+        err = AVERROR(EIO);
+        goto done;
+    }
+
+    err = 0;
 done:
     av_freep(&authstr);
     av_freep(&proxyauthstr);
-- 
2.52.0


>From 1e776cb914d760a161524cc6bf077887944952b5 Mon Sep 17 00:00:00 2001
From: Niklas Haas <git@haasn.dev>
Date: Sun, 15 Feb 2026 18:12:18 +0100
Subject: [PATCH 3/7] avformat/http: avoid circular redirect infinite loop

If there is a circular redirect, both redirects will get cached, at which
point the next loop iteration will be stuck infinitely redirecting internally
in the cycle.

Avoid this by treating cached redirects as identical to uncached redirects
for the purposes of incrementing the redirect loop counter.
---
 libavformat/http.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/libavformat/http.c b/libavformat/http.c
index a0ed3d5c30..12d7ee7229 100644
--- a/libavformat/http.c
+++ b/libavformat/http.c
@@ -416,6 +416,8 @@ redo:
             ret = AVERROR(ENOMEM);
             goto fail;
         }
+        if (redirects++ >= MAX_REDIRECTS)
+            return AVERROR(EIO);
         goto redo;
     }
 
-- 
2.52.0


>From 47d47c38fe25795e8a9f31892be8d64d89244eff Mon Sep 17 00:00:00 2001
From: Niklas Haas <git@haasn.dev>
Date: Sun, 15 Feb 2026 18:17:46 +0100
Subject: [PATCH 4/7] avformat/http: restore offset on http_open_cnx() failure

The retry path restores this offset, but the failure path does not. This
is especially important for the case of the continuation handler in
http_read_stream(), which may result in subsequent loop iterations (after
repeated failures to read additional data) seeking to the wrong offset.
---
 libavformat/http.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libavformat/http.c b/libavformat/http.c
index 12d7ee7229..29cf82d229 100644
--- a/libavformat/http.c
+++ b/libavformat/http.c
@@ -507,6 +507,7 @@ redo:
     return 0;
 
 fail:
+    s->off = off;
     if (s->hd)
         ffurl_closep(&s->hd);
     if (ret < 0)
-- 
2.52.0


>From de5fb6f065782e5686e81757c7bd9db6887c69cf Mon Sep 17 00:00:00 2001
From: Niklas Haas <git@haasn.dev>
Date: Sun, 15 Feb 2026 18:28:29 +0100
Subject: [PATCH 5/7] avformat/http: move retry label (cosmetic)

Move this closer to the corresponding `goto`. From the PoV of the control
flow, these placements are completely identical.
---
 libavformat/http.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/libavformat/http.c b/libavformat/http.c
index 29cf82d229..7465798c22 100644
--- a/libavformat/http.c
+++ b/libavformat/http.c
@@ -1834,6 +1834,8 @@ static int http_read_stream(URLContext *h, uint8_t *buf, int size)
     if (s->compressed)
         return http_buf_read_compressed(h, buf, size);
 #endif /* CONFIG_ZLIB */
+
+retry:
     read_ret = http_buf_read(h, buf, size);
     while (read_ret < 0) {
         uint64_t target = h->is_streamed ? 0 : s->off;
@@ -1881,7 +1883,6 @@ static int http_read_stream(URLContext *h, uint8_t *buf, int size)
             return read_ret;
         }
 
-retry:
         read_ret = http_buf_read(h, buf, size);
     }
 
-- 
2.52.0


>From bd68207653d5468748ab953a87211fa1e1fc0e64 Mon Sep 17 00:00:00 2001
From: Niklas Haas <git@haasn.dev>
Date: Sun, 15 Feb 2026 18:29:07 +0100
Subject: [PATCH 6/7] avformat/http: close stale connection on wrong seek

If http_seek_internal() gives us an unexpected position, we should
close the connection to avoid leaking reading incorrect bytes on subsequent
reads.
---
 libavformat/http.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libavformat/http.c b/libavformat/http.c
index 7465798c22..1fb563a010 100644
--- a/libavformat/http.c
+++ b/libavformat/http.c
@@ -1879,6 +1879,7 @@ retry:
         conn_attempts++;
         seek_ret = http_seek_internal(h, target, SEEK_SET, 1);
         if (seek_ret >= 0 && seek_ret != target) {
+            ffurl_close(&s->hd);
             av_log(h, AV_LOG_ERROR, "Failed to reconnect at %"PRIu64".\n", target);
             return read_ret;
         }
-- 
2.52.0


>From c8867f522d301db77d9d54405701c4c8012a0641 Mon Sep 17 00:00:00 2001
From: Niklas Haas <git@haasn.dev>
Date: Sun, 15 Feb 2026 18:31:01 +0100
Subject: [PATCH 7/7] avformat/http: fix Cache-Control header parsing

This was calling atoi() on `p + offset`, which is nonsense (p may point to
the start of the cache-control string, which does not necessarilly coincide
with the location of the max-age value). Based on the code, the intent
was clearly to parse the value *after* the matched substring.
---
 libavformat/http.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavformat/http.c b/libavformat/http.c
index 1fb563a010..e5124a5fe0 100644
--- a/libavformat/http.c
+++ b/libavformat/http.c
@@ -1160,7 +1160,7 @@ static void parse_cache_control(HTTPContext *s, const char *p)
     }
 
     if (age) {
-        s->expires = time(NULL) + atoi(p + offset);
+        s->expires = time(NULL) + atoi(age + offset);
     }
 }
 
-- 
2.52.0

_______________________________________________
ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org
To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org

                 reply	other threads:[~2026-02-15 17:34 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=177117681341.25.2921584865392573526@009cbcb3d8cd \
    --to=ffmpeg-devel@ffmpeg.org \
    --cc=code@ffmpeg.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
		ffmpegdev@gitmailbox.com
	public-inbox-index ffmpegdev

Example config snippet for mirrors.


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git