[njs] Detecting memory error in njs_chb_*() functions.
Dmitry Volyntsev
xeioex at nginx.com
Tue Feb 18 15:56:36 UTC 2020
details: https://hg.nginx.org/njs/rev/aa9ac79f7fd9
branches:
changeset: 1330:aa9ac79f7fd9
user: Dmitry Volyntsev <xeioex at nginx.com>
date: Tue Feb 18 18:41:38 2020 +0300
description:
Detecting memory error in njs_chb_*() functions.
diffstat:
src/njs_array.c | 9 +++++++--
src/njs_chb.c | 17 ++++++++++++-----
src/njs_chb.h | 12 ++++++++++--
src/njs_json.c | 14 ++++++++------
4 files changed, 37 insertions(+), 15 deletions(-)
diffs (158 lines):
diff -r d2877d602d39 -r aa9ac79f7fd9 src/njs_array.c
--- a/src/njs_array.c Mon Feb 17 16:18:40 2020 +0300
+++ b/src/njs_array.c Tue Feb 18 18:41:38 2020 +0300
@@ -1381,8 +1381,8 @@ njs_array_prototype_join(njs_vm_t *vm, n
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, n
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 -r d2877d602d39 -r aa9ac79f7fd9 src/njs_chb.c
--- a/src/njs_chb.c Mon Feb 17 16:18:40 2020 +0300
+++ b/src/njs_chb.c Tue Feb 18 18:41:38 2020 +0300
@@ -134,9 +134,13 @@ njs_chb_drain(njs_chb_t *chain, size_t d
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 dr
}
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
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 -r d2877d602d39 -r aa9ac79f7fd9 src/njs_chb.h
--- a/src/njs_chb.h Mon Feb 17 16:18:40 2020 +0300
+++ b/src/njs_chb.h Tue Feb 18 18:41:38 2020 +0300
@@ -61,12 +61,16 @@ njs_chb_init(njs_chb_t *chain, njs_mp_t
}
-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 -r d2877d602d39 -r aa9ac79f7fd9 src/njs_json.c
--- a/src/njs_json.c Mon Feb 17 16:18:40 2020 +0300
+++ b/src/njs_json.c Tue Feb 18 18:41:38 2020 +0300
@@ -1120,8 +1120,7 @@ njs_json_stringify_iterator(njs_vm_t *vm
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;
}
More information about the nginx-devel
mailing list