Oi,
Estou tentando descobrir por que os módulos internos são proxy do host e não são necessários no vm.
esta é a minha configuração atualmente:
const vm = new NodeVM({
require: {
external: true,
context: 'sandbox',
builtin: ['*'],
},
});
vm.run(...);
dentro da VM eu exijo um módulo externo ( axios
se isso importa) e na cadeia de dependências requer outro módulo ( follow-redirects
) que faz isso (mais ou menos):
var Writable = require('stream').Writable;
function RedirectableRequest(options, responseCallback) {
// .....
}
RedirectableRequest.prototype = Object.create(Writable.prototype);
RedirectableRequest.prototype._performRequest = function () { // <-------- this line breaks
// ..........
}
executar este código dentro do vm lança: TypeError: 'set' on proxy: trap retornou false para a propriedade '_performRequest'.
O objeto de fluxo está sendo proxy para o vm.
executar este código quando stream
está sendo realmente necessário dentro da vm (removendo a instrução if aqui: https://github.com/patriksimek/vm2/blob/master/lib/sandbox.js#L133) é trabalhando.
executando o nó 6.10.3 no osx.
Obrigado
relacionado a #127
Eu fui em frente e mudei a instrução if para:
if( vm.options.require.context === 'sandbox' && modulename !== 'async_hooks' ){
Descobri que no nó 8.x tive problemas com async_hooks
Também encontrei uma solução alternativa (uma que acho que se encaixa melhor no paradigma).
Basicamente o que eu encontrei foi que o código contextualizado estava tentando escrever em um protótipo de um objeto que ele criou em seu contexto, mas que estendeu um objeto trazido de outro contexto.
De acordo com a documentação do manipulador de proxy set, se a propriedade não existir no objeto que você está tentando definir, o manipulador de conjunto de protótipo será chamado.
Assim;
Objeto
protótipo
a <-Definindo isso (que na verdade não existe no protótipo)
__proto__ (proxy)
set: (){} <- Na verdade chama isso
E quando o manipulador set for chamado, o argumento receiver será definido para o objeto original que estávamos tentando definir. Minha solução foi essa:
--- 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;
+
+ },
Qual é o estado? Projeto morto?
Este problema foi marcado automaticamente como obsoleto porque não teve atividade recente. Será fechado se não ocorrer mais nenhuma atividade. Obrigado por suas contribuições.
Comentários muito úteis
Também encontrei uma solução alternativa (uma que acho que se encaixa melhor no paradigma).
Basicamente o que eu encontrei foi que o código contextualizado estava tentando escrever em um protótipo de um objeto que ele criou em seu contexto, mas que estendeu um objeto trazido de outro contexto.
De acordo com a documentação do manipulador de proxy set, se a propriedade não existir no objeto que você está tentando definir, o manipulador de conjunto de protótipo será chamado.
Assim;
Objeto
protótipo
a <-Definindo isso (que na verdade não existe no protótipo)
__proto__ (proxy)
set: (){} <- Na verdade chama isso
E quando o manipulador set for chamado, o argumento receiver será definido para o objeto original que estávamos tentando definir. Minha solução foi essa: