You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Buffer#indexOf()/lastIndexOf()/includes() abort the process when end is not a number #66589
v27.0.0-nightly20261007aa1bf2cc37 (main at 9899b39)
Platform
Linux x64
Subsystem
buffer
What steps will reproduce the bug?
constbuf=Buffer.from('abcabc');// Each of these aborts the process, try/catch does not help:buf.indexOf('a',0,null);buf.includes(97,0,null);buf.lastIndexOf(Buffer.from('a'),5,{});// These return -1, expected 0:buf.indexOf('a',0,Infinity);buf.indexOf(97,0,1e20);
How often does it reproduce? Is there a required condition?
Always. Any end other than a number, a string or undefined aborts (null, booleans, objects, arrays, BigInts, symbols). Numbers outside the int64 range give a wrong result on x64.
What is the expected behavior? Why is that the expected behavior?
end is documented as {integer}, so a wrong type should throw ERR_INVALID_ARG_TYPE instead of aborting. Infinity should be clamped to buf.length, the same way end = 100 already is.
The three methods only handle end in JS when it is a string (treated as the encoding) or undefined; anything else goes straight to the binding. IndexOfString and IndexOfBuffer do CHECK(args[5]->IsNumber()) and SlowIndexOfNumber does CHECK(args[4]->IsNumber()). Numbers are read with As<Integer>()->Value(), which for NaN, ±Infinity or values beyond int64 is an undefined double-to-int64 conversion (INT64_MIN on x64, which is then clamped to 0).
end was added in #62390. I have a fix and will open a PR.
I'd like to take this. The crash is in src/node_buffer.cc: the fast-path helpers (e.g. IndexOfString) read end straight from �rgs[5] and assert �rgs[5]->IsNumber(), so a non-number end hits the V8/CHECK assertion and aborts instead of surfacing a normal TypeError. Booleans,
ull, objects, arrays, BigInt and symbols all take that path, and ry/catch can't help because it's an abort.
Fix: validate end before the assertion — accept only numbers/strings/undefined (coercing where the existing C++ helpers already expect it, e.g. via the same Value::Int32Value/ToInteger path used elsewhere in the file) and throw ERR_INVALID_ARG_TYPE otherwise, matching the {integer} docs. Also clamp Infinity/out-of-int64-range values to �uf.length instead of wrapping (currently indexOf('a', 0, Infinity) returns -1).
I'll cover it with tests in est/parallel/test-buffer-indexof.js (and the includes/lastIndexOf variants). I'd like to take this.
Activity
buffer: validate end argument of indexOf methods
Yusuf-Hussien commentedon Oct 8, 2026
I'd like to take this. The crash is in src/node_buffer.cc: the fast-path helpers (e.g. IndexOfString) read end straight from �rgs[5] and assert �rgs[5]->IsNumber(), so a non-number end hits the V8/CHECK assertion and aborts instead of surfacing a normal TypeError. Booleans,
ull, objects, arrays, BigInt and symbols all take that path, and ry/catch can't help because it's an abort.
Fix: validate end before the assertion — accept only numbers/strings/undefined (coercing where the existing C++ helpers already expect it, e.g. via the same Value::Int32Value/ToInteger path used elsewhere in the file) and throw ERR_INVALID_ARG_TYPE otherwise, matching the {integer} docs. Also clamp Infinity/out-of-int64-range values to �uf.length instead of wrapping (currently indexOf('a', 0, Infinity) returns -1).
I'll cover it with tests in est/parallel/test-buffer-indexof.js (and the includes/lastIndexOf variants). I'd like to take this.