0

前の質問で、repl コンテキストから不要なグローバル変数を削除する方法を見つけました。ただし、 repl は、を使用せずrequireにすべての内部ノードモジュールに自動的にアクセスできることがわかりました。これを無効にする方法がわかりません。repl自体でモジュール変数をオーバーライドしようとしましたが、機能しません。

> fs = "テスト";
> fs

まだfs元の値が表示されます。私はパブリック repl を公開しようとしていますが、サーバー全体へのアクセスを許可しているため、これは非常に残念です。

何か案は?

4

1 に答える 1

2

あなたが言ったように、REPL はコアモジュールにアクセスできます。

(ただし、確認後、ノード0.10.20でそれらをオーバーライドできるため、解決策があるはずです)

> fs
> { Stats: [Function], …
> fs = 'hello';
> fs
'hello'

より良い方法はrepl._builtinLibs、repl インスタンスを作成する前にオーバーライドすることです。

var repl = require('repl');
repl._builtinLibs = [];
repl.start('> ');

.saveまた、や などのコマンドを公開したくない場合は、 repl コマンドをホワイトリストに登録するのは簡単です.load

var allowedReplCmds = ['.break', '.clear', '.help'];

var newRepl = repl.start('> ');
for (var key in newRepl.commands)
    if (!allowedReplCmds.contains(key))
        delete replInstance.commands[key];

注: 通常、配列にはcontainsメソッドがないため、追加しました。

Array.prototype.contains = function(v) {
    for(var i = 0; i < this.length; i++) {
        if(this[i] === v) return true;
    }
    return false;
};

repl インスタンスのグローバル スコープから変数を削除する場合は、この質問を参照してください。


REPL を一般に公開することは非常に危険であることに注意してください。

サーバー全体を簡単にクラッシュさせることができます

> setTimeout(function () { throw 'bye bye!'; }, 0);

非同期コールバックで発生するエラーは、REPL によって捕捉されず、node.js インスタンスをダウンさせます。

サーバーをブロックできます

> while(true) {};

最善の策は、child_process、readline、および vm を使用して別のプロセスで独自の REPL をコーディングすることです。出発点は次のとおりです。

マスター:

// master.js
var fork = require('child_process').fork;

// functions exposed to the repl
var replApi = {
  hello: function () {
    return 'world!';
  },

  unknown: function () {
    return 'unknown';
  }
};

function forkRepl() {
  var repl = fork('./child_repl');

  repl.on('message', function (command) {
    var fun = replApi[command] || replApi.unknown;
     repl.send(fun());
  });

  // restart the repl if it dies
  repl.on('exit', forkRepl);
}

forkRepl();

およびreplの別のプロセス:

// child_repl.js
var readline = require('readline'),
    vm = require('vm');

var context = vm.createContext({
  hello: function () {
    process.send('hello');
  }
});

var rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

rl.on('line', function (line) {
  vm.runInContext(line, context, 'repl.vm');
});

process.on('message', function (message) {
  console.log('master:', message);
});

rl.prompt();
于 2013-10-16T09:42:18.827 に答える