Привет,
Я пытаюсь понять, почему встроенные модули проксируются с хоста и не требуются в vm.
это моя установка в настоящее время:
const vm = new NodeVM({
require: {
external: true,
context: 'sandbox',
builtin: ['*'],
},
});
vm.run(...);
внутри виртуальной машины мне нужен внешний модуль ( axios
, если это имеет значение), а в цепочке зависимостей требуется другой модуль ( follow-redirects
), который делает это (более или менее):
var Writable = require('stream').Writable;
function RedirectableRequest(options, responseCallback) {
// .....
}
RedirectableRequest.prototype = Object.create(Writable.prototype);
RedirectableRequest.prototype._performRequest = function () { // <-------- this line breaks
// ..........
}
запуск этого кода внутри vm throws: TypeError: 'set' на прокси: ловушка вернула ложность для свойства '_performRequest'.
Объект потока проксируется на виртуальную машину.
запуск этого кода, когда stream
действительно требуется внутри vm (путем удаления оператора if здесь: https://github.com/patriksimek/vm2/blob/master/lib/sandbox.js#L133) работающий.
работающий узел 6.10.3 на osx.
Спасибо
относится к # 127
Я пошел дальше и изменил оператор if на:
if( vm.options.require.context === 'sandbox' && modulename !== 'async_hooks' ){
Я обнаружил, что в узле 8.x я столкнулся с проблемами с async_hooks.
Я также нашел альтернативное решение (которое, по моему мнению, лучше соответствует парадигме).
В основном то, что я обнаружил, было контекстным кодом, пытающимся записать прототип объекта, который он создал в своем контексте, но который расширял объект, полученный из другого контекста.
В соответствии с документацией об обработчике набора прокси, если свойство не существует в объекте, который вы пытаетесь установить, будет вызван обработчик набора прототипов.
Так;
Объект
прототип
a <-Setting this (которого на самом деле нет в прототипе)
__proto__ (прокси)
set: (){} <- На самом деле вызывает это
И когда вызывается обработчик set, аргумент получателя будет установлен на исходный объект, который мы пытались установить. Мое решение было таким:
--- a/node_modules/vm2/lib/contextify.js
+++ b/node_modules/vm2/lib/contextify.js
@@ -17,7 +17,23 @@ const DEBUG = false;
const OPNA = 'Operation not allowed on contextified object.';
const ERROR_CST = Error.captureStackTrace;
const FROZEN_TRAPS = {
- set: (target, key) => false,
+ set: (target, key, value, receiver) => {
+ if( target !== receiver ){
+
+ Object.defineProperty(receiver, key, {
+ value: value,
+ writable: true,
+ enumerable: true,
+ configurable: true
+ })
+
+ return true;
+
+ }
+
+ return false;
+
+ },
Каков статус? Проект умер?
Эта проблема была автоматически помечена как устаревшая, поскольку в последнее время с ней не было никаких действий. Он будет закрыт, если никакой дальнейшей активности не произойдет. Спасибо за ваш вклад.
Самый полезный комментарий
Я также нашел альтернативное решение (которое, по моему мнению, лучше соответствует парадигме).
В основном то, что я обнаружил, было контекстным кодом, пытающимся записать прототип объекта, который он создал в своем контексте, но который расширял объект, полученный из другого контекста.
В соответствии с документацией об обработчике набора прокси, если свойство не существует в объекте, который вы пытаетесь установить, будет вызван обработчик набора прототипов.
Так;
Объект
прототип
a <-Setting this (которого на самом деле нет в прототипе)
__proto__ (прокси)
set: (){} <- На самом деле вызывает это
И когда вызывается обработчик set, аргумент получателя будет установлен на исходный объект, который мы пытались установить. Мое решение было таким: