[FFmpeg-devel] [PATCH] Handling special characters in a URL.

Senthilnathan Maadasamy senthilnathan.maadasamy at gmail.com
Sun Feb 3 20:55:01 CET 2013


Implements Percent Encoding of URLs based on RFC 3986.
Fixes Ticket 2031

Signed-off-by: Senthilnathan M <senthilnathan.maadasamy at gmail.com>
---
 libavformat/avformat.h |    9 +++++++++
 libavformat/utils.c    |   28 ++++++++++++++++++++++++++++
 2 files changed, 37 insertions(+)

diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index 8330c6b..1b1d86e 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -1963,6 +1963,15 @@ int av_index_search_timestamp(AVStream *st, int64_t
timestamp, int flags);
 int av_add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
                        int size, int distance, int flags);

+/**
+ * Percent encodes parts of a URL string based on RFC 3986.  Encodes the
+ * component string in place.
+ *
+ * @param component portion of a URL (e.g. protocol, hostname, path)
+ * @param allowed These extra permissible characters do not get encoded
+ * @param comp_size the size of the component buffer
+ */
+void av_url_percent_encode(char *component, const char *allowed, int
comp_size);

 /**
  * Split a URL string into components.
diff --git a/libavformat/utils.c b/libavformat/utils.c
index 97d6558..a51b867 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -3751,6 +3751,32 @@ 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);
 }

+void av_url_percent_encode(char *component, const char *allowed, int
comp_size)
+{
+    char enc[MAX_URL_SIZE], c;
+    const char *src = component;
+    int enc_len = 0;
+
+    if (!src) return;
+
+    while (c = *src) {
+        if (isalnum(c)
+            || c == '-' || c == '.' || c == '_' || c == '~' || c == '%'
+            || (allowed && strchr(allowed, c))) {
+            if (enc_len+1 >= MAX_URL_SIZE) break;
+            enc[enc_len] = c;
+            enc_len++;
+        } else {
+            if (enc_len+3 >= MAX_URL_SIZE) break;
+            snprintf(&enc[enc_len], 4, "%%%02x", c);
+            enc_len+=3;
+        }
+        src++;
+    }
+    enc[enc_len] = '\0';
+    av_strlcpy(component, enc, comp_size);
+}
+
 void av_url_split(char *proto, int proto_size,
                   char *authorization, int authorization_size,
                   char *hostname, int hostname_size,
@@ -3814,6 +3840,8 @@ void av_url_split(char *proto, int proto_size,
             av_strlcpy(hostname, p,
                        FFMIN(ls + 1 - p, hostname_size));
     }
+    av_url_percent_encode(hostname, NULL, hostname_size);
+    av_url_percent_encode(path, "/?", path_size);
 }

 char *ff_data_to_hex(char *buff, const uint8_t *src, int s, int lowercase)
-- 
1.7.9.5


More information about the ffmpeg-devel mailing list