Skip to content

Commit 6fc20c5

Browse files
addaleaxevanlucas
authored andcommitted
buffer: fix lastIndexOf crash for overlong needle
Return -1 in `Buffer.lastIndexOf` if the needle is longer than the haystack. The previous check only tested the corresponding condition for forward searches. This applies only to Node.js v6, as `lastIndexOf` was added in it. Fixes: #6510 PR-URL: #6511 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Trevor Norris <trev.norris@gmail.com>
1 parent 4401575 commit 6fc20c5

2 files changed

Lines changed: 27 additions & 2 deletions

File tree

‎src/node_buffer.cc‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1009,7 +1009,8 @@ void IndexOfString(const FunctionCallbackInfo<Value>& args) {
10091009
}
10101010
size_t offset = static_cast<size_t>(opt_offset);
10111011
CHECK_LT(offset, haystack_length);
1012-
if (is_forward && needle_length + offset > haystack_length) {
1012+
if ((is_forward && needle_length + offset > haystack_length) ||
1013+
needle_length > haystack_length) {
10131014
return args.GetReturnValue().Set(-1);
10141015
}
10151016

@@ -1111,7 +1112,8 @@ void IndexOfBuffer(const FunctionCallbackInfo<Value>& args) {
11111112
}
11121113
size_t offset = static_cast<size_t>(opt_offset);
11131114
CHECK_LT(offset, haystack_length);
1114-
if (is_forward && needle_length + offset > haystack_length) {
1115+
if ((is_forward && needle_length + offset > haystack_length) ||
1116+
needle_length > haystack_length) {
11151117
return args.GetReturnValue().Set(-1);
11161118
}
11171119

‎test/parallel/test-buffer-indexof.js‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,12 +345,35 @@ assert.equal(b.lastIndexOf('b', {}), 1);
345345
assert.equal(b.lastIndexOf('b',[]),-1);
346346
assert.equal(b.lastIndexOf('b',[2]),1);
347347

348+
// Test needles longer than the haystack.
349+
assert.strictEqual(b.lastIndexOf('aaaaaaaaaaaaaaa','ucs2'),-1);
350+
assert.strictEqual(b.lastIndexOf('aaaaaaaaaaaaaaa','utf8'),-1);
351+
assert.strictEqual(b.lastIndexOf('aaaaaaaaaaaaaaa','binary'),-1);
352+
assert.strictEqual(b.lastIndexOf(Buffer.from('aaaaaaaaaaaaaaa')),-1);
353+
assert.strictEqual(b.lastIndexOf('aaaaaaaaaaaaaaa',2,'ucs2'),-1);
354+
assert.strictEqual(b.lastIndexOf('aaaaaaaaaaaaaaa',3,'utf8'),-1);
355+
assert.strictEqual(b.lastIndexOf('aaaaaaaaaaaaaaa',5,'binary'),-1);
356+
assert.strictEqual(b.lastIndexOf(Buffer.from('aaaaaaaaaaaaaaa'),7),-1);
357+
358+
// 你好 expands to a total of 6 bytes using UTF-8 and 4 bytes using UTF-16
359+
assert.strictEqual(buf_bc.lastIndexOf('你好','ucs2'),-1);
360+
assert.strictEqual(buf_bc.lastIndexOf('你好','utf8'),-1);
361+
assert.strictEqual(buf_bc.lastIndexOf('你好','binary'),-1);
362+
assert.strictEqual(buf_bc.lastIndexOf(Buffer.from('你好')),-1);
363+
assert.strictEqual(buf_bc.lastIndexOf('你好',2,'ucs2'),-1);
364+
assert.strictEqual(buf_bc.lastIndexOf('你好',3,'utf8'),-1);
365+
assert.strictEqual(buf_bc.lastIndexOf('你好',5,'binary'),-1);
366+
assert.strictEqual(buf_bc.lastIndexOf(Buffer.from('你好'),7),-1);
367+
348368
// Test lastIndexOf on a longer buffer:
349369
varbufferString=newBuffer('a man a plan a canal panama');
350370
assert.equal(15,bufferString.lastIndexOf('canal'));
351371
assert.equal(21,bufferString.lastIndexOf('panama'));
352372
assert.equal(0,bufferString.lastIndexOf('a man a plan a canal panama'));
353373
assert.equal(-1,bufferString.lastIndexOf('a man a plan a canal mexico'));
374+
assert.equal(-1,bufferString.lastIndexOf('a man a plan a canal mexico city'));
375+
assert.equal(-1,bufferString.lastIndexOf(Buffer.from('a'.repeat(1000))));
376+
assert.equal(0,bufferString.lastIndexOf('a man a plan',4));
354377
assert.equal(13,bufferString.lastIndexOf('a '));
355378
assert.equal(13,bufferString.lastIndexOf('a ',13));
356379
assert.equal(6,bufferString.lastIndexOf('a ',12));

0 commit comments

Comments
 (0)