diff options
author | Max Romanov <max.romanov@nginx.com> | 2019-11-11 18:04:17 +0300 |
---|---|---|
committer | Max Romanov <max.romanov@nginx.com> | 2019-11-11 18:04:17 +0300 |
commit | f2610d216059fd2dfced37442ea4e76f0b88a33b (patch) | |
tree | 0bdb0abf7e5ff6bd0362909d4eace9b81c03734b /src | |
parent | ed3298a3c68bb257b43425c92b07e224c7f46be3 (diff) | |
download | unit-f2610d216059fd2dfced37442ea4e76f0b88a33b.tar.gz unit-f2610d216059fd2dfced37442ea4e76f0b88a33b.tar.bz2 |
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.
Diffstat (limited to '')
-rw-r--r-- | src/go/unit/response.go | 2 | ||||
-rw-r--r-- | src/nodejs/unit-http/unit.cpp | 21 | ||||
-rw-r--r-- | src/nxt_unit.c | 12 | ||||
-rw-r--r-- | src/test/nxt_unit_websocket_chat.c | 8 |
4 files changed, 27 insertions, 16 deletions
diff --git a/src/go/unit/response.go b/src/go/unit/response.go index bb326ea5..767d66b7 100644 --- a/src/go/unit/response.go +++ b/src/go/unit/response.go @@ -63,7 +63,7 @@ func (r *response) WriteHeader(code int) { for k, vv := range r.header { for _, v := range vv { fields++ - fields_size += len(k) + len(v) + 2 + fields_size += len(k) + len(v) } } diff --git a/src/nodejs/unit-http/unit.cpp b/src/nodejs/unit-http/unit.cpp index ac10024c..10875703 100644 --- a/src/nodejs/unit-http/unit.cpp +++ b/src/nodejs/unit-http/unit.cpp @@ -629,9 +629,6 @@ Unit::response_send_headers(napi_env env, napi_callback_info info) keys_count = napi.get_value_uint32(argv[2]); header_len = napi.get_value_uint32(argv[3]); - /* Need to reserve extra byte for C-string 0-termination. */ - header_len++; - headers = argv[1]; 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; } + /* + * 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_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_ptr = ptr; - ptr += name_len; - header_len -= name_len; + ptr += name_len + 1; + header_len -= name_len + 1; 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); f->value_length = (uint32_t) value_len; - ptr += value_len; - header_len -= value_len; + ptr += value_len + 1; + header_len -= value_len + 1; 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); f->value_length = (uint32_t) value_len; - ptr += value_len; - header_len -= value_len; + ptr += value_len + 1; + header_len -= value_len + 1; req->response->fields_count++; } diff --git a/src/nxt_unit.c b/src/nxt_unit.c index 8b1226f5..0cf32916 100644 --- a/src/nxt_unit.c +++ b/src/nxt_unit.c @@ -1316,8 +1316,12 @@ nxt_unit_response_init(nxt_unit_request_info_t *req, 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) - + max_fields_count * sizeof(nxt_unit_field_t) + + max_fields_count * (sizeof(nxt_unit_field_t) + 2) + max_fields_size; 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; } + /* + * Each field name and value 0-terminated by libunit, + * this is the reason of '+ 2' below. + */ 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; nxt_unit_req_debug(req, "realloc %"PRIu32"", buf_size); diff --git a/src/test/nxt_unit_websocket_chat.c b/src/test/nxt_unit_websocket_chat.c index ecc9a243..6e274722 100644 --- a/src/test/nxt_unit_websocket_chat.c +++ b/src/test/nxt_unit_websocket_chat.c @@ -104,10 +104,10 @@ ws_chat_root(nxt_unit_request_info_t *req) rc = nxt_unit_response_init(req, 200 /* Status code. */, 2 /* Number of response headers. */, - nxt_length(CONTENT_TYPE) + 1 - + nxt_length(TEXT_HTML) + 1 - + nxt_length(CONTENT_LENGTH) + 1 - + ws_chat_index_content_length_size + 1 + nxt_length(CONTENT_TYPE) + + nxt_length(TEXT_HTML) + + nxt_length(CONTENT_LENGTH) + + ws_chat_index_content_length_size + ws_chat_index_html_size); if (nxt_slow_path(rc != NXT_UNIT_OK)) { return rc; |