[njs] Fixed Buffer.prototype.lastIndexOf() when `from` is provided.

noreply at nginx.com noreply at nginx.com
Thu Oct 10 16:44:02 UTC 2024


details:   https://github.com/nginx/njs/commit/e0563f4dd6a2ab52b4796b5cc536ce14e8ad6483
branches:  master
commit:    e0563f4dd6a2ab52b4796b5cc536ce14e8ad6483
user:      Dmitry Volyntsev <xeioex at nginx.com>
date:      Wed, 9 Oct 2024 17:59:26 -0700
description:
Fixed Buffer.prototype.lastIndexOf() when `from` is provided.

Previous incorrect fix was introduced in 5d15a8d6 (0.8.5).

---
 src/njs_buffer.c | 15 +++++++++------
 src/qjs_buffer.c | 16 +++++++++-------
 test/buffer.t.js |  2 ++
 3 files changed, 20 insertions(+), 13 deletions(-)

diff --git a/src/njs_buffer.c b/src/njs_buffer.c
index 0bd5b896..20618d24 100644
--- a/src/njs_buffer.c
+++ b/src/njs_buffer.c
@@ -2218,13 +2218,12 @@ encoding:
             goto done;
         }
 
-        if (str.length > (size_t) length) {
-            goto done;
-        }
-
         if (last) {
-            from -= str.length - 1;
-            from = njs_max(from, 0);
+            from = njs_min(from, length - (int64_t) str.length);
+
+            if (to > from) {
+                goto done;
+            }
 
         } else {
             to -= str.length - 1;
@@ -2246,6 +2245,10 @@ encoding:
     case NJS_NUMBER:
         byte = njs_number_to_uint32(njs_number(value));
 
+        if (last) {
+            from = njs_min(from, length - 1);
+        }
+
         for (i = from; i != to; i += increment) {
             if (u8[i] == byte) {
                 index = i;
diff --git a/src/qjs_buffer.c b/src/qjs_buffer.c
index 5def5e63..8a7b10ff 100644
--- a/src/qjs_buffer.c
+++ b/src/qjs_buffer.c
@@ -1047,6 +1047,10 @@ qjs_buffer_prototype_index_of(JSContext *ctx, JSValueConst this_val, int argc,
             return JS_EXCEPTION;
         }
 
+        if (last) {
+            from = njs_min(from, length - 1);
+        }
+
         for (i = from; i != to; i += increment) {
             if (self.start[i] == (uint8_t) byte) {
                 return JS_NewInt32(ctx, i);
@@ -1087,14 +1091,12 @@ encoding:
         return JS_NewInt32(ctx, (last) ? length : 0);
     }
 
-    if (str.length > (size_t) length) {
-        JS_FreeValue(ctx, buffer);
-        return JS_NewInt32(ctx, -1);
-    }
-
     if (last) {
-        from -= str.length - 1;
-        from = njs_max(from, 0);
+        from = njs_min(from, length - (int64_t) str.length);
+
+        if (to > from) {
+            goto done;
+        }
 
     } else {
         to -= str.length - 1;
diff --git a/test/buffer.t.js b/test/buffer.t.js
index f47c62f7..0b8db0d3 100644
--- a/test/buffer.t.js
+++ b/test/buffer.t.js
@@ -583,6 +583,7 @@ let lastIndexOf_tsuite = {
         { buf: Buffer.from('abcdef'), value: 'def', expected: 3 },
         { buf: Buffer.from('abcdef'), value: 'abc', offset: 1, expected: 0 },
         { buf: Buffer.from('abcdef'), value: 'def', offset: 1, expected: -1 },
+        { buf: Buffer.from('xxxABCx'), value: 'ABC', offset: 3, expected: 3 },
         { buf: Buffer.from(Buffer.alloc(7).fill('Zabcdef').buffer, 1), value: 'abcdef', expected: 0 },
         { buf: Buffer.from(Buffer.alloc(7).fill('Zabcdef').buffer, 1), value: 'abcdefg', expected: -1 },
         { buf: Buffer.from('abcdef'), value: '626364', encoding: 'hex', expected: 1 },
@@ -590,6 +591,7 @@ let lastIndexOf_tsuite = {
           exception: 'TypeError: "utf-128" encoding is not supported' },
         { buf: Buffer.from('abcabc'), value: 0x61, expected: 3 },
         { buf: Buffer.from('abcabc'), value: 0x61, offset: 1, expected: 0 },
+        { buf: Buffer.from('ab'), value: 7, offset: 2, expected: -1 },
         { buf: Buffer.from('abcdef'), value: Buffer.from('def'), expected: 3 },
         { buf: Buffer.from('abcdef'), value: Buffer.from(new Uint8Array([0x60, 0x62, 0x63]).buffer, 1), expected: 1 },
         { buf: Buffer.from('abcdef'), value: {},


More information about the nginx-devel mailing list