Fixing libunit 'off by 2' issue in library.
Name and value in each header are 0-terminated, so additional 2 bytes should be allocated for them. There were several attempts to add these 2 bytes to headers in language modules, but some modules weren't updated. Also, adding these 2 bytes is specific to the implementation which may be changed later, so extending this mechanics to modules may cause errors.
This commit is contained in:
@@ -63,7 +63,7 @@ func (r *response) WriteHeader(code int) {
|
|||||||
for k, vv := range r.header {
|
for k, vv := range r.header {
|
||||||
for _, v := range vv {
|
for _, v := range vv {
|
||||||
fields++
|
fields++
|
||||||
fields_size += len(k) + len(v) + 2
|
fields_size += len(k) + len(v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -629,9 +629,6 @@ Unit::response_send_headers(napi_env env, napi_callback_info info)
|
|||||||
keys_count = napi.get_value_uint32(argv[2]);
|
keys_count = napi.get_value_uint32(argv[2]);
|
||||||
header_len = napi.get_value_uint32(argv[3]);
|
header_len = napi.get_value_uint32(argv[3]);
|
||||||
|
|
||||||
/* Need to reserve extra byte for C-string 0-termination. */
|
|
||||||
header_len++;
|
|
||||||
|
|
||||||
headers = argv[1];
|
headers = argv[1];
|
||||||
|
|
||||||
ret = nxt_unit_response_init(req, status_code, keys_count, header_len);
|
ret = nxt_unit_response_init(req, status_code, keys_count, header_len);
|
||||||
@@ -640,6 +637,12 @@ Unit::response_send_headers(napi_env env, napi_callback_info info)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Each name and value are 0-terminated by libunit.
|
||||||
|
* Need to add extra 2 bytes for each header.
|
||||||
|
*/
|
||||||
|
header_len += keys_count * 2;
|
||||||
|
|
||||||
keys = napi.get_property_names(headers);
|
keys = napi.get_property_names(headers);
|
||||||
keys_len = napi.get_array_length(keys);
|
keys_len = napi.get_array_length(keys);
|
||||||
|
|
||||||
@@ -656,8 +659,8 @@ Unit::response_send_headers(napi_env env, napi_callback_info info)
|
|||||||
name_len = napi.get_value_string_latin1(name, ptr, header_len);
|
name_len = napi.get_value_string_latin1(name, ptr, header_len);
|
||||||
name_ptr = ptr;
|
name_ptr = ptr;
|
||||||
|
|
||||||
ptr += name_len;
|
ptr += name_len + 1;
|
||||||
header_len -= name_len;
|
header_len -= name_len + 1;
|
||||||
|
|
||||||
hash = nxt_unit_field_hash(name_ptr, name_len);
|
hash = nxt_unit_field_hash(name_ptr, name_len);
|
||||||
|
|
||||||
@@ -689,8 +692,8 @@ Unit::response_send_headers(napi_env env, napi_callback_info info)
|
|||||||
nxt_unit_sptr_set(&f->value, ptr);
|
nxt_unit_sptr_set(&f->value, ptr);
|
||||||
f->value_length = (uint32_t) value_len;
|
f->value_length = (uint32_t) value_len;
|
||||||
|
|
||||||
ptr += value_len;
|
ptr += value_len + 1;
|
||||||
header_len -= value_len;
|
header_len -= value_len + 1;
|
||||||
|
|
||||||
req->response->fields_count++;
|
req->response->fields_count++;
|
||||||
}
|
}
|
||||||
@@ -715,8 +718,8 @@ Unit::response_send_headers(napi_env env, napi_callback_info info)
|
|||||||
nxt_unit_sptr_set(&f->value, ptr);
|
nxt_unit_sptr_set(&f->value, ptr);
|
||||||
f->value_length = (uint32_t) value_len;
|
f->value_length = (uint32_t) value_len;
|
||||||
|
|
||||||
ptr += value_len;
|
ptr += value_len + 1;
|
||||||
header_len -= value_len;
|
header_len -= value_len + 1;
|
||||||
|
|
||||||
req->response->fields_count++;
|
req->response->fields_count++;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1316,8 +1316,12 @@ nxt_unit_response_init(nxt_unit_request_info_t *req,
|
|||||||
nxt_unit_req_debug(req, "duplicate response init");
|
nxt_unit_req_debug(req, "duplicate response init");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Each field name and value 0-terminated by libunit,
|
||||||
|
* this is the reason of '+ 2' below.
|
||||||
|
*/
|
||||||
buf_size = sizeof(nxt_unit_response_t)
|
buf_size = sizeof(nxt_unit_response_t)
|
||||||
+ max_fields_count * sizeof(nxt_unit_field_t)
|
+ max_fields_count * (sizeof(nxt_unit_field_t) + 2)
|
||||||
+ max_fields_size;
|
+ max_fields_size;
|
||||||
|
|
||||||
if (nxt_slow_path(req->response_buf != NULL)) {
|
if (nxt_slow_path(req->response_buf != NULL)) {
|
||||||
@@ -1391,8 +1395,12 @@ nxt_unit_response_realloc(nxt_unit_request_info_t *req,
|
|||||||
return NXT_UNIT_ERROR;
|
return NXT_UNIT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Each field name and value 0-terminated by libunit,
|
||||||
|
* this is the reason of '+ 2' below.
|
||||||
|
*/
|
||||||
buf_size = sizeof(nxt_unit_response_t)
|
buf_size = sizeof(nxt_unit_response_t)
|
||||||
+ max_fields_count * sizeof(nxt_unit_field_t)
|
+ max_fields_count * (sizeof(nxt_unit_field_t) + 2)
|
||||||
+ max_fields_size;
|
+ max_fields_size;
|
||||||
|
|
||||||
nxt_unit_req_debug(req, "realloc %"PRIu32"", buf_size);
|
nxt_unit_req_debug(req, "realloc %"PRIu32"", buf_size);
|
||||||
|
|||||||
@@ -104,10 +104,10 @@ ws_chat_root(nxt_unit_request_info_t *req)
|
|||||||
|
|
||||||
rc = nxt_unit_response_init(req, 200 /* Status code. */,
|
rc = nxt_unit_response_init(req, 200 /* Status code. */,
|
||||||
2 /* Number of response headers. */,
|
2 /* Number of response headers. */,
|
||||||
nxt_length(CONTENT_TYPE) + 1
|
nxt_length(CONTENT_TYPE)
|
||||||
+ nxt_length(TEXT_HTML) + 1
|
+ nxt_length(TEXT_HTML)
|
||||||
+ nxt_length(CONTENT_LENGTH) + 1
|
+ nxt_length(CONTENT_LENGTH)
|
||||||
+ ws_chat_index_content_length_size + 1
|
+ ws_chat_index_content_length_size
|
||||||
+ ws_chat_index_html_size);
|
+ ws_chat_index_html_size);
|
||||||
if (nxt_slow_path(rc != NXT_UNIT_OK)) {
|
if (nxt_slow_path(rc != NXT_UNIT_OK)) {
|
||||||
return rc;
|
return rc;
|
||||||
|
|||||||
Reference in New Issue
Block a user