[njs] Fixed Buffer.prototype.indexOf() and friends.

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


details:   https://github.com/nginx/njs/commit/5a8bb2d172ad080efc0d719e7df609ac5355992e
branches:  master
commit:    5a8bb2d172ad080efc0d719e7df609ac5355992e
user:      Dmitry Volyntsev <xeioex at nginx.com>
date:      Wed, 9 Oct 2024 18:25:52 -0700
description:
Fixed Buffer.prototype.indexOf() and friends.

With empty buffers in both the self and search cases.

---
 src/njs_buffer.c | 39 ++++++++-------------------------------
 src/qjs_buffer.c | 39 ++++++++-------------------------------
 test/buffer.t.js | 26 ++++++++++++++++++++++++++
 3 files changed, 42 insertions(+), 62 deletions(-)

diff --git a/src/njs_buffer.c b/src/njs_buffer.c
index 20618d24..2f0fc620 100644
--- a/src/njs_buffer.c
+++ b/src/njs_buffer.c
@@ -2117,10 +2117,6 @@ njs_buffer_prototype_index_of(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     index = -1;
 
-    if (njs_slow_path(array->byte_length == 0)) {
-        goto done;
-    }
-
     length = array->byte_length;
 
     if (last) {
@@ -2145,30 +2141,11 @@ njs_buffer_prototype_index_of(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
             return ret;
         }
 
-        if (last) {
-            if (from >= 0) {
-                from = njs_min(from, length - 1);
-
-            } else if (from < 0) {
-                from += length;
-            }
-
-            if (from <= to) {
-                goto done;
-            }
+        if (from >= 0) {
+            from = njs_min(from, length);
 
         } else {
-            if (from < 0) {
-                from += length;
-
-                if (from < 0) {
-                    from = 0;
-                }
-            }
-
-            if (from >= to) {
-                goto done;
-            }
+            from = njs_max(0, length + from);
         }
     }
 
@@ -2213,11 +2190,6 @@ encoding:
             str.length = src->byte_length;
         }
 
-        if (njs_slow_path(str.length == 0)) {
-            index = (last) ? length : 0;
-            goto done;
-        }
-
         if (last) {
             from = njs_min(from, length - (int64_t) str.length);
 
@@ -2233,6 +2205,11 @@ encoding:
             }
         }
 
