Le decadi 20 ventôse, an CCXXIII, Michael Niedermayer a écrit :
> iam fine with either, i was just trying to be completely correct
> which may be overkill and indeed make the code less readable for no
> gain

What about the attached patch?

Regards,

-- 
  Nicolas George
From 28fc644a1d7e4f73921bbc9ab7c103de922480f1 Mon Sep 17 00:00:00 2001
From: Nicolas George <geo...@nsup.org>
Date: Tue, 10 Mar 2015 13:43:17 +0100
Subject: [PATCH] lavf/http: cleanup headers option string.

Replace any sequence of CR or LF with a single CRLF
and make sure there is a final CRLF.

Signed-off-by: Nicolas George <geo...@nsup.org>
---
 libavformat/http.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 65 insertions(+)

diff --git a/libavformat/http.c b/libavformat/http.c
index 55dcb6e..5371e92 100644
--- a/libavformat/http.c
+++ b/libavformat/http.c
@@ -25,6 +25,7 @@
 #include <zlib.h>
 #endif /* CONFIG_ZLIB */
 
+#include "libavutil/avassert.h"
 #include "libavutil/avstring.h"
 #include "libavutil/opt.h"
 
@@ -292,6 +293,67 @@ int ff_http_averror(int status_code, int default_averror)
         return default_averror;
 }
 
+/**
+ * Cleanup HTTP headers option string
+ * Replace any sequence of CR or LF with a single CRLF (empty lines are not
+ * valid in HTTP) and make sure there is a final CRLF.
+ */
+static int cleanup_headers_option(char **str)
+{
+    char *in = *str, *out, *p, *q;
+    size_t nb_chars = 0, nb_lf = 0, out_size;
+    int clean = 1, eol = 0;
+
+    if (!in)
+        return 0;
+    p = in;
+    while (*p) {
+        if (*p == '\n' || *p == '\r') {
+            nb_lf++;
+            eol = 1;
+            if (p[0] != '\r' || p[1] != '\n' || p[2] == '\n' || p[2] == '\r')
+                clean = 0;
+            while (*p == '\n' || *p == '\r')
+                p++;
+        } else {
+            nb_chars++;
+            eol = 0;
+            p++;
+        }
+    }
+    if (clean && eol)
+        return 0;
+    if (!eol)
+        nb_lf++;
+    if (nb_lf >= (SIZE_MAX - nb_chars) / 2 - 1)
+        return AVERROR(ENOMEM);
+    out_size = nb_chars + nb_lf * 2 + 1;
+    out = av_realloc(NULL, out_size);
+    if (!out)
+        return AVERROR(ENOMEM);
+    p = in;
+    q = out;
+    while (*p) {
+        if (*p == '\n' || *p == '\r') {
+            *(q++) = '\r';
+            *(q++) = '\n';
+            while (*p == '\n' || *p == '\r')
+                p++;
+        } else {
+            *(q++) = *(p++);
+        }
+    }
+    if (!eol) {
+        *(q++) = '\r';
+        *(q++) = '\n';
+    }
+    *(q++) = 0;
+    av_assert0(q == out + out_size);
+    av_free(in);
+    *str = out;
+    return 0;
+}
+
 static int http_open(URLContext *h, const char *uri, int flags,
                      AVDictionary **options)
 {
@@ -310,6 +372,9 @@ static int http_open(URLContext *h, const char *uri, int flags,
     if (options)
         av_dict_copy(&s->chained_options, *options, 0);
 
+    ret = cleanup_headers_option(&s->headers);
+    if (ret < 0)
+        return ret;
     if (s->headers) {
         int len = strlen(s->headers);
         if (len < 2 || strcmp("\r\n", s->headers + len - 2))
-- 
2.1.4

Attachment: signature.asc
Description: Digital signature

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Reply via email to