From: Dmitry Volyntsev Date: Tue, 18 Feb 2020 15:41:38 +0000 (+0300) Subject: Detecting memory error in njs_chb_*() functions. X-Git-Url: http://www.kaiwu.me/postgresql/commit/?a=commitdiff_plain;h=aa2caab503490dc9947e2e543070d34cb4e70d33;p=njs.git Detecting memory error in njs_chb_*() functions. --- diff --git a/src/njs_array.c b/src/njs_array.c index 35765bba..a7c03239 100644 --- a/src/njs_array.c +++ b/src/njs_array.c @@ -1381,8 +1381,8 @@ njs_array_prototype_join(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused) { u_char *p, *last; - int64_t length; - uint64_t i, len, size; + int64_t size, length; + uint64_t i, len; njs_int_t ret; njs_chb_t chain; njs_utf8_t utf8; @@ -1497,6 +1497,11 @@ njs_array_prototype_join(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_chb_drop(&chain, separator.size); size = njs_chb_size(&chain); + if (njs_slow_path(size < 0)) { + njs_memory_error(vm); + return NJS_ERROR; + } + length -= separator.length; p = njs_string_alloc(vm, &vm->retval, size, utf8 ? length : 0); diff --git a/src/njs_chb.c b/src/njs_chb.c index b9dbff04..718cfe6d 100644 --- a/src/njs_chb.c +++ b/src/njs_chb.c @@ -134,9 +134,13 @@ njs_chb_drain(njs_chb_t *chain, size_t drain) void njs_chb_drop(njs_chb_t *chain, size_t drop) { - size_t size; + uint64_t size; njs_chb_node_t *n, *next; + if (njs_slow_path(chain->error)) { + return; + } + n = chain->last; if (njs_fast_path(n != NULL && (njs_chb_node_size(n) > drop))) { @@ -145,7 +149,7 @@ njs_chb_drop(njs_chb_t *chain, size_t drop) } n = chain->nodes; - size = njs_chb_size(chain); + size = (uint64_t) njs_chb_size(chain); if (drop >= size) { njs_chb_destroy(chain); @@ -181,10 +185,10 @@ njs_int_t njs_chb_join(njs_chb_t *chain, njs_str_t *str) { u_char *start; - size_t size; + uint64_t size; njs_chb_node_t *n; - if (chain->error) { + if (njs_slow_path(chain->error)) { return NJS_DECLINED; } @@ -196,7 +200,10 @@ njs_chb_join(njs_chb_t *chain, njs_str_t *str) return NJS_OK; } - size = njs_chb_size(chain); + size = (uint64_t) njs_chb_size(chain); + if (njs_slow_path(size >= UINT32_MAX)) { + return NJS_ERROR; + } start = njs_mp_alloc(chain->pool, size); if (njs_slow_path(start == NULL)) { diff --git a/src/njs_chb.h b/src/njs_chb.h index caefda45..641547c1 100644 --- a/src/njs_chb.h +++ b/src/njs_chb.h @@ -61,12 +61,16 @@ njs_chb_init(njs_chb_t *chain, njs_mp_t *pool) } -njs_inline uint64_t +njs_inline int64_t njs_chb_size(njs_chb_t *chain) { uint64_t size; njs_chb_node_t *n; + if (njs_slow_path(chain->error)) { + return -1; + } + n = chain->nodes; size = 0; @@ -86,6 +90,10 @@ njs_chb_utf8_length(njs_chb_t *chain) int64_t len, length; njs_chb_node_t *n; + if (njs_slow_path(chain->error)) { + return -1; + } + n = chain->nodes; length = 0; @@ -93,7 +101,7 @@ njs_chb_utf8_length(njs_chb_t *chain) while (n != NULL) { len = njs_utf8_length(n->start, njs_chb_node_size(n)); if (njs_slow_path(len < 0)) { - return len; + return 0; } length += len; diff --git a/src/njs_json.c b/src/njs_json.c index 0a238767..9e8e49a5 100644 --- a/src/njs_json.c +++ b/src/njs_json.c @@ -1120,8 +1120,7 @@ njs_json_stringify_iterator(njs_vm_t *vm, njs_json_stringify_t *stringify, njs_value_t *object) { u_char *p; - int64_t length; - uint64_t size; + int64_t size, length; njs_int_t ret; njs_chb_t chain; njs_value_t *key, *value, index, wrapper; @@ -1295,18 +1294,21 @@ done: } size = njs_chb_size(&chain); - if (njs_slow_path(size == 0)) { + if (njs_slow_path(size < 0)) { + njs_chb_destroy(&chain); + goto memory_error; + } + + if (size == 0) { njs_set_undefined(&vm->retval); goto release; } length = njs_chb_utf8_length(&chain); - if (njs_slow_path(length < 0)) { - length = 0; - } p = njs_string_alloc(vm, &vm->retval, size, length); if (njs_slow_path(p == NULL)) { + njs_chb_destroy(&chain); goto memory_error; }