Range filter: changed type for total length to off_t.
Total length of a response with multiple ranges can be larger than a size_t
variable can hold, so type changed to off_t. Previously, an incorrect
Content-Length was returned when requesting more than 4G of ranges from
a large enough file on a 32-bit system.
An additional size_t variable introduced to calculate size of the boundary
header buffer, as off_t is not needed here and will require type casts on
win32.
Reported by Shuxin Yang,
http://mailman.nginx.org/pipermail/nginx/2017-July/054384.html.
Maxim Dounin
4 years ago
457 | 457 | ngx_http_range_multipart_header(ngx_http_request_t *r, |
458 | 458 | ngx_http_range_filter_ctx_t *ctx) |
459 | 459 | { |
460 | size_t len; | |
460 | off_t len; | |
461 | size_t size; | |
461 | 462 | ngx_uint_t i; |
462 | 463 | ngx_http_range_t *range; |
463 | 464 | ngx_atomic_uint_t boundary; |
464 | 465 | |
465 | len = sizeof(CRLF "--") - 1 + NGX_ATOMIC_T_LEN | |
466 | + sizeof(CRLF "Content-Type: ") - 1 | |
467 | + r->headers_out.content_type.len | |
468 | + sizeof(CRLF "Content-Range: bytes ") - 1; | |
466 | size = sizeof(CRLF "--") - 1 + NGX_ATOMIC_T_LEN | |
467 | + sizeof(CRLF "Content-Type: ") - 1 | |
468 | + r->headers_out.content_type.len | |
469 | + sizeof(CRLF "Content-Range: bytes ") - 1; | |
469 | 470 | |
470 | 471 | if (r->headers_out.content_type_len == r->headers_out.content_type.len |
471 | 472 | && r->headers_out.charset.len) |
472 | 473 | { |
473 | len += sizeof("; charset=") - 1 + r->headers_out.charset.len; | |
474 | } | |
475 | ||
476 | ctx->boundary_header.data = ngx_pnalloc(r->pool, len); | |
474 | size += sizeof("; charset=") - 1 + r->headers_out.charset.len; | |
475 | } | |
476 | ||
477 | ctx->boundary_header.data = ngx_pnalloc(r->pool, size); | |
477 | 478 | if (ctx->boundary_header.data == NULL) { |
478 | 479 | return NGX_ERROR; |
479 | 480 | } |
563 | 564 | - range[i].content_range.data; |
564 | 565 | |
565 | 566 | len += ctx->boundary_header.len + range[i].content_range.len |
566 | + (size_t) (range[i].end - range[i].start); | |
567 | + (range[i].end - range[i].start); | |
567 | 568 | } |
568 | 569 | |
569 | 570 | r->headers_out.content_length_n = len; |