Skip to content

Commit e8438c1

Browse files
TrottMylesBorins
authored andcommitted
timers: do not use user object call/apply
Timers should work even if the user has monkey-patched `.call()` and `.apply()` to undesirable values. PR-URL: #12960 Ref: #12956 Reviewed-By: Refael Ackermann <[email protected]> Reviewed-By: Jeremiah Senkpiel <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Joyee Cheung <[email protected]> Reviewed-By: Rich Trott <[email protected]>
1 parent 74d5cba commit e8438c1

File tree

2 files changed

+46
-6
lines changed

2 files changed

+46
-6
lines changed

lib/timers.js

+6-6
Original file line numberDiff line numberDiff line change
@@ -383,20 +383,20 @@ function ontimeout(timer) {
383383
var args = timer._timerArgs;
384384
var callback = timer._onTimeout;
385385
if (!args)
386-
callback.call(timer);
386+
timer._onTimeout();
387387
else {
388388
switch (args.length) {
389389
case 1:
390-
callback.call(timer, args[0]);
390+
timer._onTimeout(args[0]);
391391
break;
392392
case 2:
393-
callback.call(timer, args[0], args[1]);
393+
timer._onTimeout(args[0], args[1]);
394394
break;
395395
case 3:
396-
callback.call(timer, args[0], args[1], args[2]);
396+
timer._onTimeout(args[0], args[1], args[2]);
397397
break;
398398
default:
399-
callback.apply(timer, args);
399+
Function.prototype.apply.call(callback, timer, args);
400400
}
401401
}
402402
if (timer._repeat)
@@ -678,7 +678,7 @@ function runCallback(timer) {
678678
return timer._callback(argv[0], argv[1], argv[2]);
679679
// more than 3 arguments run slower with .apply
680680
default:
681-
return timer._callback.apply(timer, argv);
681+
return Function.prototype.apply.call(timer._callback, timer, argv);
682682
}
683683
}
684684

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// Make sure `setTimeout()` and friends don't throw if the user-supplied
2+
// function has .call() and .apply() monkey-patched to undesirable values.
3+
4+
// Refs: https://github.com/nodejs/node/issues/12956
5+
6+
'use strict';
7+
8+
const common = require('../common');
9+
10+
{
11+
const fn = common.mustCall(10);
12+
fn.call = 'not a function';
13+
fn.apply = 'also not a function';
14+
setTimeout(fn, 1);
15+
setTimeout(fn, 1, 'oneArg');
16+
setTimeout(fn, 1, 'two', 'args');
17+
setTimeout(fn, 1, 'three', '(3)', 'args');
18+
setTimeout(fn, 1, 'more', 'than', 'three', 'args');
19+
20+
setImmediate(fn, 1);
21+
setImmediate(fn, 1, 'oneArg');
22+
setImmediate(fn, 1, 'two', 'args');
23+
setImmediate(fn, 1, 'three', '(3)', 'args');
24+
setImmediate(fn, 1, 'more', 'than', 'three', 'args');
25+
}
26+
27+
{
28+
const testInterval = (...args) => {
29+
const fn = common.mustCall(() => { clearInterval(interval); });
30+
fn.call = 'not a function';
31+
fn.apply = 'also not a function';
32+
const interval = setInterval(fn, 1, ...args);
33+
};
34+
35+
testInterval();
36+
testInterval('oneArg');
37+
testInterval('two', 'args');
38+
testInterval('three', '(3)', 'args');
39+
testInterval('more', 'than', 'three', 'args');
40+
}

0 commit comments

Comments
 (0)