Vm2: Есть ли причина, по которой большинство встроенных модулей проксируются, а не требуются в песочнице?

Созданный на 17 окт. 2017  ·  5Комментарии  ·  Источник: patriksimek/vm2

Привет,
Я пытаюсь понять, почему встроенные модули проксируются с хоста и не требуются в 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.

Спасибо

Самый полезный комментарий

Я также нашел альтернативное решение (которое, по моему мнению, лучше соответствует парадигме).

В основном то, что я обнаружил, было контекстным кодом, пытающимся записать прототип объекта, который он создал в своем контексте, но который расширял объект, полученный из другого контекста.

В соответствии с документацией об обработчике набора прокси, если свойство не существует в объекте, который вы пытаетесь установить, будет вызван обработчик набора прототипов.

Так;
Объект
прототип
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;
+
+   },

Все 5 Комментарий

относится к # 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;
+
+   },

Каков статус? Проект умер?

Эта проблема была автоматически помечена как устаревшая, поскольку в последнее время с ней не было никаких действий. Он будет закрыт, если никакой дальнейшей активности не произойдет. Спасибо за ваш вклад.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги

Смежные вопросы

unxcepted picture unxcepted  ·  11Комментарии

ghost picture ghost  ·  23Комментарии

seanc picture seanc  ·  3Комментарии

KonradLinkowski picture KonradLinkowski  ·  10Комментарии

patriksimek picture patriksimek  ·  15Комментарии