aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnton Khirnov <anton@khirnov.net>2016-02-19 11:17:22 +0100
committerAnton Khirnov <anton@khirnov.net>2016-02-22 11:35:57 +0100
commit832a202c47a246ed15e3edc6b05dfcfa7d82c4b2 (patch)
tree6588a47d57c9301ae3ac1d97aae81c1a1ec205f5
parent7d61dc95d741ca134d59b1f34c4e10c4c4e36f56 (diff)
downloadffmpeg-832a202c47a246ed15e3edc6b05dfcfa7d82c4b2.tar.gz
protocols: make the list of protocols static
Disallow other code to touch it directly, now it's only accessible through a blacklisting/whitelisting function.
-rw-r--r--libavformat/avio.c14
-rw-r--r--libavformat/protocols.c41
-rw-r--r--libavformat/url.h16
3 files changed, 59 insertions, 12 deletions
diff --git a/libavformat/avio.c b/libavformat/avio.c
index b4e57e943a..a9a399af93 100644
--- a/libavformat/avio.c
+++ b/libavformat/avio.c
@@ -138,6 +138,7 @@ int ffurl_connect(URLContext *uc, AVDictionary **options)
int ffurl_alloc(URLContext **puc, const char *filename, int flags,
const AVIOInterruptCB *int_cb)
{
+ const URLProtocol **protocols;
char proto_str[128], proto_nested[128], *ptr;
size_t proto_len = strspn(filename, URL_SCHEME_CHARS);
int i;
@@ -152,13 +153,18 @@ int ffurl_alloc(URLContext **puc, const char *filename, int flags,
if ((ptr = strchr(proto_nested, '+')))
*ptr = '\0';
- for (i = 0; ff_url_protocols[i]; i++) {
- const URLProtocol *up = ff_url_protocols[i];
- if (!strcmp(proto_str, up->name))
+ protocols = ffurl_get_protocols(NULL, NULL);
+ for (i = 0; protocols[i]; i++) {
+ const URLProtocol *up = protocols[i];
+ if (!strcmp(proto_str, up->name)) {
+ av_freep(&protocols);
return url_alloc_for_protocol(puc, up, filename, flags, int_cb);
+ }
if (up->flags & URL_PROTOCOL_FLAG_NESTED_SCHEME &&
- !strcmp(proto_nested, up->name))
+ !strcmp(proto_nested, up->name)) {
+ av_freep(&protocols);
return url_alloc_for_protocol(puc, up, filename, flags, int_cb);
+ }
}
*puc = NULL;
return AVERROR_PROTOCOL_NOT_FOUND;
diff --git a/libavformat/protocols.c b/libavformat/protocols.c
index 45b2a90251..b03adffa77 100644
--- a/libavformat/protocols.c
+++ b/libavformat/protocols.c
@@ -18,6 +18,9 @@
#include "config.h"
+#include "libavutil/avstring.h"
+#include "libavutil/mem.h"
+
#include "url.h"
extern const URLProtocol ff_concat_protocol;
@@ -55,7 +58,7 @@ extern const URLProtocol ff_librtmps_protocol;
extern const URLProtocol ff_librtmpt_protocol;
extern const URLProtocol ff_librtmpte_protocol;
-const URLProtocol *ff_url_protocols[] = {
+static const URLProtocol *url_protocols[] = {
#if CONFIG_CONCAT_PROTOCOL
&ff_concat_protocol,
#endif
@@ -168,17 +171,17 @@ const AVClass *ff_urlcontext_child_class_next(const AVClass *prev)
int i;
/* find the protocol that corresponds to prev */
- for (i = 0; ff_url_protocols[i]; i++) {
- if (ff_url_protocols[i]->priv_data_class == prev) {
+ for (i = 0; url_protocols[i]; i++) {
+ if (url_protocols[i]->priv_data_class == prev) {
i++;
break;
}
}
/* find next protocol with priv options */
- for (; ff_url_protocols[i]; i++)
- if (ff_url_protocols[i]->priv_data_class)
- return ff_url_protocols[i]->priv_data_class;
+ for (; url_protocols[i]; i++)
+ if (url_protocols[i]->priv_data_class)
+ return url_protocols[i]->priv_data_class;
return NULL;
}
@@ -187,7 +190,7 @@ const char *avio_enum_protocols(void **opaque, int output)
{
const URLProtocol **p = *opaque;
- p = p ? p + 1 : ff_url_protocols;
+ p = p ? p + 1 : url_protocols;
*opaque = p;
if (!*p) {
*opaque = NULL;
@@ -197,3 +200,27 @@ const char *avio_enum_protocols(void **opaque, int output)
return (*p)->name;
return avio_enum_protocols(opaque, output);
}
+
+const URLProtocol **ffurl_get_protocols(const char *whitelist,
+ const char *blacklist)
+{
+ const URLProtocol **ret;
+ int i, ret_idx = 0;
+
+ ret = av_mallocz_array(FF_ARRAY_ELEMS(url_protocols), sizeof(*ret));
+ if (!ret)
+ return NULL;
+
+ for (i = 0; url_protocols[i]; i++) {
+ const URLProtocol *up = url_protocols[i];
+
+ if (whitelist && *whitelist && !av_match_name(up->name, whitelist))
+ continue;
+ if (blacklist && *blacklist && av_match_name(up->name, blacklist))
+ continue;
+
+ ret[ret_idx++] = up;
+ }
+
+ return ret;
+}
diff --git a/libavformat/url.h b/libavformat/url.h
index 3006905446..455021964e 100644
--- a/libavformat/url.h
+++ b/libavformat/url.h
@@ -266,6 +266,20 @@ void ff_make_absolute_url(char *buf, int size, const char *base,
const AVClass *ff_urlcontext_child_class_next(const AVClass *prev);
-extern const URLProtocol *ff_url_protocols[];
+/**
+ * Construct a list of protocols matching a given whitelist and/or blacklist.
+ *
+ * @param whitelist a comma-separated list of allowed protocol names or NULL. If
+ * this is a non-empty string, only protocols in this list will
+ * be included.
+ * @param blacklist a comma-separated list of forbidden protocol names or NULL.
+ * If this is a non-empty string, all protocols in this list
+ * will be excluded.
+ *
+ * @return a NULL-terminated array of matching protocols. The array must be
+ * freed by the caller.
+ */
+const URLProtocol **ffurl_get_protocols(const char *whitelist,
+ const char *blacklist);
#endif /* AVFORMAT_URL_H */