mirror of
https://github.com/nodejs/node.git
synced 2024-11-21 10:59:27 +00:00
domain: make node resilient to Array prototype tempering
Fixes: https://github.com/nodejs/node/issues/36669 PR-URL: https://github.com/nodejs/node/pull/36676 Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
parent
421279bfee
commit
83b428a954
@ -319,7 +319,7 @@ Domain.prototype.exit = function() {
|
||||
// Exit all domains until this one.
|
||||
ArrayPrototypeSplice(stack, index);
|
||||
|
||||
exports.active = stack[stack.length - 1];
|
||||
exports.active = stack.length === 0 ? undefined : stack[stack.length - 1];
|
||||
process.domain = exports.active;
|
||||
updateExceptionCapture();
|
||||
};
|
||||
|
66
test/parallel/test-repl-array-prototype-tempering.js
Normal file
66
test/parallel/test-repl-array-prototype-tempering.js
Normal file
@ -0,0 +1,66 @@
|
||||
'use strict';
|
||||
const common = require('../common');
|
||||
const assert = require('assert');
|
||||
const { spawn } = require('child_process');
|
||||
|
||||
const replProcess = spawn(process.argv0, ['--interactive'], {
|
||||
stdio: ['pipe', 'pipe', 'inherit'],
|
||||
windowsHide: true,
|
||||
});
|
||||
|
||||
replProcess.on('error', common.mustNotCall());
|
||||
|
||||
const replReadyState = (async function* () {
|
||||
let ready;
|
||||
const SPACE = ' '.charCodeAt();
|
||||
const BRACKET = '>'.charCodeAt();
|
||||
const DOT = '.'.charCodeAt();
|
||||
replProcess.stdout.on('data', (data) => {
|
||||
ready = data[data.length - 1] === SPACE && (
|
||||
data[data.length - 2] === BRACKET || (
|
||||
data[data.length - 2] === DOT &&
|
||||
data[data.length - 3] === DOT &&
|
||||
data[data.length - 4] === DOT
|
||||
));
|
||||
});
|
||||
|
||||
const processCrashed = new Promise((resolve, reject) =>
|
||||
replProcess.on('exit', reject)
|
||||
);
|
||||
while (true) {
|
||||
await Promise.race([new Promise(setImmediate), processCrashed]);
|
||||
if (ready) {
|
||||
ready = false;
|
||||
yield;
|
||||
}
|
||||
}
|
||||
})();
|
||||
async function writeLn(data, expectedOutput) {
|
||||
await replReadyState.next();
|
||||
if (expectedOutput) {
|
||||
replProcess.stdout.once('data', common.mustCall((data) =>
|
||||
assert.match(data.toString('utf8'), expectedOutput)
|
||||
));
|
||||
}
|
||||
await new Promise((resolve, reject) => replProcess.stdin.write(
|
||||
`${data}\n`,
|
||||
(err) => (err ? reject(err) : resolve())
|
||||
));
|
||||
}
|
||||
|
||||
async function main() {
|
||||
await writeLn(
|
||||
'Object.defineProperty(Array.prototype, "-1", ' +
|
||||
'{ get() { return this[this.length - 1]; } });'
|
||||
);
|
||||
|
||||
await writeLn(
|
||||
'[3, 2, 1][-1];',
|
||||
/^1\n(>\s)?$/
|
||||
);
|
||||
await writeLn('.exit');
|
||||
|
||||
assert(!replProcess.connected);
|
||||
}
|
||||
|
||||
main().then(common.mustCall());
|
Loading…
Reference in New Issue
Block a user