+        if (from == to && str.length == 0) {
+            index = 0;
+            goto done;
+        }
+
         for (i = from; i != to; i += increment) {
             if (memcmp(&u8[i], str.start, str.length) == 0) {
                 index = i;
diff --git a/src/qjs_buffer.c b/src/qjs_buffer.c
index 8a7b10ff..02618387 100644
--- a/src/qjs_buffer.c
+++ b/src/qjs_buffer.c
@@ -988,10 +988,6 @@ qjs_buffer_prototype_index_of(JSContext *ctx, JSValueConst this_val, int argc,
 
     length = self.length;
 
-    if (length == 0) {
-        return JS_NewInt32(ctx, -1);
-    }
-
     if (last) {
         from = length - 1;
         to = -1;
@@ -1015,30 +1011,11 @@ qjs_buffer_prototype_index_of(JSContext *ctx, JSValueConst this_val, int argc,
             return JS_EXCEPTION;
         }
 
-        if (last) {
-            if (from >= 0) {
-                from = njs_min(from, length - 1);
-
-            } else if (from < 0) {
-                from += length;
-            }
-
-            if (from <= to) {
-                return JS_NewInt32(ctx, -1);
-            }
+        if (from >= 0) {
+            from = njs_min(from, length);
 
         } else {
-            if (from < 0) {
-                from += length;
-
-                if (from < 0) {
-                    from = 0;
-                }
-            }
-
-            if (from >= to) {
-                return JS_NewInt32(ctx, -1);
-            }
+            from = njs_max(0, length + from);
         }
     }
 
@@ -1086,11 +1063,6 @@ encoding:
                                 "or Buffer-like object");
     }
 
-    if (str.length == 0) {
-        JS_FreeValue(ctx, buffer);
-        return JS_NewInt32(ctx, (last) ? length : 0);
-    }
-
     if (last) {
         from = njs_min(from, length - (int64_t) str.length);
 
@@ -1106,6 +1078,11 @@ encoding:
         }
     }
 
+    if (from == to && str.length == 0) {
+        JS_FreeValue(ctx, buffer);
+        return JS_NewInt32(ctx, 0);
+    }
+
     for (i = from; i != to; i += increment) {
         if (memcmp(&self.start[i], str.start, str.length) == 0) {
             JS_FreeValue(ctx, buffer);
diff --git a/test/buffer.t.js b/test/buffer.t.js
index 0b8db0d3..9becf487 100644
--- a/test/buffer.t.js
+++ b/test/buffer.t.js
@@ -474,6 +474,19 @@ let indexOf_tsuite = {
         { buf: Buffer.from('abcdef'), value: 'def', offset: 1, expected: 3 },
         { buf: Buffer.from('abcdef'), value: 'def', offset: -3, expected: 3 },
         { buf: Buffer.from('abcdef'), value: 'efgh', offset: 4, expected: -1 },
+        { buf: Buffer.from(''), value: '', expected: 0 },
+        { buf: Buffer.from(''), value: '', offset: -1, expected: 0 },
+        { buf: Buffer.from(''), value: '', offset: 0, expected: 0 },
+        { buf: Buffer.from(''), value: '', offset: 1, expected: 0 },
+        { buf: Buffer.from('abc'), value: '', offset: -4, expected: 0 },
+        { buf: Buffer.from('abc'), value: '', offset: -3, expected: 0 },
+        { buf: Buffer.from('abc'), value: '', offset: -2, expected: 1 },
+        { buf: Buffer.from('abc'), value: '', offset: -1, expected: 2 },
+        { buf: Buffer.from('abc'), value: '', offset: 0, expected: 0 },
+        { buf: Buffer.from('abc'), value: '', offset: 1, expected: 1 },
+        { buf: Buffer.from('abc'), value: '', offset: 2, expected: 2 },
+        { buf: Buffer.from('abc'), value: '', offset: 3, expected: 3 },
+        { buf: Buffer.from('abc'), value: '', offset: 4, expected: 3 },
         { buf: Buffer.from('abcdef'), value: '626364', encoding: 'hex', expected: 1 },
         { buf: Buffer.from('abcdef'), value: '626364', encoding: 'utf-128',
           exception: 'TypeError: "utf-128" encoding is not supported' },
@@ -584,6 +597,19 @@ let lastIndexOf_tsuite = {
         { 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(''), value: '', expected: 0 },
+        { buf: Buffer.from(''), value: '', offset: -1, expected: 0 },
+        { buf: Buffer.from(''), value: '', offset: 0, expected: 0 },
+        { buf: Buffer.from(''), value: '', offset: 1, expected: 0 },
+        { buf: Buffer.from('abc'), value: '', offset: -4, expected: 0 },
+        { buf: Buffer.from('abc'), value: '', offset: -3, expected: 0 },
+        { buf: Buffer.from('abc'), value: '', offset: -2, expected: 1 },
+        { buf: Buffer.from('abc'), value: '', offset: -1, expected: 2 },
+        { buf: Buffer.from('abc'), value: '', offset: 0, expected: 0 },
+        { buf: Buffer.from('abc'), value: '', offset: 1, expected: 1 },
+        { buf: Buffer.from('abc'), value: '', offset: 2, expected: 2 },
+        { buf: Buffer.from('abc'), value: '', offset: 3, expected: 3 },
+        { buf: Buffer.from('abc'), value: '', offset: 4, 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 },


More information about the nginx-devel mailing list