Repository navigation
Assigning a value to Array.prototype[1] will result in an error :node:internal/process/task_queues:77 callback(); #54472
Description
Activity
I'm unable to reproduce in v22.6.0, but I haven't tested in v20. @LoongZP can you reproduce in the latest version of v20? (v20.16.0)
➜ ~ node Welcome to Node.js v22.6.0. Type ".help" for more information. > Array.prototype[1] = 2 2 > console.log(Array.prototype); Object(2) [ <1 empty item>, 2 ] undefined >
@redyetidev
The strange thing is that I also have no error when executing in interactive mode in node, it only occurs when node xx.js, which I also found in v22.3.0.I'll retest later, but for now could you try to reproduce in the latest version of those release lines?
v22.6.0
v20.16.0@redyetidev
I also tried it in ubuntu (node v20.11.1.) and found this issue as well.@redyetidev
I've tried the following:os node version result my coputer Microsoft Windows NT 10.0.22631.0 x64 22.6.0 x my coputer Microsoft Windows NT 10.0.22631.0 x64 22.3.0 x my coputer Microsoft Windows NT 10.0.22631.0 x64 20.14.0 x other's coputer Linux version 5.15.0-118-generic (buildd@lcy02-amd64-103) (gcc (Ubuntu 9.4.0-1ubuntu1 20.04.2) 9.4.0, GNU ld (GNU Binutils for Ubuntu) 2.34) #12820.04.1-Ubuntu SMP Wed Jul 17 13:41:17 UTC 202420.11.1 x other's coputer Microsoft Windows NT 10.0.22631.0 x64 20.9.9 x NOTE:
It's strange that there is no problem with assigning a value to Array.prototype[0/2/3/4...].Array.prototype[1] = 2; console.log(Array.prototype);
$ node repro.js Object(2) [ <1 empty item>, 2 ] node:internal/process/task_queues:77 callback(); ^ TypeError: callback is not a function at process.processTicksAndRejections (node:internal/process/task_queues:77:11) Node.js v22.6.0
Array.prototype[0] = 2; console.log(Array.prototype);
$ node repro.js Object(1) [ 2 ]
@redyetidev
So what is the reason, it's a very strange mistake.- addedconsoleIssues and PRs related to the console subsystem.Issues and PRs related to the console subsystem.
on Aug 21, 2024 I think leaving first index cause the issue
Array.prototype[0]=2;
let problem = Array.prototype;
console.log(problem);C:\Users\Moorthi\De
Object(1) [ 2 ]I think leaving first index cause the issue
Array.prototype[0]=2; let problem = Array.prototype; console.log(problem);
C:\Users\Moorthi\De Object(1) [ 2 ]
No, you can try the code below:
Array.prototype[2] = 2;
let problem = Array.prototype;
console.log(problem);Array.prototype[2] = 2;
let problem = Array.prototype;
console.log(problem);The failing line is:
node/lib/internal/process/task_queues.js
Line 85 in 8b0c699
callback(); So something is calling that line incorrectly when
Array.prototype[1]isn't what it should be...I've added the
consolelabel, as this isn't reproducible without callingconsole.log.
The following prefixes each behave differently:
// Crashes Array.prototype[1] = 1;
// Hangs Array.prototype[1] = null;
// Works normally Array.prototype[1] = undefined;
The error can be reproduced without console (but this function is called from the console.log call):
process.nextTick(()=>{});
- addedprocessIssues and PRs related to the process subsystem.Issues and PRs related to the process subsystem.and removedconsoleIssues and PRs related to the console subsystem.Issues and PRs related to the console subsystem.
on Aug 21, 2024 @nodejs/process
15 remaining items
Just thought asking about the "out of bound access issue here" - the
this.listwill bekSizehere which is2048when initialised. And this line here with bit mask should prevent the out of bound access issue.We totally should fix the one Antoine pointed out (where node core dumps). Even if we don't do primordials everywhere for readability/performance we totally still should in error paths so users can tell why their code failed.
new Array()doesn't actually initialize it, it'll need to be filled or otherwise it's still an out-of-bound access that leads to prototype lookup.Actually, this rings a bell - we should probably just forbid
new Arraywith the linter. I made a similar argument against holey arrays in #52058 (comment) (it can also lead to worse performance in array accesses).we should probably just forbid
new Arraywith the linter.I agree. #54281 fixed a similar issue.
it's still an out-of-bound access that leads to prototype lookup.
Much appreciated! Now I understood 🙏
- added a commit that references this issue
on Sep 2, 2024 - added a commit that references this issue
on Sep 12, 2024 - added 3 commits that reference this issue
on Sep 22, 2024
Version
v20.14.0
Platform
Subsystem
No response
What steps will reproduce the bug?
code:
Array.prototype[1] = 2
console.log(Array.prototype);
result:

How often does it reproduce? Is there a required condition?
When I knew that Array.prototype was an Array, I tried to assign a value to Array.prototype[x].
Assigning only Array.prototype[1] results in an error that will occur when reading Array.prototype.
What is the expected behavior? Why is that the expected behavior?
In Chrome, you will get the following results:
Array.prototype[1] = 2
console.log(Array.prototype);
result:
[1: 2, at: ƒ, concat: ƒ, copyWithin: ƒ, fill: ƒ, find: ƒ, …]
What do you see instead?
code:
Array.prototype[1] = 2
console.log(Array.prototype);
result:
Object(2) [ <1 empty item>, 2 ]
node:internal/process/task_queues:77
callback();
^
TypeError: callback is not a function
at process.processTicksAndRejections (node:internal/process/task_queues:77:11)
Node.js v20.14.0
Additional information
No response