>From d88b58028c0d314e461fb4b894b190cbf4175fde Mon Sep 17 00:00:00 2001
From: denim2x <denim2x@cyberdude.com>
Date: Thu, 13 Apr 2017 14:20:48 +0300
Subject: [PATCH] make libavformat more tolerant (fixes #2617)

new compilation flags + some refactored code

Signed-off-by: denim2x <denim2x@cyberdude.com>
---
 Changelog          |  4 ++++
 libavformat/hls.c  |  2 ++
 libavformat/http.c | 34 +++++++++++++++++++++++-----------
 3 files changed, 29 insertions(+), 11 deletions(-)

diff --git a/Changelog b/Changelog
index e76b324..d9388d4 100644
--- a/Changelog
+++ b/Changelog
@@ -3,6 +3,10 @@ releases are sorted from youngest to oldest.
 
 version <next>:
 
+version 3.3.1:
+- when compiled with 'FORBID_EXTM3U_LINES' - terminates when '#EXTM3U' is found
+- when compiled with 'FORBID_FAULTY_HTTP_HEADERS' - terminates on faulty HTTP headers
+
 version 3.3:
 - CrystalHD decoder moved to new decode API
 - add internal ebur128 library, remove external libebur128 dependency
diff --git a/libavformat/hls.c b/libavformat/hls.c
index bac53a4..afb9bc4 100644
--- a/libavformat/hls.c
+++ b/libavformat/hls.c
@@ -691,10 +691,12 @@ static int parse_playlist(HLSContext *c, const char *url,
         url = new_url;
 
     read_chomp_line(in, line, sizeof(line));
+#ifdef FORBID_EXTM3U_LINES
     if (strcmp(line, "#EXTM3U")) {
         ret = AVERROR_INVALIDDATA;
         goto fail;
     }
+#endif
 
     if (pls) {
         free_segment_list(pls);
diff --git a/libavformat/http.c b/libavformat/http.c
index 293a8a7..7aa7e39 100644
--- a/libavformat/http.c
+++ b/libavformat/http.c
@@ -314,21 +314,29 @@ int ff_http_do_new_request(URLContext *h, const char *uri)
     return ret;
 }
 
-int ff_http_averror(int status_code, int default_averror)
+int _ff_http_averror(int status_code, int default_averror, int client_override)
 {
-    switch (status_code) {
-        case 400: return AVERROR_HTTP_BAD_REQUEST;
-        case 401: return AVERROR_HTTP_UNAUTHORIZED;
-        case 403: return AVERROR_HTTP_FORBIDDEN;
-        case 404: return AVERROR_HTTP_NOT_FOUND;
-        default: break;
+    if (client_override) {
+        switch (status_code) {
+            case 400: return AVERROR_HTTP_BAD_REQUEST;
+            case 401: return AVERROR_HTTP_UNAUTHORIZED;
+            case 403: return AVERROR_HTTP_FORBIDDEN;
+            case 404: return AVERROR_HTTP_NOT_FOUND;
+            default: break;
+        }
     }
     if (status_code >= 400 && status_code <= 499)
-        return AVERROR_HTTP_OTHER_4XX;
-    else if (status_code >= 500)
+        return client_override;
+
+    if (status_code >= 500)
         return AVERROR_HTTP_SERVER_ERROR;
-    else
-        return default_averror;
+
+    return default_averror;
+}
+
+int ff_http_averror(int status_code, int default_averror)
+{
+    return _ff_http_averror(status_code, default_averror, AVERROR_HTTP_OTHER_4XX);
 }
 
 static int http_write_reply(URLContext* h, int status_code)
@@ -590,7 +598,11 @@ static int check_http_code(URLContext *h, int http_code, const char *end)
         (http_code != 407 || s->proxy_auth_state.auth_type != HTTP_AUTH_NONE)) {
         end += strspn(end, SPACE_CHARS);
         av_log(h, AV_LOG_WARNING, "HTTP error %d %s\n", http_code, end);
+#ifdef FORBID_FAULTY_HTTP_HEADERS
         return ff_http_averror(http_code, AVERROR(EIO));
+#else
+        return _ff_http_averror(http_code, AVERROR(EIO), 0);
+#endif
     }
     return 0;
 }
-- 
2.8.3

