Vulnerability: Heap-based buffer overflow in libavformat/http.c in FFmpeg before 2.8.10, 3.0.x before 3.0.5, 3.1.x before 3.1.6, and 3.2.x before 3.2.2 allows remote web servers to execute arbitrary code via a negative chunk size in an HTTP response.
Vulnerability ID: CVE-2016-10190
CWE: CWE-119
Severity score: 6.4
Project: https://github.com/FFmpeg/FFmpeg
Published: 2017-02-09
File: libavformat/http.c
Commit message: http: make length/offset-related variables unsigned.

Fixes #5992, reported and found by Paul Cher <paulcher@icloud.com>.
Commit author: Ronald S. Bultje

Vulnerable version (before fix):
 typedef struct HTTPContext {     int line_count;     int http_code;     /* Used if "Transfer-Encoding: chunked" otherwise -1. */     int64_t chunksize;     int64_t off, end_off, filesize;     char *location;     HTTPAuthState auth_state;     HTTPAuthState proxy_auth_state; typedef struct HTTPContext {     AVDictionary *cookie_dict;     int icy;     /* how much data was read since the last ICY metadata packet */     int icy_data_read;     /* after how many bytes of read data a new metadata packet will be found */     int icy_metaint;     char *icy_metadata_headers;     char *icy_metadata_packet;     AVDictionary *metadata; static int http_open(URLContext *h, const char *uri, int flags,     else         h->is_streamed = 1;      s->filesize = -1;     s->location = av_strdup(uri);     if (!s->location)         return AVERROR(ENOMEM); static void parse_content_range(URLContext *h, const char *p)      if (!strncmp(p, "bytes ", 6)) {         p     += 6;         s->off = strtoll(p, NULL, 10);         if ((slash = strchr(p, '/')) && strlen(slash) > 0)             s->filesize = strtoll(slash + 1, NULL, 10);     }     if (s->seekable == -1 && (!s->is_akamai || s->filesize != 2147483647))         h->is_streamed = 0; /* we _can_ in fact seek */ static int process_line(URLContext *h, char *line, int line_count,             if ((ret = parse_location(s, p)) < 0)                 return ret;             *new_location = 1;         } else if (!av_strcasecmp(tag, "Content-Length") && s->filesize == -1) {             s->filesize = strtoll(p, NULL, 10);         } else if (!av_strcasecmp(tag, "Content-Range")) {             parse_content_range(h, p);         } else if (!av_strcasecmp(tag, "Accept-Ranges") && static int process_line(URLContext *h, char *line, int line_count,             h->is_streamed = 0;         } else if (!av_strcasecmp(tag, "Transfer-Encoding") &&                    !av_strncasecmp(p, "chunked", 7)) {             s->filesize  = -1;             s->chunksize = 0;         } else if (!av_strcasecmp(tag, "WWW-Authenticate")) {             ff_http_auth_handle_header(&s->auth_state, tag, p); static int process_line(URLContext *h, char *line, int line_count,             if (parse_cookie(s, p, &s->cookie_dict))                 av_log(h, AV_LOG_WARNING, "Unable to parse '%s'\n", p);         } else if (!av_strcasecmp(tag, "Icy-MetaInt")) {             s->icy_metaint = strtoll(p, NULL, 10);         } else if (!av_strncasecmp(tag, "Icy-", 4)) {             if ((ret = parse_icy(s, tag, p)) < 0)                 return ret; static int http_read_header(URLContext *h, int *new_location)     char line[MAX_URL_SIZE];     int err = 0;      s->chunksize = -1;      for (;;) {         if ((err = http_get_line(s, line, sizeof(line))) < 0) static int http_connect(URLContext *h, const char *path, const char *local_path,     int post, err;     char headers[HTTP_HEADERS_SIZE] = "";     char *authstr = NULL, *proxyauthstr = NULL;     int64_t off = s->off;     int len = 0;     const char *method;     int send_expect_100 = 0; static int http_connect(URLContext *h, const char *path, const char *local_path,     // server supports seeking by analysing the reply headers.     if (!has_header(s->headers, "\r\nRange: ") && !post && (s->off > 0 || s->end_off || s->seekable == -1)) {         len += av_strlcatf(headers + len, sizeof(headers) - len,                            "Range: bytes=%"PRId64"-", s->off);         if (s->end_off)             len += av_strlcatf(headers + len, sizeof(headers) - len,                                "%"PRId64, s->end_off - 1); static int http_connect(URLContext *h, const char *path, const char *local_path,     s->line_count       = 0;     s->off              = 0;     s->icy_data_read    = 0;     s->filesize         = -1;     s->willclose        = 0;     s->end_chunked_post = 0;     s->end_header       = 0; static int http_buf_read(URLContext *h, uint8_t *buf, int size)         memcpy(buf, s->buf_ptr, len);         s->buf_ptr += len;     } else {         int64_t target_end = s->end_off ? s->end_off : s->filesize;         if ((!s->willclose || s->chunksize < 0) &&             target_end >= 0 && s->off >= target_end)             return AVERROR_EOF;         len = ffurl_read(s->hd, buf, size);         if (!len && (!s->willclose || s->chunksize < 0) &&             target_end >= 0 && s->off < target_end) {             av_log(h, AV_LOG_ERROR,                    "Stream ends prematurely at %"PRId64", should be %"PRId64"\n",                    s->off, target_end                   );             return AVERROR(EIO); static int http_read_stream(URLContext *h, uint8_t *buf, int size)             return err;     }      if (s->chunksize >= 0) {         if (!s->chunksize) {             char line[32];  static int http_read_stream(URLContext *h, uint8_t *buf, int size)                         return err;                 } while (!*line);    /* skip CR LF from last chunk */                  s->chunksize = strtoll(line, NULL, 16);                  av_log(NULL, AV_LOG_TRACE, "Chunked encoding data size: %"PRId64"'\n",                         s->chunksize);                  if (!s->chunksize)                     return 0;         }         size = FFMIN(size, s->chunksize);     } static int http_read_stream(URLContext *h, uint8_t *buf, int size)     read_ret = http_buf_read(h, buf, size);     if (   (read_ret  < 0 && s->reconnect        && (!h->is_streamed || s->reconnect_streamed) && s->filesize > 0 && s->off < s->filesize)         || (read_ret == 0 && s->reconnect_at_eof && (!h->is_streamed || s->reconnect_streamed))) {         int64_t target = h->is_streamed ? 0 : s->off;          if (s->reconnect_delay > s->reconnect_delay_max)             return AVERROR(EIO);          av_log(h, AV_LOG_INFO, "Will reconnect at %"PRId64" error=%s.\n", s->off, av_err2str(read_ret));         av_usleep(1000U*1000*s->reconnect_delay);         s->reconnect_delay = 1 + 2*s->reconnect_delay;         seek_ret = http_seek_internal(h, target, SEEK_SET, 1);         if (seek_ret != target) {             av_log(h, AV_LOG_ERROR, "Failed to reconnect at %"PRId64".\n", target);             return read_ret;         }  static int store_icy(URLContext *h, int size) {     HTTPContext *s = h->priv_data;     /* until next metadata packet */     int remaining = s->icy_metaint - s->icy_data_read;      if (remaining < 0)         return AVERROR_INVALIDDATA;      if (!remaining) {         /* The metadata packet is variable sized. It has a 1 byte header static int64_t http_seek_internal(URLContext *h, int64_t off, int whence, int fo {     HTTPContext *s = h->priv_data;     URLContext *old_hd = s->hd;     int64_t old_off = s->off;     uint8_t old_buf[BUFFER_SIZE];     int old_buf_size, ret;     AVDictionary *options = NULL; static int64_t http_seek_internal(URLContext *h, int64_t off, int whence, int fo              ((whence == SEEK_CUR && off == 0) ||               (whence == SEEK_SET && off == s->off)))         return s->off;     else if ((s->filesize == -1 && whence == SEEK_END))         return AVERROR(ENOSYS);      if (whence == SEEK_CUR) static int http_proxy_open(URLContext *h, const char *uri, int flags)     s->buf_ptr    = s->buffer;     s->buf_end    = s->buffer;     s->line_count = 0;     s->filesize   = -1;     cur_auth_type = s->proxy_auth_state.auth_type;      /* Note: This uses buffering, potentially reading more than the

Fixed version (after fix):
 typedef struct HTTPContext {     int line_count;     int http_code;     /* Used if "Transfer-Encoding: chunked" otherwise -1. */     uint64_t chunksize;     uint64_t off, end_off, filesize;     char *location;     HTTPAuthState auth_state;     HTTPAuthState proxy_auth_state; typedef struct HTTPContext {     AVDictionary *cookie_dict;     int icy;     /* how much data was read since the last ICY metadata packet */     uint64_t icy_data_read;     /* after how many bytes of read data a new metadata packet will be found */     uint64_t icy_metaint;     char *icy_metadata_headers;     char *icy_metadata_packet;     AVDictionary *metadata; static int http_open(URLContext *h, const char *uri, int flags,     else         h->is_streamed = 1;      s->filesize = UINT64_MAX;     s->location = av_strdup(uri);     if (!s->location)         return AVERROR(ENOMEM); static void parse_content_range(URLContext *h, const char *p)      if (!strncmp(p, "bytes ", 6)) {         p     += 6;         s->off = strtoull(p, NULL, 10);         if ((slash = strchr(p, '/')) && strlen(slash) > 0)             s->filesize = strtoull(slash + 1, NULL, 10);     }     if (s->seekable == -1 && (!s->is_akamai || s->filesize != 2147483647))         h->is_streamed = 0; /* we _can_ in fact seek */ static int process_line(URLContext *h, char *line, int line_count,             if ((ret = parse_location(s, p)) < 0)                 return ret;             *new_location = 1;         } else if (!av_strcasecmp(tag, "Content-Length") &&                    s->filesize == UINT64_MAX) {             s->filesize = strtoull(p, NULL, 10);         } else if (!av_strcasecmp(tag, "Content-Range")) {             parse_content_range(h, p);         } else if (!av_strcasecmp(tag, "Accept-Ranges") && static int process_line(URLContext *h, char *line, int line_count,             h->is_streamed = 0;         } else if (!av_strcasecmp(tag, "Transfer-Encoding") &&                    !av_strncasecmp(p, "chunked", 7)) {             s->filesize  = UINT64_MAX;             s->chunksize = 0;         } else if (!av_strcasecmp(tag, "WWW-Authenticate")) {             ff_http_auth_handle_header(&s->auth_state, tag, p); static int process_line(URLContext *h, char *line, int line_count,             if (parse_cookie(s, p, &s->cookie_dict))                 av_log(h, AV_LOG_WARNING, "Unable to parse '%s'\n", p);         } else if (!av_strcasecmp(tag, "Icy-MetaInt")) {             s->icy_metaint = strtoull(p, NULL, 10);         } else if (!av_strncasecmp(tag, "Icy-", 4)) {             if ((ret = parse_icy(s, tag, p)) < 0)                 return ret; static int http_read_header(URLContext *h, int *new_location)     char line[MAX_URL_SIZE];     int err = 0;      s->chunksize = UINT64_MAX;      for (;;) {         if ((err = http_get_line(s, line, sizeof(line))) < 0) static int http_connect(URLContext *h, const char *path, const char *local_path,     int post, err;     char headers[HTTP_HEADERS_SIZE] = "";     char *authstr = NULL, *proxyauthstr = NULL;     uint64_t off = s->off;     int len = 0;     const char *method;     int send_expect_100 = 0; static int http_connect(URLContext *h, const char *path, const char *local_path,     // server supports seeking by analysing the reply headers.     if (!has_header(s->headers, "\r\nRange: ") && !post && (s->off > 0 || s->end_off || s->seekable == -1)) {         len += av_strlcatf(headers + len, sizeof(headers) - len,                            "Range: bytes=%"PRIu64"-", s->off);         if (s->end_off)             len += av_strlcatf(headers + len, sizeof(headers) - len,                                "%"PRId64, s->end_off - 1); static int http_connect(URLContext *h, const char *path, const char *local_path,     s->line_count       = 0;     s->off              = 0;     s->icy_data_read    = 0;     s->filesize         = UINT64_MAX;     s->willclose        = 0;     s->end_chunked_post = 0;     s->end_header       = 0; static int http_buf_read(URLContext *h, uint8_t *buf, int size)         memcpy(buf, s->buf_ptr, len);         s->buf_ptr += len;     } else {         uint64_t target_end = s->end_off ? s->end_off : s->filesize;         if ((!s->willclose || s->chunksize == UINT64_MAX) && s->off >= target_end)             return AVERROR_EOF;         len = ffurl_read(s->hd, buf, size);         if (!len && (!s->willclose || s->chunksize == UINT64_MAX) && s->off < target_end) {             av_log(h, AV_LOG_ERROR,                    "Stream ends prematurely at %"PRIu64", should be %"PRIu64"\n",                    s->off, target_end                   );             return AVERROR(EIO); static int http_read_stream(URLContext *h, uint8_t *buf, int size)             return err;     }      if (s->chunksize != UINT64_MAX) {         if (!s->chunksize) {             char line[32];  static int http_read_stream(URLContext *h, uint8_t *buf, int size)                         return err;                 } while (!*line);    /* skip CR LF from last chunk */                  s->chunksize = strtoull(line, NULL, 16);                  av_log(h, AV_LOG_TRACE,                        "Chunked encoding data size: %"PRIu64"'\n",                         s->chunksize);                  if (!s->chunksize)                     return 0;                 else if (s->chunksize == UINT64_MAX) {                     av_log(h, AV_LOG_ERROR, "Invalid chunk size %"PRIu64"\n",                            s->chunksize);                     return AVERROR(EINVAL);                 }         }         size = FFMIN(size, s->chunksize);     } static int http_read_stream(URLContext *h, uint8_t *buf, int size)     read_ret = http_buf_read(h, buf, size);     if (   (read_ret  < 0 && s->reconnect        && (!h->is_streamed || s->reconnect_streamed) && s->filesize > 0 && s->off < s->filesize)         || (read_ret == 0 && s->reconnect_at_eof && (!h->is_streamed || s->reconnect_streamed))) {         uint64_t target = h->is_streamed ? 0 : s->off;          if (s->reconnect_delay > s->reconnect_delay_max)             return AVERROR(EIO);          av_log(h, AV_LOG_INFO, "Will reconnect at %"PRIu64" error=%s.\n", s->off, av_err2str(read_ret));         av_usleep(1000U*1000*s->reconnect_delay);         s->reconnect_delay = 1 + 2*s->reconnect_delay;         seek_ret = http_seek_internal(h, target, SEEK_SET, 1);         if (seek_ret != target) {             av_log(h, AV_LOG_ERROR, "Failed to reconnect at %"PRIu64".\n", target);             return read_ret;         }  static int store_icy(URLContext *h, int size) {     HTTPContext *s = h->priv_data;     /* until next metadata packet */     uint64_t remaining;      if (s->icy_metaint < s->icy_data_read)         return AVERROR_INVALIDDATA;     remaining = s->icy_metaint - s->icy_data_read;      if (!remaining) {         /* The metadata packet is variable sized. It has a 1 byte header static int64_t http_seek_internal(URLContext *h, int64_t off, int whence, int fo {     HTTPContext *s = h->priv_data;     URLContext *old_hd = s->hd;     uint64_t old_off = s->off;     uint8_t old_buf[BUFFER_SIZE];     int old_buf_size, ret;     AVDictionary *options = NULL; static int64_t http_seek_internal(URLContext *h, int64_t off, int whence, int fo              ((whence == SEEK_CUR && off == 0) ||               (whence == SEEK_SET && off == s->off)))         return s->off;     else if ((s->filesize == UINT64_MAX && whence == SEEK_END))         return AVERROR(ENOSYS);      if (whence == SEEK_CUR) static int http_proxy_open(URLContext *h, const char *uri, int flags)     s->buf_ptr    = s->buffer;     s->buf_end    = s->buffer;     s->line_count = 0;     s->filesize   = UINT64_MAX;     cur_auth_type = s->proxy_auth_state.auth_type;      /* Note: This uses buffering, potentially reading more than the

Patch:
patch: @@ -62,8 +62,8 @@ typedef struct HTTPContext {
     int line_count;
     int http_code;
     /* Used if "Transfer-Encoding: chunked" otherwise -1. */
-    int64_t chunksize;
-    int64_t off, end_off, filesize;
+    uint64_t chunksize;
+    uint64_t off, end_off, filesize;
     char *location;
     HTTPAuthState auth_state;
     HTTPAuthState proxy_auth_state;
@@ -95,9 +95,9 @@ typedef struct HTTPContext {
     AVDictionary *cookie_dict;
     int icy;
     /* how much data was read since the last ICY metadata packet */
-    int icy_data_read;
+    uint64_t icy_data_read;
     /* after how many bytes of read data a new metadata packet will be found */
-    int icy_metaint;
+    uint64_t icy_metaint;
     char *icy_metadata_headers;
     char *icy_metadata_packet;
     AVDictionary *metadata;
@@ -489,7 +489,7 @@ static int http_open(URLContext *h, const char *uri, int flags,
     else
         h->is_streamed = 1;
 
-    s->filesize = -1;
+    s->filesize = UINT64_MAX;
     s->location = av_strdup(uri);
     if (!s->location)
         return AVERROR(ENOMEM);
@@ -616,9 +616,9 @@ static void parse_content_range(URLContext *h, const char *p)
 
     if (!strncmp(p, "bytes ", 6)) {
         p     += 6;
-        s->off = strtoll(p, NULL, 10);
+        s->off = strtoull(p, NULL, 10);
         if ((slash = strchr(p, '/')) && strlen(slash) > 0)
-            s->filesize = strtoll(slash + 1, NULL, 10);
+            s->filesize = strtoull(slash + 1, NULL, 10);
     }
     if (s->seekable == -1 && (!s->is_akamai || s->filesize != 2147483647))
         h->is_streamed = 0; /* we _can_ in fact seek */
@@ -808,8 +808,9 @@ static int process_line(URLContext *h, char *line, int line_count,
             if ((ret = parse_location(s, p)) < 0)
                 return ret;
             *new_location = 1;
-        } else if (!av_strcasecmp(tag, "Content-Length") && s->filesize == -1) {
-            s->filesize = strtoll(p, NULL, 10);
+        } else if (!av_strcasecmp(tag, "Content-Length") &&
+                   s->filesize == UINT64_MAX) {
+            s->filesize = strtoull(p, NULL, 10);
         } else if (!av_strcasecmp(tag, "Content-Range")) {
             parse_content_range(h, p);
         } else if (!av_strcasecmp(tag, "Accept-Ranges") &&
@@ -818,7 +819,7 @@ static int process_line(URLContext *h, char *line, int line_count,
             h->is_streamed = 0;
         } else if (!av_strcasecmp(tag, "Transfer-Encoding") &&
                    !av_strncasecmp(p, "chunked", 7)) {
-            s->filesize  = -1;
+            s->filesize  = UINT64_MAX;
             s->chunksize = 0;
         } else if (!av_strcasecmp(tag, "WWW-Authenticate")) {
             ff_http_auth_handle_header(&s->auth_state, tag, p);
@@ -842,7 +843,7 @@ static int process_line(URLContext *h, char *line, int line_count,
             if (parse_cookie(s, p, &s->cookie_dict))
                 av_log(h, AV_LOG_WARNING, "Unable to parse '%s'\n", p);
         } else if (!av_strcasecmp(tag, "Icy-MetaInt")) {
-            s->icy_metaint = strtoll(p, NULL, 10);
+            s->icy_metaint = strtoull(p, NULL, 10);
         } else if (!av_strncasecmp(tag, "Icy-", 4)) {
             if ((ret = parse_icy(s, tag, p)) < 0)
                 return ret;
@@ -972,7 +973,7 @@ static int http_read_header(URLContext *h, int *new_location)
     char line[MAX_URL_SIZE];
     int err = 0;
 
-    s->chunksize = -1;
+    s->chunksize = UINT64_MAX;
 
     for (;;) {
         if ((err = http_get_line(s, line, sizeof(line))) < 0)
@@ -1006,7 +1007,7 @@ static int http_connect(URLContext *h, const char *path, const char *local_path,
     int post, err;
     char headers[HTTP_HEADERS_SIZE] = "";
     char *authstr = NULL, *proxyauthstr = NULL;
-    int64_t off = s->off;
+    uint64_t off = s->off;
     int len = 0;
     const char *method;
     int send_expect_100 = 0;
@@ -1060,7 +1061,7 @@ static int http_connect(URLContext *h, const char *path, const char *local_path,
     // server supports seeking by analysing the reply headers.
     if (!has_header(s->headers, "\r\nRange: ") && !post && (s->off > 0 || s->end_off || s->seekable == -1)) {
         len += av_strlcatf(headers + len, sizeof(headers) - len,
-                           "Range: bytes=%"PRId64"-", s->off);
+                           "Range: bytes=%"PRIu64"-", s->off);
         if (s->end_off)
             len += av_strlcatf(headers + len, sizeof(headers) - len,
                                "%"PRId64, s->end_off - 1);
@@ -1135,7 +1136,7 @@ static int http_connect(URLContext *h, const char *path, const char *local_path,
     s->line_count       = 0;
     s->off              = 0;
     s->icy_data_read    = 0;
-    s->filesize         = -1;
+    s->filesize         = UINT64_MAX;
     s->willclose        = 0;
     s->end_chunked_post = 0;
     s->end_header       = 0;
@@ -1175,15 +1176,13 @@ static int http_buf_read(URLContext *h, uint8_t *buf, int size)
         memcpy(buf, s->buf_ptr, len);
         s->buf_ptr += len;
     } else {
-        int64_t target_end = s->end_off ? s->end_off : s->filesize;
-        if ((!s->willclose || s->chunksize < 0) &&
-            target_end >= 0 && s->off >= target_end)
+        uint64_t target_end = s->end_off ? s->end_off : s->filesize;
+        if ((!s->willclose || s->chunksize == UINT64_MAX) && s->off >= target_end)
             return AVERROR_EOF;
         len = ffurl_read(s->hd, buf, size);
-        if (!len && (!s->willclose || s->chunksize < 0) &&
-            target_end >= 0 && s->off < target_end) {
+        if (!len && (!s->willclose || s->chunksize == UINT64_MAX) && s->off < target_end) {
             av_log(h, AV_LOG_ERROR,
-                   "Stream ends prematurely at %"PRId64", should be %"PRId64"\n",
+                   "Stream ends prematurely at %"PRIu64", should be %"PRIu64"\n",
                    s->off, target_end
                   );
             return AVERROR(EIO);
@@ -1247,7 +1246,7 @@ static int http_read_stream(URLContext *h, uint8_t *buf, int size)
             return err;
     }
 
-    if (s->chunksize >= 0) {
+    if (s->chunksize != UINT64_MAX) {
         if (!s->chunksize) {
             char line[32];
 
@@ -1256,13 +1255,19 @@ static int http_read_stream(URLContext *h, uint8_t *buf, int size)
                         return err;
                 } while (!*line);    /* skip CR LF from last chunk */
 
-                s->chunksize = strtoll(line, NULL, 16);
+                s->chunksize = strtoull(line, NULL, 16);
 
-                av_log(NULL, AV_LOG_TRACE, "Chunked encoding data size: %"PRId64"'\n",
+                av_log(h, AV_LOG_TRACE,
+                       "Chunked encoding data size: %"PRIu64"'\n",
                         s->chunksize);
 
                 if (!s->chunksize)
                     return 0;
+                else if (s->chunksize == UINT64_MAX) {
+                    av_log(h, AV_LOG_ERROR, "Invalid chunk size %"PRIu64"\n",
+                           s->chunksize);
+                    return AVERROR(EINVAL);
+                }
         }
         size = FFMIN(size, s->chunksize);
     }
@@ -1273,17 +1278,17 @@ static int http_read_stream(URLContext *h, uint8_t *buf, int size)
     read_ret = http_buf_read(h, buf, size);
     if (   (read_ret  < 0 && s->reconnect        && (!h->is_streamed || s->reconnect_streamed) && s->filesize > 0 && s->off < s->filesize)
         || (read_ret == 0 && s->reconnect_at_eof && (!h->is_streamed || s->reconnect_streamed))) {
-        int64_t target = h->is_streamed ? 0 : s->off;
+        uint64_t target = h->is_streamed ? 0 : s->off;
 
         if (s->reconnect_delay > s->reconnect_delay_max)
             return AVERROR(EIO);
 
-        av_log(h, AV_LOG_INFO, "Will reconnect at %"PRId64" error=%s.\n", s->off, av_err2str(read_ret));
+        av_log(h, AV_LOG_INFO, "Will reconnect at %"PRIu64" error=%s.\n", s->off, av_err2str(read_ret));
         av_usleep(1000U*1000*s->reconnect_delay);
         s->reconnect_delay = 1 + 2*s->reconnect_delay;
         seek_ret = http_seek_internal(h, target, SEEK_SET, 1);
         if (seek_ret != target) {
-            av_log(h, AV_LOG_ERROR, "Failed to reconnect at %"PRId64".\n", target);
+            av_log(h, AV_LOG_ERROR, "Failed to reconnect at %"PRIu64".\n", target);
             return read_ret;
         }
 
@@ -1338,10 +1343,11 @@ static int store_icy(URLContext *h, int size)
 {
     HTTPContext *s = h->priv_data;
     /* until next metadata packet */
-    int remaining = s->icy_metaint - s->icy_data_read;
+    uint64_t remaining;
 
-    if (remaining < 0)
+    if (s->icy_metaint < s->icy_data_read)
         return AVERROR_INVALIDDATA;
+    remaining = s->icy_metaint - s->icy_data_read;
 
     if (!remaining) {
         /* The metadata packet is variable sized. It has a 1 byte header
@@ -1455,7 +1461,7 @@ static int64_t http_seek_internal(URLContext *h, int64_t off, int whence, int fo
 {
     HTTPContext *s = h->priv_data;
     URLContext *old_hd = s->hd;
-    int64_t old_off = s->off;
+    uint64_t old_off = s->off;
     uint8_t old_buf[BUFFER_SIZE];
     int old_buf_size, ret;
     AVDictionary *options = NULL;
@@ -1466,7 +1472,7 @@ static int64_t http_seek_internal(URLContext *h, int64_t off, int whence, int fo
              ((whence == SEEK_CUR && off == 0) ||
               (whence == SEEK_SET && off == s->off)))
         return s->off;
-    else if ((s->filesize == -1 && whence == SEEK_END))
+    else if ((s->filesize == UINT64_MAX && whence == SEEK_END))
         return AVERROR(ENOSYS);
 
     if (whence == SEEK_CUR)
@@ -1621,7 +1627,7 @@ static int http_proxy_open(URLContext *h, const char *uri, int flags)
     s->buf_ptr    = s->buffer;
     s->buf_end    = s->buffer;
     s->line_count = 0;
-    s->filesize   = -1;
+    s->filesize   = UINT64_MAX;
     cur_auth_type = s->proxy_auth_state.auth_type;
 
     /* Note: This uses buffering, potentially reading more than the
path: libavformat/http.c