[njs] Fixed Array.prototype.sort() with --debug=YES and --debug-memory=YES.

Dmitry Volyntsev xeioex at nginx.com
Sat Oct 7 05:49:10 UTC 2023


details:   https://hg.nginx.org/njs/rev/b49a98886c02
branches:  
changeset: 2219:b49a98886c02
user:      Dmitry Volyntsev <xeioex at nginx.com>
date:      Fri Oct 06 16:52:23 2023 -0700
description:
Fixed Array.prototype.sort() with --debug=YES and --debug-memory=YES.

Previously, --debug-memory=YES activated a different allocation
mechanism that was not able to properly handle the 0 size allocation.
Specifically, njs_mp_free() failed to find a block to free when the size
of the block is 0.

The fix is to alloc at least 1 byte in the --debug-memory=YES mode.

diffstat:

 src/njs_array.c |  28 +++++++++++++++++++++++-----
 src/njs_mp.c    |   8 ++++++++
 2 files changed, 31 insertions(+), 5 deletions(-)

diffs (77 lines):

diff -r b67fc7398a83 -r b49a98886c02 src/njs_array.c
--- a/src/njs_array.c	Fri Oct 06 16:51:53 2023 -0700
+++ b/src/njs_array.c	Fri Oct 06 16:52:23 2023 -0700
@@ -2782,6 +2782,8 @@ njs_sort_indexed_properties(njs_vm_t *vm
     njs_array_sort_ctx_t   ctx;
     njs_array_sort_slot_t  *p, *end, *slots, *newslots;
 
+    njs_assert(length != 0);
+
     slots = NULL;
     keys = NULL;
     ctx.vm = vm;
@@ -2993,6 +2995,12 @@ njs_array_prototype_sort(njs_vm_t *vm, n
         return ret;
     }
 
+    slots = NULL;
+
+    if (length == 0) {
+        goto done;
+    }
+
     /* Satisfy gcc -O3 */
     nslots = 0;
 
@@ -3027,6 +3035,8 @@ njs_array_prototype_sort(njs_vm_t *vm, n
         }
     }
 
+done:
+
     njs_value_assign(retval, this);
 
     ret = NJS_OK;
@@ -3083,11 +3093,19 @@ njs_array_prototype_to_sorted(njs_vm_t *
         return NJS_ERROR;
     }
 
-    slots = njs_sort_indexed_properties(vm, this, length, compare, 0, &nslots,
-                                        &nunds);
-    if (njs_slow_path(slots == NULL)) {
-        ret = NJS_ERROR;
-        goto exception;
+    if (length != 0) {
+        slots = njs_sort_indexed_properties(vm, this, length, compare, 0,
+                                            &nslots, &nunds);
+        if (njs_slow_path(slots == NULL)) {
+            ret = NJS_ERROR;
+            goto exception;
+        }
+
+    } else {
+        slots = NULL;
+        length = 0;
+        nslots = 0;
+        nunds = 0;
     }
 
     njs_assert(length == (nslots + nunds));
diff -r b67fc7398a83 -r b49a98886c02 src/njs_mp.c
--- a/src/njs_mp.c	Fri Oct 06 16:51:53 2023 -0700
+++ b/src/njs_mp.c	Fri Oct 06 16:52:23 2023 -0700
@@ -592,6 +592,14 @@ njs_mp_alloc_large(njs_mp_t *mp, size_t 
         return NULL;
     }
 
+#if (NJS_DEBUG)
+    /*
+     * Ensure that the size is not zero, otherwise njs_mp_find_block()
+     * will not be able to find the block.
+     */
+    size += size == 0;
+#endif
+
     if (njs_is_power_of_two(size)) {
         block = njs_malloc(sizeof(njs_mp_block_t));
         if (njs_slow_path(block == NULL)) {


More information about the nginx-devel mailing list