diff --git a/src/node_buffer.cc b/src/node_buffer.cc index 2d00ca97cc0f58..bc8c7cba5b0724 100644 --- a/src/node_buffer.cc +++ b/src/node_buffer.cc @@ -607,13 +607,37 @@ int32_t IndexOf(const char* haystack, const char* needle, size_t n_length) { CHECK_GE(h_length, n_length); - // TODO(trevnorris): Implement Boyer-Moore string search algorithm. - for (size_t i = 0; i < h_length - n_length + 1; i++) { - if (haystack[i] == needle[0]) { - if (memcmp(haystack + i, needle, n_length) == 0) - return i; - } + + const char* inc; + const void* ptr; + + // Guard against zero length searches + if (h_length == 0 || n_length == 0 || n_length > h_length) + return -1; + + // Single character case + if (n_length == 1) { + ptr = memchr(haystack, *needle, h_length); + if (ptr == nullptr) + return -1; + return static_cast<int32_t>(static_cast<const char*>(ptr) - haystack); } + + // Do multicharacter string match + inc = haystack; + do { + ptr = memchr(inc, *needle, h_length - static_cast<int32_t>(inc - haystack)); + if (ptr != nullptr) { + const void* ptr2 = memmem(inc, + h_length - static_cast<int32_t>(inc - haystack), + needle, + n_length); + if (ptr2 != nullptr) + return static_cast<int32_t>(static_cast<const char*>(ptr2) - haystack); + inc = static_cast<const char*>(ptr); + } + } while (ptr != nullptr); + return -1; } diff --git a/test/parallel/test-buffer-indexof.js b/test/parallel/test-buffer-indexof.js index 32748dcaaab727..daae45a4f6bf2b 100644 --- a/test/parallel/test-buffer-indexof.js +++ b/test/parallel/test-buffer-indexof.js @@ -26,6 +26,7 @@ assert.equal(b.indexOf('bc', -5), 1); assert.equal(b.indexOf('bc', NaN), 1); assert.equal(b.indexOf('bc', -Infinity), 1); assert.equal(b.indexOf('bc', Infinity), -1); +assert.equal(b.indexOf('cd'), 2); assert.equal(b.indexOf('f'), b.length - 1); assert.equal(b.indexOf('z'), -1); assert.equal(b.indexOf(''), -1);