mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2026-08-10 07:37:43 +00:00
avformat/libcurl: respect format whitelist
And also set a reasonable default whitelist. This is especially important because libcurl supports a much wider range of protocols than FFmpeg, including e.g. smtps, telnet, gopher, etc. We have to include "libcurl" in libcurl's own default whitelist, otherwise it will refuse te recursively open itself for e.g. HLS. Sponsored-by: nxtedition AB Signed-off-by: Niklas Haas <git@haasn.dev>
This commit is contained in:
committed by
Kacper Michajłow
parent
c70d777f7f
commit
e11cec1059
@@ -28,6 +28,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "libavutil/avstring.h"
|
||||
#include "libavutil/bprint.h"
|
||||
#include "libavutil/error.h"
|
||||
#include "libavutil/fifo.h"
|
||||
#include "libavutil/log.h"
|
||||
@@ -699,6 +700,44 @@ static struct curl_slist *build_headers(CurlContext *c)
|
||||
return list;
|
||||
}
|
||||
|
||||
static int setup_protocols(CurlContext *c)
|
||||
{
|
||||
const char *wl = c->h->protocol_whitelist;
|
||||
const char *bl = c->h->protocol_blacklist;
|
||||
if (!wl && !bl)
|
||||
return 0;
|
||||
|
||||
AVBPrint bp;
|
||||
av_bprint_init(&bp, 0, AV_BPRINT_SIZE_AUTOMATIC);
|
||||
|
||||
curl_version_info_data *info = curl_version_info(CURLVERSION_NOW);
|
||||
for (const char *const *p = info->protocols; *p; p++) {
|
||||
const char *proto = *p;
|
||||
if (av_strcasecmp(proto, "http") && av_strcasecmp(proto, "https"))
|
||||
continue; /* only http(s) are supported by libcurl.c at the moment */
|
||||
if (wl && av_match_list(proto, wl, ',') <= 0)
|
||||
continue;
|
||||
if (bl && av_match_list(proto, bl, ',') > 0)
|
||||
continue;
|
||||
if (bp.len)
|
||||
av_bprint_chars(&bp, ',', 1);
|
||||
av_bprintf(&bp, "%s", proto);
|
||||
}
|
||||
|
||||
if (!av_bprint_is_complete(&bp))
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
if (!bp.len) {
|
||||
av_log(c->h, AV_LOG_ERROR, "Set of allowed protocols is empty.\n");
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
curl_easy_setopt(c->easy, CURLOPT_PROTOCOLS_STR, bp.str);
|
||||
curl_easy_setopt(c->easy, CURLOPT_REDIR_PROTOCOLS_STR, bp.str);
|
||||
av_bprint_finalize(&bp, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void setup_curl(CurlContext *c)
|
||||
{
|
||||
CURL *e = c->easy;
|
||||
@@ -857,6 +896,11 @@ static int libcurl_open(URLContext *h, const char *url, int flags,
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = setup_protocols(c);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
|
||||
setup_curl(c);
|
||||
|
||||
ret = curl_dispatch(c->loop, CMD_ADD, c, 0, 0);
|
||||
@@ -1042,4 +1086,5 @@ const URLProtocol ff_libcurl_protocol = {
|
||||
.priv_data_size = sizeof(CurlContext),
|
||||
.priv_data_class = &libcurl_context_class,
|
||||
.flags = URL_PROTOCOL_FLAG_NETWORK,
|
||||
.default_whitelist = "http,https,libcurl",
|
||||
};
|
||||
Reference in New Issue
Block a user