node icon indicating copy to clipboard operation
node copied to clipboard

lib: the REPL should survive deletion of Array.prototype methods

Open ljharb opened this issue 5 years ago • 33 comments

Specifically, delete Array.prototype.lastIndexOf immediately crashes the REPL, as does deletion of a few other Array prototype methods.

Checklist
  • [x] make -j4 test (UNIX), or vcbuild test (Windows) passes
  • [ ] tests and/or benchmarks are included
  • [ ] documentation is changed or added
  • [x] commit message follows commit guidelines

ljharb avatar Jan 22 '20 08:01 ljharb

I will rebase it within the next hour or two, for sure :-)

ljharb avatar Jan 22 '20 16:01 ljharb

Rebased, and added a bunch of other primordials I found when poking around the repl.

ljharb avatar Jan 22 '20 18:01 ljharb

Not sure why the python tests are failing :-/

ljharb avatar Jan 22 '20 22:01 ljharb

Not sure why the python tests are failing :-/

For the same reason Travis is failing; there are several failing repl tests.

richardlau avatar Jan 22 '20 22:01 richardlau

CI: https://ci.nodejs.org/job/node-test-pull-request/28577/

nodejs-github-bot avatar Jan 22 '20 22:01 nodejs-github-bot

alright, got tests passing :-D this is ready for any additional/final/repeat reviews, and is ready to land whenever it's allowed to!

ljharb avatar Jan 23 '20 06:01 ljharb

Can/should we add a test that crashes the current REPL but not the REPL with these changes?

Trott avatar Jan 23 '20 23:01 Trott

I took the liberty of adding a test. Hope that's OK. (It's in a separate commit so it is easy to rebase out.)

Trott avatar Jan 23 '20 23:01 Trott

CI: https://ci.nodejs.org/job/node-test-pull-request/28595/

nodejs-github-bot avatar Jan 23 '20 23:01 nodejs-github-bot

Absolutely it's OK, thank you! I commented with a possible improvement.

ljharb avatar Jan 23 '20 23:01 ljharb

CI: https://ci.nodejs.org/job/node-test-pull-request/28645/

nodejs-github-bot avatar Jan 25 '20 15:01 nodejs-github-bot

Are these 3 test failures something due to my PR, or are they expected?

ljharb avatar Jan 25 '20 16:01 ljharb

Are these 3 test failures something due to my PR, or are they expected?

It looks like the test fails if run in a worker (tools/test.py --worker path/to/test-file.js). That needs to be addressed here, but the Windows failures are CI and I'm taking some nodes offline temporarily to work around that.

Trott avatar Jan 25 '20 16:01 Trott

Test failure when run with tools/test.py --worker:

07:51:07 not ok 1665 parallel/test-repl-delete-array-prototype
07:51:07   ---
07:51:07   duration_ms: 0.272
07:51:07   severity: fail
07:51:07   exitcode: 1
07:51:07   stack: |-
07:51:07     > undefined
07:51:07     events.js:298
07:51:07           throw er; // Unhandled 'error' event
07:51:07           ^
07:51:07     
07:51:07     Error [ERR_WORKER_UNSERIALIZABLE_ERROR]: Serializing an uncaught exception failed
07:51:07         at Worker.[kOnCouldNotSerializeErr] (internal/worker.js:198:24)
07:51:07         at Worker.[kOnMessage] (internal/worker.js:212:45)
07:51:07         at MessagePort.<anonymous> (internal/worker.js:141:57)
07:51:07         at MessagePort.emit (events.js:321:20)
07:51:07         at MessagePort.onmessage (internal/worker/io.js:78:8)
07:51:07     Emitted 'error' event on Worker instance at:
07:51:07         at Worker.[kOnCouldNotSerializeErr] (internal/worker.js:198:10)
07:51:07         at Worker.[kOnMessage] (internal/worker.js:212:45)
07:51:07         [... lines matching original stack trace ...]
07:51:07         at MessagePort.onmessage (internal/worker/io.js:78:8) {
07:51:07       code: 'ERR_WORKER_UNSERIALIZABLE_ERROR'
07:51:07     }
07:51:07   ...

