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 <[email protected]> Reviewed-By: Trevor Norris <[email protected]>
1 parent 4401575 commit 6fc20c5

File tree

2 files changed

+27
-2
lines changed

2 files changed

+27
-2
lines changed

src/node_buffer.cc

+4-2
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

+23
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
var bufferString = new Buffer('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)