protocols: make the list of protocols static
authorAnton Khirnov <anton@khirnov.net>
Fri, 19 Feb 2016 10:17:22 +0000 (11:17 +0100)
committerAnton Khirnov <anton@khirnov.net>
Mon, 22 Feb 2016 10:35:57 +0000 (11:35 +0100)
Disallow other code to touch it directly, now it's only accessible
through a blacklisting/whitelisting function.

libavformat/avio.c
libavformat/protocols.c
libavformat/url.h

index b4e57e9..a9a399a 100644 (file)
@@ -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;
index 45b2a90..b03adff 100644 (file)
@@ -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;
+}
index 3006905..4550219 100644 (file)
@@ -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 */