[njs] Fixed endless loop in Array.prototype.sort().

Dmitry Volyntsev xeioex at nginx.com
Tue Jun 2 15:18:08 UTC 2020


details:   https://hg.nginx.org/njs/rev/1ce9a0895630
branches:  
changeset: 1417:1ce9a0895630
user:      Dmitry Volyntsev <xeioex at nginx.com>
date:      Tue Jun 02 14:59:30 2020 +0000
description:
Fixed endless loop in Array.prototype.sort().

With non-consistent comparison function.

The issue was introduced in 1d0825906438.

diffstat:

 src/njs_utils.c          |  7 +++----
 src/test/njs_unit_test.c |  3 +++
 2 files changed, 6 insertions(+), 4 deletions(-)

diffs (37 lines):

diff -r 13e36f31e331 -r 1ce9a0895630 src/njs_utils.c
--- a/src/njs_utils.c	Tue Jun 02 14:59:27 2020 +0000
+++ b/src/njs_utils.c	Tue Jun 02 14:59:30 2020 +0000
@@ -241,7 +241,7 @@ void
 njs_qsort(void *arr, size_t n, size_t esize, njs_sort_cmp_t cmp, void *ctx)
 {
     int                r;
-    u_char             *base, *lt, *gt, *p, *end;
+    u_char             *base, *lt, *gt, *c, *p, *end;
     njs_uint_t         m4;
     njs_swap_t         swap;
     njs_qsort_state_t  stack[NJS_MAX_DEPTH], *sp;
@@ -321,9 +321,8 @@ njs_qsort(void *arr, size_t n, size_t es
         /* Insertion sort. */
 
         for (p = base + esize; p < end; p += esize) {
-            while (p > base && cmp(p, p - esize, ctx) < 0) {
-                swap(p, p - esize, esize);
-                p -= esize;
+            for (c = p; c > base && cmp(c, c - esize, ctx) < 0; c -= esize) {
+                swap(c, c - esize, esize);
             }
         }
     }
diff -r 13e36f31e331 -r 1ce9a0895630 src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c	Tue Jun 02 14:59:27 2020 +0000
+++ b/src/test/njs_unit_test.c	Tue Jun 02 14:59:30 2020 +0000
@@ -6101,6 +6101,9 @@ static njs_unit_test_t  njs_test[] =
               "a.sort((a, b) => b.r - a.r).map(v=>v.n).join('')"),
       njs_str("BDEAC") },
 
+    { njs_str("[1,2,3].sort(()=>-1)"),
+      njs_str("3,2,1") },
+
     { njs_str("var count = 0;"
               "[4,3,2,1].sort(function(x, y) { if (count++ == 2) {throw Error('Oops'); }; return x - y })"),
       njs_str("Error: Oops") },


More information about the nginx-devel mailing list