OSDN Git Service

lavf/utils: add support for special characters encoding in URL
authorSenthilnathan M <senthilnathan.maadasamy@gmail.com>
Sun, 10 Feb 2013 17:38:52 +0000 (23:08 +0530)
committerStefano Sabatini <stefasab@gmail.com>
Wed, 27 Feb 2013 23:39:17 +0000 (00:39 +0100)
In particular, fix trac ticket #2031.

Signed-off-by: Senthilnathan M <senthilnathan.maadasamy@gmail.com>
Signed-off-by: Stefano Sabatini <stefasab@gmail.com>
libavformat/utils.c

index 9bd2d0c..47637b9 100644 (file)
@@ -3767,6 +3767,50 @@ void av_pkt_dump_log2(void *avcl, int level, AVPacket *pkt, int dump_payload,
     pkt_dump_internal(avcl, NULL, level, pkt, dump_payload, st->time_base);
 }
 
+/**
+ * Percent encode part of an URL string according to RFC 3986.
+ *
+ * @param component      portion of an URL (e.g. protocol, hostname, path) to
+ *                       percent-encode. This will be percent-encoded in place.
+ * @param allowed        string containing the allowed characters which must not be
+ *                       encoded. It may be NULL if there are no such characters.
+ * @param component_size size in bytes of the component buffer
+ */
+static void percent_encode_url(char *component, size_t component_size,
+                               const char *allowed)
+{
+    char enc[MAX_URL_SIZE], c;
+    int enc_len = 0;
+    char *src = component;
+
+    while (c = *src) {
+        if (isalnum(c) || strchr("-._~%", c) ||
+            (allowed && strchr(allowed, c))) {
+            if (enc_len+1 < MAX_URL_SIZE)
+                enc[enc_len] = c;
+            else
+                break;
+            enc_len++;
+        } else {
+            if (enc_len+3 < MAX_URL_SIZE)
+                snprintf(&enc[enc_len], 4, "%%%02x", c);
+            else
+                break;
+            enc_len += 3;
+        }
+        src++;
+    }
+
+    enc[enc_len++] = '\0';
+    if (enc_len <= component_size) {
+        av_strlcpy(component, enc, component_size);
+    } else {
+        av_log(NULL, AV_LOG_ERROR,
+               "Skipping percent-encoding for string '%s' since buffer is too small\n",
+               component);
+    }
+}
+
 void av_url_split(char *proto, int proto_size,
                   char *authorization, int authorization_size,
                   char *hostname, int hostname_size,
@@ -3830,6 +3874,9 @@ void av_url_split(char *proto, int proto_size,
             av_strlcpy(hostname, p,
                        FFMIN(ls + 1 - p, hostname_size));
     }
+
+    percent_encode_url(hostname, hostname_size, NULL);
+    percent_encode_url(path, path_size, "/?");
 }
 
 char *ff_data_to_hex(char *buff, const uint8_t *src, int s, int lowercase)