7

ライブラリをrequire/loadするRubyコード内からライブラリのソースコードにアクセスする方法はいくつかあります。これらの方法の中には、ライブラリ ファイルを直接読み取って解析するものがあります。また、ソースに関する情報を提供する組み込みメソッド (抽象構文ツリーなど) を介してソースにアクセスするものもあります。(以前の方法のように) ファイルのコンテンツを直接読み取ることができない状況では、ソースにアクセスする唯一の方法は、情報を提供する組み込みメソッドにアクセスすることです。これらのメソッドを別のことを行うように再定義すると、ソース コードへのアクセスが完全に失われます。メソッドを別のものに再定義すると、外部ファイルのライブラリのソース コードへのアクセスが完全に失われる最小のメソッド セットは何ですか?


質問を言い換えると

仮定する:

  • ファイル A に任意の Ruby コードを記述できるユーザーがいます。
  • 私が作成した静的 Ruby ファイル B があります。これは、ファイル A をロードし、A で定義されたメイン ルーチンを呼び出し、ユーザーが A で使用できるいくつかのクラス/メソッドも定義します。
  • ユーザーには、B に対する +r (読み取り) または +w (書き込み) 権限がありません。

ユーザーがファイル B に記述されたソースに (ユーザーがファイル A に記述できるコードを介して) アクセスできないようにするために、ファイル B にそのように記述して、どの (標準 Ruby) メソッドを再定義 (無効化) または削除する必要がありますか? ) ファイル B を実行すると?

sorcerer、pry など、アクセスできるメソッドのソース コードを抽出できるライブラリがいくつかあります。これらのライブラリがソースコードにアクセスできるようにするために依存する、プレーンな Ruby 内のいくつかのプリミティブ コマンドが必要です。この種のことを可能にする方法は何ですか?

完全な答えがわからないが、特定のライブラリがメソッドのソースを抽出する方法を知っている場合でも、それは役に立ちます。

4

2 に答える 2

6

TL;DR : Ruby のみのソリューションでは しか使用できないためsource_location、これを再定義して のようなものを返すだけ['/some/empty/file', 1]です。インタープリターへのハックは を使用しませんが、ブロック/ホワイトリストと友人source_locationによって C 拡張機能の使用を防ぐことができます。require


たとえば、Ruby スクリプトを実行できるようにするには、スクリプトを読み取れる必要があります...

しかし、質問に戻ります。Sourcify は、 Proc と Method という名前の小さなメソッド以外に神秘的なメソッドを使用しないことを知っていますsource_location。これにより、メソッド/プロシージャが定義されているファイル名と行番号が得られます。このアプローチは非常に壊れやすく、ある種のパーサーを作成する必要があり、正当な状況でしか機能しない場合があることを経験から知っています。なので、source_locationB で再定義して次のようなものを返して/dev/null, line 0、Sourcify が Ruby ソースではない例外をスローするようにすると、Sourcify は既にアウトです。

Pry の情報源によると、Pry も同じsource_locationアプローチを使用しているようで、一石二鳥です。

現在、これらすべてのライブラリには別のオプションがあります。それは、C にドロップダウンし、インタープリターをハックしてソース コードを記録することです。これはほぼ完璧です。しかし、非常に簡単な方法で危険を回避することはできます。誰かが Pry のメソッド ソースのすべてのコードを A に含めることができます。しかし、C ライブラリを必要とせずにインライン C/C 拡張機能を含めることはできません。したがって、解決策は明らかです。requireandrequire_relativeを再定義しloadて、動作しないようにするか、特定のライブラリのみを許可します。このようにして、C ハッキングを防ぐことができます。

MRI では、これを行う以外source_locationに (Ruby コードから) 方法はありません。では、どうぞ!

編集:@banisterによると、MRI 2.0+から、binding_of_callerソースの場所を置き換えることができるメソッドが組み込まれています。これもヌケる。;)

警告: Ruby はこれに適した言語ではありません。それらをメタプログラミングできる場合、別のプロセスにいる場合を除き、おそらくメタプログラミングできます。

于 2013-05-10T01:04:31.747 に答える