mirror of
https://github.com/fofolee/uTools-quickcommand.git
synced 2025-06-29 20:32:44 +08:00
vm 即将在渲染进程内被禁用,改用简单的沙箱执行命令
This commit is contained in:
parent
24d0dd1e2a
commit
a27fe4c338
53
plugin/lib/nodeFns.js
Normal file
53
plugin/lib/nodeFns.js
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
const nodeFns = {
|
||||||
|
AbortController,
|
||||||
|
AbortSignal,
|
||||||
|
Array,
|
||||||
|
ArrayBuffer,
|
||||||
|
Boolean,
|
||||||
|
Buffer,
|
||||||
|
DataView,
|
||||||
|
Date,
|
||||||
|
Error,
|
||||||
|
EvalError,
|
||||||
|
Float32Array,
|
||||||
|
Float64Array,
|
||||||
|
Function,
|
||||||
|
Infinity,
|
||||||
|
Int16Array,
|
||||||
|
Int32Array,
|
||||||
|
Int8Array,
|
||||||
|
Intl,
|
||||||
|
JSON,
|
||||||
|
Math,
|
||||||
|
NaN,
|
||||||
|
Number,
|
||||||
|
Object,
|
||||||
|
RangeError,
|
||||||
|
ReferenceError,
|
||||||
|
RegExp,
|
||||||
|
String,
|
||||||
|
SyntaxError,
|
||||||
|
TypeError,
|
||||||
|
URIError,
|
||||||
|
URL,
|
||||||
|
URLSearchParams,
|
||||||
|
Uint16Array,
|
||||||
|
Uint32Array,
|
||||||
|
Uint8Array,
|
||||||
|
Uint8ClampedArray,
|
||||||
|
atob,
|
||||||
|
btoa,
|
||||||
|
decodeURI,
|
||||||
|
decodeURIComponent,
|
||||||
|
encodeURI,
|
||||||
|
encodeURIComponent,
|
||||||
|
escape,
|
||||||
|
isFinite,
|
||||||
|
isNaN,
|
||||||
|
parseFloat,
|
||||||
|
parseInt,
|
||||||
|
require,
|
||||||
|
unescape,
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = nodeFns
|
@ -1,3 +0,0 @@
|
|||||||
if (parseInt(process.versions.node.split('.')[0]) < 6) throw new Error('vm2 requires Node.js version 6 or newer.');
|
|
||||||
|
|
||||||
module.exports = require('./lib/main');
|
|
@ -1,35 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
const pa = require('path');
|
|
||||||
|
|
||||||
const {NodeVM, VMError} = require('../');
|
|
||||||
|
|
||||||
if (process.argv[2]) {
|
|
||||||
const path = pa.resolve(process.argv[2]);
|
|
||||||
|
|
||||||
console.log(`\x1B[90m[vm] creating VM for ${path}\x1B[39m`);
|
|
||||||
const started = Date.now();
|
|
||||||
|
|
||||||
try {
|
|
||||||
NodeVM.file(path, {
|
|
||||||
verbose: true,
|
|
||||||
require: {
|
|
||||||
external: true
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log(`\x1B[90m[vm] VM completed in ${Date.now() - started}ms\x1B[39m`);
|
|
||||||
} catch (ex) {
|
|
||||||
if (ex instanceof VMError) {
|
|
||||||
console.error(`\x1B[31m[vm:error] ${ex.message}\x1B[39m`);
|
|
||||||
} else {
|
|
||||||
const {stack} = ex;
|
|
||||||
|
|
||||||
if (stack) {
|
|
||||||
console.error(`\x1B[31m[vm:error] ${stack}\x1B[39m`);
|
|
||||||
} else {
|
|
||||||
console.error(`\x1B[31m[vm:error] ${ex}\x1B[39m`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
@ -1,83 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
// eslint-disable-next-line no-invalid-this, no-shadow
|
|
||||||
const {GeneratorFunction, AsyncFunction, AsyncGeneratorFunction, global, internal, host, hook} = this;
|
|
||||||
const {Contextify, Decontextify} = internal;
|
|
||||||
// eslint-disable-next-line no-shadow
|
|
||||||
const {Function, eval: eval_, Promise, Object, Reflect} = global;
|
|
||||||
const {getOwnPropertyDescriptor, defineProperty, assign} = Object;
|
|
||||||
const {apply: rApply, construct: rConstruct} = Reflect;
|
|
||||||
|
|
||||||
const FunctionHandler = {
|
|
||||||
__proto__: null,
|
|
||||||
apply(target, thiz, args) {
|
|
||||||
const type = this.type;
|
|
||||||
args = Decontextify.arguments(args);
|
|
||||||
try {
|
|
||||||
args = Contextify.value(hook(type, args));
|
|
||||||
} catch (e) {
|
|
||||||
throw Contextify.value(e);
|
|
||||||
}
|
|
||||||
return rApply(target, thiz, args);
|
|
||||||
},
|
|
||||||
construct(target, args, newTarget) {
|
|
||||||
const type = this.type;
|
|
||||||
args = Decontextify.arguments(args);
|
|
||||||
try {
|
|
||||||
args = Contextify.value(hook(type, args));
|
|
||||||
} catch (e) {
|
|
||||||
throw Contextify.value(e);
|
|
||||||
}
|
|
||||||
return rConstruct(target, args, newTarget);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function makeCheckFunction(type) {
|
|
||||||
return assign({
|
|
||||||
__proto__: null,
|
|
||||||
type
|
|
||||||
}, FunctionHandler);
|
|
||||||
}
|
|
||||||
|
|
||||||
function override(obj, prop, value) {
|
|
||||||
const desc = getOwnPropertyDescriptor(obj, prop);
|
|
||||||
desc.value = value;
|
|
||||||
defineProperty(obj, prop, desc);
|
|
||||||
}
|
|
||||||
|
|
||||||
const proxiedFunction = new host.Proxy(Function, makeCheckFunction('function'));
|
|
||||||
override(Function.prototype, 'constructor', proxiedFunction);
|
|
||||||
if (GeneratorFunction) {
|
|
||||||
Object.setPrototypeOf(GeneratorFunction, proxiedFunction);
|
|
||||||
override(GeneratorFunction.prototype, 'constructor', new host.Proxy(GeneratorFunction, makeCheckFunction('generator_function')));
|
|
||||||
}
|
|
||||||
if (AsyncFunction) {
|
|
||||||
Object.setPrototypeOf(AsyncFunction, proxiedFunction);
|
|
||||||
override(AsyncFunction.prototype, 'constructor', new host.Proxy(AsyncFunction, makeCheckFunction('async_function')));
|
|
||||||
}
|
|
||||||
if (AsyncGeneratorFunction) {
|
|
||||||
Object.setPrototypeOf(AsyncGeneratorFunction, proxiedFunction);
|
|
||||||
override(AsyncGeneratorFunction.prototype, 'constructor', new host.Proxy(AsyncGeneratorFunction, makeCheckFunction('async_generator_function')));
|
|
||||||
}
|
|
||||||
|
|
||||||
global.Function = proxiedFunction;
|
|
||||||
global.eval = new host.Proxy(eval_, makeCheckFunction('eval'));
|
|
||||||
|
|
||||||
if (Promise) {
|
|
||||||
|
|
||||||
Promise.prototype.then = new host.Proxy(Promise.prototype.then, makeCheckFunction('promise_then'));
|
|
||||||
// This seems not to work, and will produce
|
|
||||||
// UnhandledPromiseRejectionWarning: TypeError: Method Promise.prototype.then called on incompatible receiver [object Object].
|
|
||||||
// This is likely caused since the host.Promise.prototype.then cannot use the VM Proxy object.
|
|
||||||
// Contextify.connect(host.Promise.prototype.then, Promise.prototype.then);
|
|
||||||
|
|
||||||
if (Promise.prototype.finally) {
|
|
||||||
Promise.prototype.finally = new host.Proxy(Promise.prototype.finally, makeCheckFunction('promise_finally'));
|
|
||||||
// Contextify.connect(host.Promise.prototype.finally, Promise.prototype.finally);
|
|
||||||
}
|
|
||||||
if (Promise.prototype.catch) {
|
|
||||||
Promise.prototype.catch = new host.Proxy(Promise.prototype.catch, makeCheckFunction('promise_catch'));
|
|
||||||
// Contextify.connect(host.Promise.prototype.catch, Promise.prototype.catch);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
// source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#Escaping
|
|
||||||
function escapeRegExp(string) {
|
|
||||||
return string.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
|
|
||||||
}
|
|
||||||
|
|
||||||
function match(wildcard, s) {
|
|
||||||
const regexString = escapeRegExp(wildcard).replace(/\\\*/g, '\\S*').replace(/\\\?/g, '.');
|
|
||||||
const regex = new RegExp(regexString);
|
|
||||||
return regex.test(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {match};
|
|
File diff suppressed because it is too large
Load Diff
@ -1,682 +0,0 @@
|
|||||||
/* eslint-disable no-shadow, no-invalid-this */
|
|
||||||
/* global vm, host, Contextify, Decontextify, VMError, options */
|
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
const {Script} = host.require('vm');
|
|
||||||
const fs = host.require('fs');
|
|
||||||
const pa = host.require('path');
|
|
||||||
|
|
||||||
const BUILTIN_MODULES = host.process.binding('natives');
|
|
||||||
const parseJSON = JSON.parse;
|
|
||||||
const importModuleDynamically = () => {
|
|
||||||
// We can't throw an error object here because since vm.Script doesn't store a context, we can't properly contextify that error object.
|
|
||||||
// eslint-disable-next-line no-throw-literal
|
|
||||||
throw 'Dynamic imports are not allowed.';
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Object} host Hosts's internal objects.
|
|
||||||
*/
|
|
||||||
|
|
||||||
return ((vm, host) => {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
const global = this;
|
|
||||||
|
|
||||||
const TIMERS = new host.WeakMap(); // Contains map of timers created inside sandbox
|
|
||||||
const BUILTINS = {__proto__: null};
|
|
||||||
const CACHE = {__proto__: null};
|
|
||||||
const EXTENSIONS = {
|
|
||||||
__proto__: null,
|
|
||||||
['.json'](module, filename) {
|
|
||||||
try {
|
|
||||||
const code = fs.readFileSync(filename, 'utf8');
|
|
||||||
module.exports = parseJSON(code);
|
|
||||||
} catch (e) {
|
|
||||||
throw Contextify.value(e);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
['.node'](module, filename) {
|
|
||||||
if (vm.options.require.context === 'sandbox') throw new VMError('Native modules can be required only with context set to \'host\'.');
|
|
||||||
|
|
||||||
try {
|
|
||||||
module.exports = Contextify.readonly(host.require(filename));
|
|
||||||
} catch (e) {
|
|
||||||
throw Contextify.value(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
for (let i = 0; i < vm.options.sourceExtensions.length; i++) {
|
|
||||||
const ext = vm.options.sourceExtensions[i];
|
|
||||||
|
|
||||||
EXTENSIONS['.' + ext] = (module, filename, dirname) => {
|
|
||||||
if (vm.options.require.context !== 'sandbox') {
|
|
||||||
try {
|
|
||||||
module.exports = Contextify.readonly(host.require(filename));
|
|
||||||
} catch (e) {
|
|
||||||
throw Contextify.value(e);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let script;
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Load module
|
|
||||||
let contents = fs.readFileSync(filename, 'utf8');
|
|
||||||
contents = vm._compiler(contents, filename);
|
|
||||||
|
|
||||||
const code = host.STRICT_MODULE_PREFIX + contents + host.MODULE_SUFFIX;
|
|
||||||
|
|
||||||
const ccode = vm._hook('run', [code]);
|
|
||||||
|
|
||||||
// Precompile script
|
|
||||||
script = new Script(ccode, {
|
|
||||||
__proto__: null,
|
|
||||||
filename: filename || 'vm.js',
|
|
||||||
displayErrors: false,
|
|
||||||
importModuleDynamically
|
|
||||||
});
|
|
||||||
|
|
||||||
} catch (ex) {
|
|
||||||
throw Contextify.value(ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
const closure = script.runInContext(global, {
|
|
||||||
__proto__: null,
|
|
||||||
filename: filename || 'vm.js',
|
|
||||||
displayErrors: false,
|
|
||||||
importModuleDynamically
|
|
||||||
});
|
|
||||||
|
|
||||||
// run the script
|
|
||||||
closure(module.exports, module.require, module, filename, dirname);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const _parseExternalOptions = (options) => {
|
|
||||||
if (host.Array.isArray(options)) {
|
|
||||||
return {
|
|
||||||
__proto__: null,
|
|
||||||
external: options,
|
|
||||||
transitive: false
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
__proto__: null,
|
|
||||||
external: options.modules,
|
|
||||||
transitive: options.transitive
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resolve filename.
|
|
||||||
*/
|
|
||||||
|
|
||||||
const _resolveFilename = (path) => {
|
|
||||||
if (!path) return null;
|
|
||||||
let hasPackageJson;
|
|
||||||
try {
|
|
||||||
path = pa.resolve(path);
|
|
||||||
|
|
||||||
const exists = fs.existsSync(path);
|
|
||||||
const isdir = exists ? fs.statSync(path).isDirectory() : false;
|
|
||||||
|
|
||||||
// direct file match
|
|
||||||
if (exists && !isdir) return path;
|
|
||||||
|
|
||||||
// load as file
|
|
||||||
|
|
||||||
for (let i = 0; i < vm.options.sourceExtensions.length; i++) {
|
|
||||||
const ext = vm.options.sourceExtensions[i];
|
|
||||||
if (fs.existsSync(`${path}.${ext}`)) return `${path}.${ext}`;
|
|
||||||
}
|
|
||||||
if (fs.existsSync(`${path}.json`)) return `${path}.json`;
|
|
||||||
if (fs.existsSync(`${path}.node`)) return `${path}.node`;
|
|
||||||
|
|
||||||
// load as module
|
|
||||||
|
|
||||||
hasPackageJson = fs.existsSync(`${path}/package.json`);
|
|
||||||
} catch (e) {
|
|
||||||
throw Contextify.value(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasPackageJson) {
|
|
||||||
let pkg;
|
|
||||||
try {
|
|
||||||
pkg = fs.readFileSync(`${path}/package.json`, 'utf8');
|
|
||||||
} catch (e) {
|
|
||||||
throw Contextify.value(e);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
pkg = parseJSON(pkg);
|
|
||||||
} catch (ex) {
|
|
||||||
throw new VMError(`Module '${path}' has invalid package.json`, 'EMODULEINVALID');
|
|
||||||
}
|
|
||||||
|
|
||||||
let main;
|
|
||||||
if (pkg && pkg.main) {
|
|
||||||
main = _resolveFilename(`${path}/${pkg.main}`);
|
|
||||||
if (!main) main = _resolveFilename(`${path}/index`);
|
|
||||||
} else {
|
|
||||||
main = _resolveFilename(`${path}/index`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return main;
|
|
||||||
}
|
|
||||||
|
|
||||||
// load as directory
|
|
||||||
|
|
||||||
try {
|
|
||||||
for (let i = 0; i < vm.options.sourceExtensions.length; i++) {
|
|
||||||
const ext = vm.options.sourceExtensions[i];
|
|
||||||
if (fs.existsSync(`${path}/index.${ext}`)) return `${path}/index.${ext}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fs.existsSync(`${path}/index.json`)) return `${path}/index.json`;
|
|
||||||
if (fs.existsSync(`${path}/index.node`)) return `${path}/index.node`;
|
|
||||||
} catch (e) {
|
|
||||||
throw Contextify.value(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Builtin require.
|
|
||||||
*/
|
|
||||||
|
|
||||||
const _requireBuiltin = (moduleName) => {
|
|
||||||
if (moduleName === 'buffer') return ({Buffer});
|
|
||||||
if (BUILTINS[moduleName]) return BUILTINS[moduleName].exports; // Only compiled builtins are stored here
|
|
||||||
|
|
||||||
if (moduleName === 'util') {
|
|
||||||
return Contextify.readonly(host.require(moduleName), {
|
|
||||||
// Allows VM context to use util.inherits
|
|
||||||
__proto__: null,
|
|
||||||
inherits: (ctor, superCtor) => {
|
|
||||||
ctor.super_ = superCtor;
|
|
||||||
Object.setPrototypeOf(ctor.prototype, superCtor.prototype);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (moduleName === 'events' || moduleName === 'internal/errors') {
|
|
||||||
let script;
|
|
||||||
try {
|
|
||||||
script = new Script(`(function (exports, require, module, process, internalBinding) {
|
|
||||||
'use strict';
|
|
||||||
const primordials = global;
|
|
||||||
${BUILTIN_MODULES[moduleName]}
|
|
||||||
\n
|
|
||||||
});`, {
|
|
||||||
filename: `${moduleName}.vm.js`
|
|
||||||
});
|
|
||||||
|
|
||||||
} catch (e) {
|
|
||||||
throw Contextify.value(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
// setup module scope
|
|
||||||
const module = BUILTINS[moduleName] = {
|
|
||||||
exports: {},
|
|
||||||
require: _requireBuiltin
|
|
||||||
};
|
|
||||||
|
|
||||||
// run script
|
|
||||||
try {
|
|
||||||
// FIXME binding should be contextified
|
|
||||||
script.runInContext(global)(module.exports, module.require, module, host.process, host.process.binding);
|
|
||||||
} catch (e) {
|
|
||||||
// e could be from inside or outside of sandbox
|
|
||||||
throw new VMError(`Error loading '${moduleName}'`);
|
|
||||||
}
|
|
||||||
return module.exports;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Contextify.readonly(host.require(moduleName));
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prepare require.
|
|
||||||
*/
|
|
||||||
|
|
||||||
const _prepareRequire = (currentDirname, parentAllowsTransitive = false) => {
|
|
||||||
const _require = moduleName => {
|
|
||||||
let requireObj;
|
|
||||||
try {
|
|
||||||
const optionsObj = vm.options;
|
|
||||||
if (optionsObj.nesting && moduleName === 'vm2') return {VM: Contextify.readonly(host.VM), NodeVM: Contextify.readonly(host.NodeVM)};
|
|
||||||
requireObj = optionsObj.require;
|
|
||||||
} catch (e) {
|
|
||||||
throw Contextify.value(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!requireObj) throw new VMError(`Access denied to require '${moduleName}'`, 'EDENIED');
|
|
||||||
if (moduleName == null) throw new VMError("Module '' not found.", 'ENOTFOUND');
|
|
||||||
if (typeof moduleName !== 'string') throw new VMError(`Invalid module name '${moduleName}'`, 'EINVALIDNAME');
|
|
||||||
|
|
||||||
let filename;
|
|
||||||
let allowRequireTransitive = false;
|
|
||||||
|
|
||||||
// Mock?
|
|
||||||
|
|
||||||
try {
|
|
||||||
const {mock} = requireObj;
|
|
||||||
if (mock) {
|
|
||||||
const mockModule = mock[moduleName];
|
|
||||||
if (mockModule) {
|
|
||||||
return Contextify.readonly(mockModule);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
throw Contextify.value(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Builtin?
|
|
||||||
|
|
||||||
if (BUILTIN_MODULES[moduleName]) {
|
|
||||||
let allowed;
|
|
||||||
try {
|
|
||||||
const builtinObj = requireObj.builtin;
|
|
||||||
if (host.Array.isArray(builtinObj)) {
|
|
||||||
if (builtinObj.indexOf('*') >= 0) {
|
|
||||||
allowed = builtinObj.indexOf(`-${moduleName}`) === -1;
|
|
||||||
} else {
|
|
||||||
allowed = builtinObj.indexOf(moduleName) >= 0;
|
|
||||||
}
|
|
||||||
} else if (builtinObj) {
|
|
||||||
allowed = builtinObj[moduleName];
|
|
||||||
} else {
|
|
||||||
allowed = false;
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
throw Contextify.value(e);
|
|
||||||
}
|
|
||||||
if (!allowed) throw new VMError(`Access denied to require '${moduleName}'`, 'EDENIED');
|
|
||||||
|
|
||||||
return _requireBuiltin(moduleName);
|
|
||||||
}
|
|
||||||
|
|
||||||
// External?
|
|
||||||
|
|
||||||
let externalObj;
|
|
||||||
try {
|
|
||||||
externalObj = requireObj.external;
|
|
||||||
} catch (e) {
|
|
||||||
throw Contextify.value(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!externalObj) throw new VMError(`Access denied to require '${moduleName}'`, 'EDENIED');
|
|
||||||
|
|
||||||
if (/^(\.|\.\/|\.\.\/)/.exec(moduleName)) {
|
|
||||||
// Module is relative file, e.g. ./script.js or ../script.js
|
|
||||||
|
|
||||||
if (!currentDirname) throw new VMError('You must specify script path to load relative modules.', 'ENOPATH');
|
|
||||||
|
|
||||||
filename = _resolveFilename(`${currentDirname}/${moduleName}`);
|
|
||||||
} else if (/^(\/|\\|[a-zA-Z]:\\)/.exec(moduleName)) {
|
|
||||||
// Module is absolute file, e.g. /script.js or //server/script.js or C:\script.js
|
|
||||||
|
|
||||||
filename = _resolveFilename(moduleName);
|
|
||||||
} else {
|
|
||||||
// Check node_modules in path
|
|
||||||
|
|
||||||
if (!currentDirname) throw new VMError('You must specify script path to load relative modules.', 'ENOPATH');
|
|
||||||
|
|
||||||
if (typeof externalObj === 'object') {
|
|
||||||
let isWhitelisted;
|
|
||||||
try {
|
|
||||||
const { external, transitive } = _parseExternalOptions(externalObj);
|
|
||||||
|
|
||||||
isWhitelisted = external.some(ext => host.helpers.match(ext, moduleName)) || (transitive && parentAllowsTransitive);
|
|
||||||
} catch (e) {
|
|
||||||
throw Contextify.value(e);
|
|
||||||
}
|
|
||||||
if (!isWhitelisted) {
|
|
||||||
throw new VMError(`The module '${moduleName}' is not whitelisted in VM.`, 'EDENIED');
|
|
||||||
}
|
|
||||||
|
|
||||||
allowRequireTransitive = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME the paths array has side effects
|
|
||||||
const paths = currentDirname.split(pa.sep);
|
|
||||||
|
|
||||||
while (paths.length) {
|
|
||||||
const path = paths.join(pa.sep);
|
|
||||||
|
|
||||||
// console.log moduleName, "#{path}#{pa.sep}node_modules#{pa.sep}#{moduleName}"
|
|
||||||
|
|
||||||
filename = _resolveFilename(`${path}${pa.sep}node_modules${pa.sep}${moduleName}`);
|
|
||||||
if (filename) break;
|
|
||||||
|
|
||||||
paths.pop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!filename) {
|
|
||||||
let resolveFunc;
|
|
||||||
try {
|
|
||||||
resolveFunc = requireObj.resolve;
|
|
||||||
} catch (e) {
|
|
||||||
throw Contextify.value(e);
|
|
||||||
}
|
|
||||||
if (resolveFunc) {
|
|
||||||
let resolved;
|
|
||||||
try {
|
|
||||||
resolved = requireObj.resolve(moduleName, currentDirname);
|
|
||||||
} catch (e) {
|
|
||||||
throw Contextify.value(e);
|
|
||||||
}
|
|
||||||
filename = _resolveFilename(resolved);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!filename) throw new VMError(`Cannot find module '${moduleName}'`, 'ENOTFOUND');
|
|
||||||
|
|
||||||
// return cache whenever possible
|
|
||||||
if (CACHE[filename]) return CACHE[filename].exports;
|
|
||||||
|
|
||||||
const dirname = pa.dirname(filename);
|
|
||||||
const extname = pa.extname(filename);
|
|
||||||
|
|
||||||
let allowedModule = true;
|
|
||||||
try {
|
|
||||||
const rootObj = requireObj.root;
|
|
||||||
if (rootObj) {
|
|
||||||
const rootPaths = host.Array.isArray(rootObj) ? rootObj : host.Array.of(rootObj);
|
|
||||||
allowedModule = rootPaths.some(path => host.String.prototype.startsWith.call(dirname, pa.resolve(path)));
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
throw Contextify.value(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!allowedModule) {
|
|
||||||
throw new VMError(`Module '${moduleName}' is not allowed to be required. The path is outside the border!`, 'EDENIED');
|
|
||||||
}
|
|
||||||
|
|
||||||
const module = CACHE[filename] = {
|
|
||||||
filename,
|
|
||||||
exports: {},
|
|
||||||
require: _prepareRequire(dirname, allowRequireTransitive)
|
|
||||||
};
|
|
||||||
|
|
||||||
// lookup extensions
|
|
||||||
if (EXTENSIONS[extname]) {
|
|
||||||
EXTENSIONS[extname](module, filename, dirname);
|
|
||||||
return module.exports;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new VMError(`Failed to load '${moduleName}': Unknown type.`, 'ELOADFAIL');
|
|
||||||
};
|
|
||||||
|
|
||||||
return _require;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prepare sandbox.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// This is a function and not an arrow function, since the original is also a function
|
|
||||||
global.setTimeout = function setTimeout(callback, delay, ...args) {
|
|
||||||
if (typeof callback !== 'function') throw new TypeError('"callback" argument must be a function');
|
|
||||||
let tmr;
|
|
||||||
try {
|
|
||||||
tmr = host.setTimeout(Decontextify.value(() => {
|
|
||||||
// FIXME ...args has side effects
|
|
||||||
callback(...args);
|
|
||||||
}), Decontextify.value(delay));
|
|
||||||
} catch (e) {
|
|
||||||
throw Contextify.value(e);
|
|
||||||
}
|
|
||||||
const local = Contextify.value(tmr);
|
|
||||||
|
|
||||||
TIMERS.set(local, tmr);
|
|
||||||
return local;
|
|
||||||
};
|
|
||||||
|
|
||||||
global.setInterval = function setInterval(callback, interval, ...args) {
|
|
||||||
if (typeof callback !== 'function') throw new TypeError('"callback" argument must be a function');
|
|
||||||
let tmr;
|
|
||||||
try {
|
|
||||||
tmr = host.setInterval(Decontextify.value(() => {
|
|
||||||
// FIXME ...args has side effects
|
|
||||||
callback(...args);
|
|
||||||
}), Decontextify.value(interval));
|
|
||||||
} catch (e) {
|
|
||||||
throw Contextify.value(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
const local = Contextify.value(tmr);
|
|
||||||
|
|
||||||
TIMERS.set(local, tmr);
|
|
||||||
return local;
|
|
||||||
};
|
|
||||||
|
|
||||||
global.setImmediate = function setImmediate(callback, ...args) {
|
|
||||||
if (typeof callback !== 'function') throw new TypeError('"callback" argument must be a function');
|
|
||||||
let tmr;
|
|
||||||
try {
|
|
||||||
tmr = host.setImmediate(Decontextify.value(() => {
|
|
||||||
// FIXME ...args has side effects
|
|
||||||
callback(...args);
|
|
||||||
}));
|
|
||||||
} catch (e) {
|
|
||||||
throw Contextify.value(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
const local = Contextify.value(tmr);
|
|
||||||
|
|
||||||
TIMERS.set(local, tmr);
|
|
||||||
return local;
|
|
||||||
};
|
|
||||||
|
|
||||||
global.clearTimeout = function clearTimeout(local) {
|
|
||||||
try {
|
|
||||||
host.clearTimeout(TIMERS.get(local));
|
|
||||||
} catch (e) {
|
|
||||||
throw Contextify.value(e);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
global.clearInterval = function clearInterval(local) {
|
|
||||||
try {
|
|
||||||
host.clearInterval(TIMERS.get(local));
|
|
||||||
} catch (e) {
|
|
||||||
throw Contextify.value(e);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
global.clearImmediate = function clearImmediate(local) {
|
|
||||||
try {
|
|
||||||
host.clearImmediate(TIMERS.get(local));
|
|
||||||
} catch (e) {
|
|
||||||
throw Contextify.value(e);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function addListener(name, handler) {
|
|
||||||
if (name !== 'beforeExit' && name !== 'exit') {
|
|
||||||
throw new Error(`Access denied to listen for '${name}' event.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
host.process.on(name, Decontextify.value(handler));
|
|
||||||
} catch (e) {
|
|
||||||
throw Contextify.value(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
const {argv: optionArgv, env: optionsEnv} = options;
|
|
||||||
|
|
||||||
// FIXME wrong class structure
|
|
||||||
global.process = {
|
|
||||||
argv: optionArgv !== undefined ? Contextify.value(optionArgv) : [],
|
|
||||||
title: host.process.title,
|
|
||||||
version: host.process.version,
|
|
||||||
versions: Contextify.readonly(host.process.versions),
|
|
||||||
arch: host.process.arch,
|
|
||||||
platform: host.process.platform,
|
|
||||||
env: optionsEnv !== undefined ? Contextify.value(optionsEnv) : {},
|
|
||||||
pid: host.process.pid,
|
|
||||||
features: Contextify.readonly(host.process.features),
|
|
||||||
nextTick: function nextTick(callback, ...args) {
|
|
||||||
if (typeof callback !== 'function') {
|
|
||||||
throw new Error('Callback must be a function.');
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
host.process.nextTick(Decontextify.value(() => {
|
|
||||||
// FIXME ...args has side effects
|
|
||||||
callback(...args);
|
|
||||||
}));
|
|
||||||
} catch (e) {
|
|
||||||
throw Contextify.value(e);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
hrtime: function hrtime(time) {
|
|
||||||
try {
|
|
||||||
return Contextify.value(host.process.hrtime(Decontextify.value(time)));
|
|
||||||
} catch (e) {
|
|
||||||
throw Contextify.value(e);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
cwd: function cwd() {
|
|
||||||
try {
|
|
||||||
return Contextify.value(host.process.cwd());
|
|
||||||
} catch (e) {
|
|
||||||
throw Contextify.value(e);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
addListener,
|
|
||||||
on: addListener,
|
|
||||||
|
|
||||||
once: function once(name, handler) {
|
|
||||||
if (name !== 'beforeExit' && name !== 'exit') {
|
|
||||||
throw new Error(`Access denied to listen for '${name}' event.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
host.process.once(name, Decontextify.value(handler));
|
|
||||||
} catch (e) {
|
|
||||||
throw Contextify.value(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
listeners: function listeners(name) {
|
|
||||||
if (name !== 'beforeExit' && name !== 'exit') {
|
|
||||||
// Maybe add ({__proto__:null})[name] to throw when name fails in https://tc39.es/ecma262/#sec-topropertykey.
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Filter out listeners, which were not created in this sandbox
|
|
||||||
try {
|
|
||||||
return Contextify.value(host.process.listeners(name).filter(listener => Contextify.isVMProxy(listener)));
|
|
||||||
} catch (e) {
|
|
||||||
throw Contextify.value(e);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
removeListener: function removeListener(name, handler) {
|
|
||||||
if (name !== 'beforeExit' && name !== 'exit') {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
host.process.removeListener(name, Decontextify.value(handler));
|
|
||||||
} catch (e) {
|
|
||||||
throw Contextify.value(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
umask: function umask() {
|
|
||||||
if (arguments.length) {
|
|
||||||
throw new Error('Access denied to set umask.');
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
return Contextify.value(host.process.umask());
|
|
||||||
} catch (e) {
|
|
||||||
throw Contextify.value(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (vm.options.console === 'inherit') {
|
|
||||||
global.console = Contextify.readonly(host.console);
|
|
||||||
} else if (vm.options.console === 'redirect') {
|
|
||||||
global.console = {
|
|
||||||
debug(...args) {
|
|
||||||
try {
|
|
||||||
// FIXME ...args has side effects
|
|
||||||
vm.emit('console.debug', ...Decontextify.arguments(args));
|
|
||||||
} catch (e) {
|
|
||||||
throw Contextify.value(e);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
log(...args) {
|
|
||||||
try {
|
|
||||||
// FIXME ...args has side effects
|
|
||||||
vm.emit('console.log', ...Decontextify.arguments(args));
|
|
||||||
} catch (e) {
|
|
||||||
throw Contextify.value(e);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
info(...args) {
|
|
||||||
try {
|
|
||||||
// FIXME ...args has side effects
|
|
||||||
vm.emit('console.info', ...Decontextify.arguments(args));
|
|
||||||
} catch (e) {
|
|
||||||
throw Contextify.value(e);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
warn(...args) {
|
|
||||||
try {
|
|
||||||
// FIXME ...args has side effects
|
|
||||||
vm.emit('console.warn', ...Decontextify.arguments(args));
|
|
||||||
} catch (e) {
|
|
||||||
throw Contextify.value(e);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
error(...args) {
|
|
||||||
try {
|
|
||||||
// FIXME ...args has side effects
|
|
||||||
vm.emit('console.error', ...Decontextify.arguments(args));
|
|
||||||
} catch (e) {
|
|
||||||
throw Contextify.value(e);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
dir(...args) {
|
|
||||||
try {
|
|
||||||
vm.emit('console.dir', ...Decontextify.arguments(args));
|
|
||||||
} catch (e) {
|
|
||||||
throw Contextify.value(e);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
time() {},
|
|
||||||
timeEnd() {},
|
|
||||||
trace(...args) {
|
|
||||||
try {
|
|
||||||
// FIXME ...args has side effects
|
|
||||||
vm.emit('console.trace', ...Decontextify.arguments(args));
|
|
||||||
} catch (e) {
|
|
||||||
throw Contextify.value(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Return contextified require.
|
|
||||||
*/
|
|
||||||
|
|
||||||
return _prepareRequire;
|
|
||||||
})(vm, host);
|
|
@ -3,15 +3,11 @@ const os = require('os');
|
|||||||
const child_process = require("child_process")
|
const child_process = require("child_process")
|
||||||
const iconv = require('iconv-lite')
|
const iconv = require('iconv-lite')
|
||||||
const electron = require('electron')
|
const electron = require('electron')
|
||||||
const {
|
|
||||||
NodeVM,
|
|
||||||
VM
|
|
||||||
} = require('./lib/vm2')
|
|
||||||
const path = require("path")
|
const path = require("path")
|
||||||
const axios = require('axios');
|
const axios = require('axios');
|
||||||
const http = require('http');
|
const http = require('http');
|
||||||
const url = require('url')
|
const url = require('url')
|
||||||
|
const nodeFns = require("./lib/nodeFns")
|
||||||
window._ = require("lodash")
|
window._ = require("lodash")
|
||||||
window.yuQueClient = axios.create({
|
window.yuQueClient = axios.create({
|
||||||
baseURL: 'https://www.yuque.com/api/v2/',
|
baseURL: 'https://www.yuque.com/api/v2/',
|
||||||
@ -26,8 +22,6 @@ window.yuQueClient = axios.create({
|
|||||||
|
|
||||||
if (!utools.isWindows()) process.env.PATH += ':/usr/local/bin:/usr/local/sbin'
|
if (!utools.isWindows()) process.env.PATH += ':/usr/local/bin:/usr/local/sbin'
|
||||||
|
|
||||||
// window.startTime = new Date().getTime()
|
|
||||||
|
|
||||||
const shortCodes = [
|
const shortCodes = [
|
||||||
|
|
||||||
open = path => {
|
open = path => {
|
||||||
@ -199,7 +193,6 @@ window.temporaryStoreSoldOut = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// python -c
|
// python -c
|
||||||
window.runPythonCommand = py => {
|
window.runPythonCommand = py => {
|
||||||
try {
|
try {
|
||||||
@ -280,7 +273,6 @@ window.hexEncode = text => Buffer.from(text, 'utf8').toString('hex')
|
|||||||
window.hexDecode = text => Buffer.from(text, 'hex').toString('utf8')
|
window.hexDecode = text => Buffer.from(text, 'hex').toString('utf8')
|
||||||
window.base64Decode = text => Buffer.from(text, 'base64').toString('utf8')
|
window.base64Decode = text => Buffer.from(text, 'base64').toString('utf8')
|
||||||
|
|
||||||
|
|
||||||
window.processPlatform = process.platform
|
window.processPlatform = process.platform
|
||||||
window.joinPath = path.join
|
window.joinPath = path.join
|
||||||
|
|
||||||
@ -401,6 +393,15 @@ window.getSelectFile = hwnd => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window.showHelpPage = path => {
|
||||||
|
utools.ubrowser
|
||||||
|
.goto("https://www.yuque.com/fofolee-awga0/cpbg1m/bg31vl" + path)
|
||||||
|
.run({
|
||||||
|
width: 1380,
|
||||||
|
height: 750
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
window.clipboardReadText = () => electron.clipboard.readText()
|
window.clipboardReadText = () => electron.clipboard.readText()
|
||||||
|
|
||||||
window.convertFilePathToUtoolsPayload = files => files.map(file => {
|
window.convertFilePathToUtoolsPayload = files => files.map(file => {
|
||||||
@ -480,64 +481,58 @@ let getSandboxFuns = () => {
|
|||||||
shortCodes.forEach(f => {
|
shortCodes.forEach(f => {
|
||||||
sandbox[f.name] = f
|
sandbox[f.name] = f
|
||||||
})
|
})
|
||||||
|
Object.assign(sandbox, nodeFns)
|
||||||
return sandbox
|
return sandbox
|
||||||
}
|
}
|
||||||
|
|
||||||
let createNodeVM = (userVars) => {
|
// 简化报错信息
|
||||||
var sandbox = getSandboxFuns()
|
let liteErr = e => {
|
||||||
Object.assign(userVars, sandbox)
|
|
||||||
const vm = new NodeVM({
|
|
||||||
require: {
|
|
||||||
external: true,
|
|
||||||
builtin: ["*"],
|
|
||||||
},
|
|
||||||
console: 'redirect',
|
|
||||||
env: process.env,
|
|
||||||
sandbox: userVars,
|
|
||||||
});
|
|
||||||
return vm
|
|
||||||
}
|
|
||||||
|
|
||||||
window.showHelpPage = path => {
|
|
||||||
utools.ubrowser
|
|
||||||
.goto("https://www.yuque.com/fofolee-awga0/cpbg1m/bg31vl" + path)
|
|
||||||
.run({
|
|
||||||
width: 1380,
|
|
||||||
height: 750
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
window.VmEval = (cmd, sandbox = {}) => new VM({
|
|
||||||
sandbox: sandbox
|
|
||||||
}).run(cmd)
|
|
||||||
|
|
||||||
let isWatchingError = false
|
|
||||||
// The vm module of Node.js is deprecated in the renderer process and will be removed
|
|
||||||
window.runCodeInVm = (cmd, callback, userVars = {}) => {
|
|
||||||
const vm = createNodeVM(userVars)
|
|
||||||
//重定向 console
|
|
||||||
vm.on('console.log', (...stdout) => {
|
|
||||||
console.log(stdout);
|
|
||||||
callback(parseStdout(stdout), null)
|
|
||||||
});
|
|
||||||
|
|
||||||
vm.on('console.error', stderr => {
|
|
||||||
callback(null, stderr.toString())
|
|
||||||
});
|
|
||||||
|
|
||||||
let liteErr = e => {
|
|
||||||
if (!e) return
|
if (!e) return
|
||||||
return e.error ? e.error.stack.replace(/([ ] +at.+)|(.+\.js:\d+)/g, '').trim() : e.message
|
return e.error ? e.error.stack.replace(/([ ] +at.+)|(.+\.js:\d+)/g, '').trim() : e.message
|
||||||
}
|
}
|
||||||
|
|
||||||
// 错误处理
|
// vm 模块将无法在渲染进程中使用,改用简单的沙箱来执行代码
|
||||||
|
let createSandbox = (code, sandbox, async = false) => {
|
||||||
|
if (!async) code = `return (${code})`
|
||||||
|
const sandFn = new Function('sandbox', `with(sandbox){${code}}`);
|
||||||
|
const proxy = new Proxy(sandbox, {
|
||||||
|
has(target, key) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return sandFn(proxy);
|
||||||
|
}
|
||||||
|
|
||||||
|
window.evalCodeInSandbox = (code, userVars = {}) => {
|
||||||
|
let sandbox = getSandboxFuns()
|
||||||
|
let sandboxWithUV = Object.assign(userVars, sandbox)
|
||||||
try {
|
try {
|
||||||
vm.run(cmd, path.join(__dirname, 'preload.js'));
|
return createSandbox(code, sandboxWithUV);
|
||||||
|
} catch (error) {
|
||||||
|
throw liteErr(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let isWatchingError = false
|
||||||
|
window.runCodeInSandbox = (code, callback, userVars = {}) => {
|
||||||
|
let sandbox = getSandboxFuns()
|
||||||
|
sandbox.console = {
|
||||||
|
log: (...stdout) => {
|
||||||
|
console.log(stdout);
|
||||||
|
callback(parseStdout(stdout), null)
|
||||||
|
},
|
||||||
|
error: (...stderr) => {
|
||||||
|
callback(null, parseStdout(stderr))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let sandboxWithUV = Object.assign(userVars, sandbox)
|
||||||
|
try {
|
||||||
|
createSandbox(code, sandboxWithUV, true)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log('Error: ', e)
|
console.log('Error: ', e)
|
||||||
callback(null, liteErr(e))
|
callback(null, liteErr(e))
|
||||||
}
|
}
|
||||||
|
// 自动捕捉错误
|
||||||
let cbUnhandledError = e => {
|
let cbUnhandledError = e => {
|
||||||
removeAllListener()
|
removeAllListener()
|
||||||
console.log('UnhandledError: ', e)
|
console.log('UnhandledError: ', e)
|
||||||
@ -619,7 +614,7 @@ let httpServer
|
|||||||
window.quickcommandHttpServer = () => {
|
window.quickcommandHttpServer = () => {
|
||||||
let run = (cmd = '', port = 33442) => {
|
let run = (cmd = '', port = 33442) => {
|
||||||
let httpResponse = (res, code, result) => {
|
let httpResponse = (res, code, result) => {
|
||||||
// 因为无法判断 vm2 是否执行完毕,故只收受一次 console.log,接收后就关闭连接
|
// 只收受一次 console.log,接收后就关闭连接
|
||||||
if (res.finished) return
|
if (res.finished) return
|
||||||
res.writeHead(code, {
|
res.writeHead(code, {
|
||||||
'Content-Type': 'text/html'
|
'Content-Type': 'text/html'
|
||||||
@ -630,7 +625,7 @@ window.quickcommandHttpServer = () => {
|
|||||||
let runUserCode = (res, cmd, userVars) => {
|
let runUserCode = (res, cmd, userVars) => {
|
||||||
// 不需要返回输出的提前关闭连接
|
// 不需要返回输出的提前关闭连接
|
||||||
if (!cmd.includes('console.log')) httpResponse(res, 200)
|
if (!cmd.includes('console.log')) httpResponse(res, 200)
|
||||||
window.runCodeInVm(cmd, (stdout, stderr) => {
|
window.runCodeInSandbox(cmd, (stdout, stderr) => {
|
||||||
// 错误返回 500
|
// 错误返回 500
|
||||||
if (stderr) return httpResponse(res, 500, stderr)
|
if (stderr) return httpResponse(res, 500, stderr)
|
||||||
return httpResponse(res, 200, stdout)
|
return httpResponse(res, 200, stdout)
|
||||||
|
@ -97,7 +97,7 @@ export default {
|
|||||||
utools.outPlugin();
|
utools.outPlugin();
|
||||||
}, 500);
|
}, 500);
|
||||||
if (currentCommand.program === "quickcommand") {
|
if (currentCommand.program === "quickcommand") {
|
||||||
window.runCodeInVm(currentCommand.cmd, (stdout, stderr) => {
|
window.runCodeInSandbox(currentCommand.cmd, (stdout, stderr) => {
|
||||||
if (stderr) {
|
if (stderr) {
|
||||||
return quitBeforeShowResult
|
return quitBeforeShowResult
|
||||||
? alert(stderr)
|
? alert(stderr)
|
||||||
|
@ -10,21 +10,21 @@ let escapeItem = item => {
|
|||||||
|
|
||||||
let handlingJsonVar = (jsonVar, name) => {
|
let handlingJsonVar = (jsonVar, name) => {
|
||||||
try {
|
try {
|
||||||
return escapeItem(window.VmEval(jsonVar.slice(2, -2), {
|
return escapeItem(window.evalCodeInSandbox(jsonVar.slice(2, -2), {
|
||||||
[name]: quickcommand.enterData.payload
|
[name]: quickcommand.enterData.payload
|
||||||
}))
|
}))
|
||||||
} catch {
|
} catch (e) {
|
||||||
return ""
|
return utools.showNotification(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let handlingJsExpression = js => {
|
let handlingJsExpression = js => {
|
||||||
try {
|
try {
|
||||||
return window.VmEval(js.slice(5, -2), {
|
return window.evalCodeInSandbox(js.slice(5, -2), {
|
||||||
utools: window.getuToolsLite(),
|
utools: window.getuToolsLite(),
|
||||||
})
|
})
|
||||||
} catch {
|
} catch (e) {
|
||||||
return ""
|
return utools.showNotification(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,7 +131,7 @@ const specialVars = {
|
|||||||
name: "js",
|
name: "js",
|
||||||
label: "{{js:}}",
|
label: "{{js:}}",
|
||||||
desc: "获取js表达式的值,如{{js:utools.isMacOs()}}",
|
desc: "获取js表达式的值,如{{js:utools.isMacOs()}}",
|
||||||
tooltip: "注意,必须为表达式而非语句,类似Vue的文本插值。不支持异步/Node",
|
tooltip: "注意,必须为表达式而非语句,类似Vue的文本插值",
|
||||||
type: "command",
|
type: "command",
|
||||||
match: /{{js:(.*?)}}/mg,
|
match: /{{js:(.*?)}}/mg,
|
||||||
repl: js => handlingJsExpression(js)
|
repl: js => handlingJsExpression(js)
|
||||||
|
13
src/plugins/monaco/types/common.d.ts
vendored
13
src/plugins/monaco/types/common.d.ts
vendored
@ -88,16 +88,3 @@ declare var console: {
|
|||||||
log(message?: any): void,
|
log(message?: any): void,
|
||||||
error(message?: any): void
|
error(message?: any): void
|
||||||
}
|
}
|
||||||
|
|
||||||
// process
|
|
||||||
declare var process: {
|
|
||||||
argv: any[];
|
|
||||||
title: string;
|
|
||||||
version: string;
|
|
||||||
versions: object;
|
|
||||||
arch: string;
|
|
||||||
platform: string;
|
|
||||||
env: object;
|
|
||||||
pid: number;
|
|
||||||
features: object
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user