Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | 1x 1x 1x 1x 40x 40x 40x 40x 40x 40x 40x 36x 40x 39x 39x 7x 32x 32x 32x 32x 32x 32x 32x 1x 31x 31x 1x 30x 1x 1x | 'use strict';
const fs = require('fs');
const runtimePath = require('../runtime-path');
const ConsoleAgent = require('../ConsoleAgent');
const ErrorParser = require('../parse-error');
class NodeAgent extends ConsoleAgent {
compile(code) {
code = super.compile(code);
// `JSON.stringify` replaces BACKSPACE, CHARACTER TABULATION, LINE FEED
// (LF), FORM FEED (FF), CARRIAGE RETURN (CR), QUOTATION MARK, and REVERSE
// SOLIDUS [1]. This does not include two valid ECMAScript line
// terminators: LINE SEPARATOR, and PARAGRAPH SEPARATOR [2]. Those two code
// points must be explicitly escaped from the output of `JSON.stringify` so
// that the source can be safely included in a dynamically-evaluated
// string.
//
// [1] https://tc39.github.io/ecma262/#table-json-single-character-escapes
// [2] https://tc39.github.io/ecma262/#table-33
const escaped = JSON.stringify(code)
.replace(/\u2028/g, '\\u2028')
.replace(/\u2029/g, '\\u2029');
// Because the input code may modify the global environment in ways that
// interfere with the normal operation of `eshost`, it must be run in a
// dedicated virtual machine.
//
// The "context" object for this virtual machine should be re-used if the
// input code invokes `$.evalScript`, but Node.js does not tolerate sharing
// context objects across virtual machines in this manner. Instead, define
// a new method for evaluating scripts in the context created here.
//
// The "print" function is defined here, instead of runtimes/node.js because
// not all code will be run with the entire host runtime.
code = `
Function("return this;")().require = require;
var vm = require("vm");
var eshostContext = vm.createContext({
setTimeout,
require,
console,
print(...args) {
console.log(...args);
}
});
vm.runInESHostContext = function(code, options) {
return vm.runInContext(code, eshostContext, options);
};
vm.runInESHostContext(${escaped});
`;
return code;
}
async evalScript(code, options = {}) {
Iif (options.module && this.args[0] !== '--experimental-modules') {
this.args.unshift('--experimental-modules');
}
Iif (!options.module && this.args[0] === '--experimental-modules') {
this.args.shift();
}
if (!this.args.includes('--expose-gc')) {
this.args.push('--expose-gc');
}
return super.evalScript(code, options);
}
parseError(str) {
let parsed = ErrorParser.parse(str);
if (parsed) {
return parsed;
}
const errorexp = /^[\w\d]+(:.*)?(?:(\r?\n\s+at.*)+|\r?\n$)/m;
const nodeerrorexp = /^([\w\d]+)(?:\s+)(?:\{\s+message:\s+'(.*)'\s+\})/gm;
const customerrorexp = /^(?:[\w\d]+)(?:\s+)(?:\{(?:\s+name:\s+'(.*)',\s+message:\s+'(.*)'\s+)\})/gm;
let match = str.match(errorexp);
Eif (!match) {
match = nodeerrorexp.exec(str);
if (match && match.length === 3) {
return {
name: match[1],
message: match[2],
stack: []
};
} else {
match = customerrorexp.exec(str);
if (match && match.length === 3) {
return {
name: match[1],
message: match[2],
stack: []
};
}
}
}
return null;
}
}
NodeAgent.runtime = fs.readFileSync(runtimePath.for('node'), 'utf8');
module.exports = NodeAgent;
|