Trott avatar Jan 25 '20 16:01 Trott

Thanks, i’ll fix that :-)

ljharb avatar Jan 25 '20 16:01 ljharb

@addaleax i'm having trouble figuring out how to trace where this error comes from. What code determines how errors are serialized, and where does it live?

ljharb avatar Jan 25 '20 17:01 ljharb

@ljharb You may be interested in workerOnGlobalUncaughtException in lib/internal/main/worker_thread.js, and serializeError in lib/internal/error-serdes.js?

Let me know if you’d like me to look into it. The code is supposed to be resilient against prototype deletion, so I’d be very curious to know what happens there…

addaleax avatar Jan 25 '20 18:01 addaleax

@addaleax thank you, that is most helpful! Unfortunately, spread syntax (..., as in ...args) is not robust against modification, because it invokes Array.prototype[Symbol.iterator]. I'll update the PR to avoid using that syntax, but that still didn't seem to be fixing the problem - so I kept digging, and it turns out that SafeSet itself is not safe, because it's invoking the iterator protocol on its constructor argument. Rather than try to fix SafeSet, i refactored to avoid passing the constructor argument.

That still didn't fix the problem, though, because I'd previously modified the test to only delete string properties off of Array :-/

That led me to the internal inspect, which is relying on prototype methods, spread syntax, and for..of; I'm working on fixing that now.

ljharb avatar Jan 25 '20 23:01 ljharb

I'm at a loss; is there any way I can locally initiate a debugger inside the worker, so i can introspect any errors prior to them being serialized?

ljharb avatar Jan 26 '20 07:01 ljharb

ok, i did a bunch of manual retries and figured out a few more methods that weren't robustly being accessed.

There's still at least one call to .push on an array somewhere, so the test currently does not delete that method in order to pass in the worker.

What would be nice is to land this now-quite-large PR, and then I can work on push and the Symbol properties, and perhaps String.prototype properties, in a followup PR?

ljharb avatar Jan 28 '20 08:01 ljharb

CI: https://ci.nodejs.org/job/node-test-pull-request/28735/

nodejs-github-bot avatar Jan 28 '20 16:01 nodejs-github-bot

(a few tests are failing in Travis; I’ll fix those in the next hour or three)

ljharb avatar Jan 28 '20 17:01 ljharb

Should we do some benchmark runs?

devsnek avatar Jan 28 '20 17:01 devsnek

Once tests are passing, that’d be great - there’s only one change i made that comments imply was in a hot path, but that’s one more than i want to make slower.

ljharb avatar Jan 28 '20 17:01 ljharb

CI: https://ci.nodejs.org/job/node-test-pull-request/28775/

nodejs-github-bot avatar Jan 30 '20 07:01 nodejs-github-bot

The performance overhead should be much less after we land V8 8.0: https://v8.dev/blog/v8-release-80#optimizing-higher-order-builtins

targos avatar Jan 30 '20 09:01 targos

I don’t think it’s true that any other program would necessarily fail in the case of these methods being removed; altho many people don’t code robustly, there are many of us that do. Either way, it’s one thing for a user modifying the env to break their own app; it’s another for it to break the platform itself.

As for the performance overhead, that’s definitely an issue :-/ but my personal philosophy is that correctness always trumps performance.

Where does this go from here? What are possible next steps?

ljharb avatar Jan 30 '20 17:01 ljharb

Most of these changes have now landed, thanks (i believe) to @aduh95.

I've rebased this, and I think it should still land. cc @BridgeAR?

ljharb avatar Dec 28 '20 01:12 ljharb

CI: https://ci.nodejs.org/job/node-test-pull-request/35128/

nodejs-github-bot avatar Dec 28 '20 18:12 nodejs-github-bot

Removed the "Author Ready" given @BridgeAR's request changes on this.

jasnell avatar Jan 25 '21 14:01 jasnell