diff options
author | Ronald S. Bultje <rsbultje@gmail.com> | 2016-12-05 08:02:33 -0500 |
---|---|---|
committer | Ronald S. Bultje <rsbultje@gmail.com> | 2016-12-05 16:50:50 -0500 |
commit | 2e3f0a1c6f39cf2a35bdda85e43970ffc6db797b (patch) | |
tree | f020f13fb34be4f35870fc0811fb0f22c9b9ba4f | |
parent | 1768e02a046ac05cb212991ae23021ad412cd15a (diff) | |
download | ffmpeg-2e3f0a1c6f39cf2a35bdda85e43970ffc6db797b.tar.gz |
http: make length/offset-related variables unsigned.
Fixes #5992, reported and found by Paul Cher <paulcher@icloud.com>.
(cherry picked from commit 2a05c8f813de6f2278827734bf8102291e7484aa)
-rw-r--r-- | libavformat/http.c | 70 |
1 files changed, 38 insertions, 32 deletions
diff --git a/libavformat/http.c b/libavformat/http.c index 3dad2ef9fb..bd84aa05da 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -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; @@ -92,9 +92,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; @@ -480,7 +480,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); @@ -607,9 +607,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 */ @@ -799,8 +799,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") && @@ -809,7 +810,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); @@ -833,7 +834,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; @@ -963,7 +964,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) @@ -997,7 +998,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; @@ -1045,7 +1046,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); @@ -1120,7 +1121,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; @@ -1160,15 +1161,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); @@ -1231,7 +1230,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]; @@ -1240,13 +1239,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); } @@ -1257,17 +1262,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; } @@ -1322,10 +1327,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 @@ -1439,7 +1445,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; @@ -1450,7 +1456,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) @@ -1605,7 +1611,7 @@ redo: 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 |