diff --git a/ngx_http_zip_file.c b/ngx_http_zip_file.c index 787a5ef..91f7cb4 100644 --- a/ngx_http_zip_file.c +++ b/ngx_http_zip_file.c @@ -353,20 +353,30 @@ ngx_http_zip_generate_pieces(ngx_http_request_t *r, ngx_http_zip_ctx_t *ctx) if(file->size >= (off_t) NGX_MAX_UINT32_VALUE) ctx->zip64_used = file->need_zip64 = 1; - ctx->cd_size += sizeof(ngx_zip_central_directory_file_header_t) + file->filename.len + sizeof(ngx_zip_extra_field_central_t) - + (file->need_zip64_offset ? - (file->need_zip64 ? sizeof(ngx_zip_extra_field_zip64_sizes_offset_t) : sizeof(ngx_zip_extra_field_zip64_offset_only_t)) : - (file->need_zip64 ? sizeof(ngx_zip_extra_field_zip64_sizes_only_t) : 0) + - (ctx->unicode_path && file->filename_utf8.len ? (sizeof(ngx_zip_extra_field_unicode_path_t) + file->filename_utf8.len): 0) - ); + ctx->cd_size += sizeof(ngx_zip_central_directory_file_header_t) + file->filename.len + sizeof(ngx_zip_extra_field_central_t); + if (file->need_zip64) { + if (file->need_zip64_offset) { + ctx->cd_size += sizeof(ngx_zip_extra_field_zip64_sizes_offset_t); + } else { + ctx->cd_size += sizeof(ngx_zip_extra_field_zip64_sizes_only_t); + } + } else if (file->need_zip64_offset) { + ctx->cd_size += sizeof(ngx_zip_extra_field_zip64_offset_only_t); + } + if (ctx->unicode_path && file->filename_utf8.len) + ctx->cd_size += sizeof(ngx_zip_extra_field_unicode_path_t) + file->filename_utf8.len; header_piece = &ctx->pieces[piece_i++]; header_piece->type = zip_header_piece; header_piece->file = file; header_piece->range.start = offset; - header_piece->range.end = offset += sizeof(ngx_zip_local_file_header_t) - + file->filename.len + sizeof(ngx_zip_extra_field_local_t) + (file->need_zip64? sizeof(ngx_zip_extra_field_zip64_sizes_only_t):0) - + (ctx->unicode_path && file->filename_utf8.len ? (sizeof(ngx_zip_extra_field_unicode_path_t) + file->filename_utf8.len): 0); + + offset += sizeof(ngx_zip_local_file_header_t) + file->filename.len + sizeof(ngx_zip_extra_field_local_t); + if (file->need_zip64) + offset += sizeof(ngx_zip_extra_field_zip64_sizes_only_t); + if (ctx->unicode_path && file->filename_utf8.len) + offset += sizeof(ngx_zip_extra_field_unicode_path_t) + file->filename_utf8.len; + header_piece->range.end = offset; file_piece = &ctx->pieces[piece_i++]; file_piece->type = zip_file_piece; @@ -417,6 +427,7 @@ ngx_http_zip_file_header_chain_link(ngx_http_request_t *r, ngx_http_zip_ctx_t *c { ngx_chain_t *link; ngx_buf_t *b; + u_char *p; ngx_http_zip_file_t *file = piece->file; ngx_zip_extra_field_local_t extra_field_local; @@ -424,9 +435,11 @@ ngx_http_zip_file_header_chain_link(ngx_http_request_t *r, ngx_http_zip_ctx_t *c ngx_zip_local_file_header_t local_file_header; ngx_zip_extra_field_unicode_path_t extra_field_unicode_path; - size_t len = sizeof(ngx_zip_local_file_header_t) + file->filename.len - + sizeof(ngx_zip_extra_field_local_t) + (file->need_zip64? sizeof(ngx_zip_extra_field_zip64_sizes_only_t):0 - + (ctx->unicode_path && file->filename_utf8.len ? (sizeof(ngx_zip_extra_field_unicode_path_t) + file->filename_utf8.len): 0)); + size_t len = sizeof(ngx_zip_local_file_header_t) + file->filename.len + sizeof(ngx_zip_extra_field_local_t); + if (file->need_zip64) + len += sizeof(ngx_zip_extra_field_zip64_sizes_only_t); + if (ctx->unicode_path && file->filename_utf8.len) + len += sizeof(ngx_zip_extra_field_unicode_path_t) + file->filename_utf8.len; if ((link = ngx_alloc_chain_link(r->pool)) == NULL || (b = ngx_calloc_buf(r->pool)) == NULL || (b->pos = ngx_pcalloc(r->pool, len)) == NULL) @@ -459,7 +472,8 @@ ngx_http_zip_file_header_chain_link(ngx_http_request_t *r, ngx_http_zip_ctx_t *c if (file->need_zip64) { local_file_header.version = htole16(zip_version_zip64); - local_file_header.extra_field_len = sizeof(ngx_zip_extra_field_zip64_sizes_only_t) + sizeof(ngx_zip_extra_field_local_t); + local_file_header.extra_field_len += sizeof(ngx_zip_extra_field_zip64_sizes_only_t); + extra_field_zip64.uncompressed_size = extra_field_zip64.compressed_size = htole64(file->size); } else { local_file_header.compressed_size = htole32(file->size); @@ -488,21 +502,28 @@ ngx_http_zip_file_header_chain_link(ngx_http_request_t *r, ngx_http_zip_ctx_t *c extra_field_local.mtime = htole32(file->unix_time); extra_field_local.atime = htole32(file->unix_time); - ngx_memcpy(b->pos, &local_file_header, sizeof(ngx_zip_local_file_header_t)); - ngx_memcpy(b->pos + sizeof(ngx_zip_local_file_header_t), file->filename.data, file->filename.len); - ngx_memcpy(b->pos + sizeof(ngx_zip_local_file_header_t) + file->filename.len, - &extra_field_local, sizeof(ngx_zip_extra_field_local_t)); + p = b->pos; + + ngx_memcpy(p, &local_file_header, sizeof(ngx_zip_local_file_header_t)); + p += sizeof(ngx_zip_local_file_header_t); + + ngx_memcpy(p, file->filename.data, file->filename.len); + p += file->filename.len; + + ngx_memcpy(p, &extra_field_local, sizeof(ngx_zip_extra_field_local_t)); + p += sizeof(ngx_zip_extra_field_local_t); + if (file->need_zip64) { - ngx_memcpy(b->pos + sizeof(ngx_zip_local_file_header_t) + file->filename.len + sizeof(ngx_zip_extra_field_local_t), - &extra_field_zip64, sizeof(ngx_zip_extra_field_zip64_sizes_only_t)); + ngx_memcpy(p, &extra_field_zip64, sizeof(ngx_zip_extra_field_zip64_sizes_only_t)); + p += sizeof(ngx_zip_extra_field_zip64_sizes_only_t); + } - if (ctx->unicode_path && file->filename_utf8.len) { - ngx_memcpy(b->pos + sizeof(ngx_zip_local_file_header_t) + file->filename.len + sizeof(ngx_zip_extra_field_local_t) + sizeof(ngx_zip_extra_field_zip64_sizes_only_t), &extra_field_unicode_path, sizeof(ngx_zip_extra_field_unicode_path_t)); - ngx_memcpy(b->pos + sizeof(ngx_zip_local_file_header_t) + file->filename.len + sizeof(ngx_zip_extra_field_local_t) + sizeof(ngx_zip_extra_field_zip64_sizes_only_t) + sizeof(ngx_zip_extra_field_unicode_path_t), file->filename_utf8.data, file->filename_utf8.len); - } - } else if (ctx->unicode_path && file->filename_utf8.len) { - ngx_memcpy(b->pos + sizeof(ngx_zip_local_file_header_t) + file->filename.len + sizeof(ngx_zip_extra_field_local_t), &extra_field_unicode_path, sizeof(ngx_zip_extra_field_unicode_path_t)); - ngx_memcpy(b->pos + sizeof(ngx_zip_local_file_header_t) + file->filename.len + sizeof(ngx_zip_extra_field_local_t) + sizeof(ngx_zip_extra_field_unicode_path_t), file->filename_utf8.data, file->filename_utf8.len); + if (ctx->unicode_path && file->filename_utf8.len) { + ngx_memcpy(p, &extra_field_unicode_path, sizeof(ngx_zip_extra_field_unicode_path_t)); + p += sizeof(ngx_zip_extra_field_unicode_path_t); + + ngx_memcpy(p, file->filename_utf8.data, file->filename_utf8.len); + p += file->filename_utf8.len; } ngx_http_zip_truncate_buffer(b, &piece->range, range); @@ -687,15 +708,13 @@ ngx_http_zip_write_central_directory_entry(u_char *p, ngx_http_zip_file_t *file, extra_zip64_ptr = &extra_zip64_size; extra_zip64_ptr_size = sizeof(extra_zip64_size); } - } else { - if (file->need_zip64_offset){ - extra_zip64_offset = ngx_zip_extra_field_zip64_offset_only_template; - extra_zip64_offset.tag = htole16(extra_zip64_offset.tag); - extra_zip64_offset.size = htole16(extra_zip64_offset.size); - extra_zip64_offset.relative_header_offset = htole64(file->offset); - extra_zip64_ptr = &extra_zip64_offset; - extra_zip64_ptr_size = sizeof(extra_zip64_offset); - } + } else if (file->need_zip64_offset) { + extra_zip64_offset = ngx_zip_extra_field_zip64_offset_only_template; + extra_zip64_offset.tag = htole16(extra_zip64_offset.tag); + extra_zip64_offset.size = htole16(extra_zip64_offset.size); + extra_zip64_offset.relative_header_offset = htole64(file->offset); + extra_zip64_ptr = &extra_zip64_offset; + extra_zip64_ptr_size = sizeof(extra_zip64_offset); } central_directory_file_header.extra_field_len=sizeof(ngx_zip_extra_field_central_t)+extra_zip64_ptr_size; extra_field_central = ngx_zip_extra_field_central_template;