0

現在、C ++のopensslベースのプロジェクトをM2Cryptoを使用してpythonに変換しているところですが、M2CryptoのBIOルーチンを使用するとやや珍しい問題が発生しました。具体的には、BIO.readlines()の呼び出しは、ファイルオブジェクトで永久にハングします。

これが私たちが試したものの簡単なサンプルです:

f = open('test.txt','w')
f.write('hello world\n')
f.close()

import M2Crypto.BIO
bio = M2Crypto.BIO.openfile('test.txt','r')
lines = bio.readlines()
# the above call hangs forever

OpenSSLのインストールにひどい問題がないことを確認するために、作成したばかりのtest.txtファイルを読み取るための小さなテストプログラムを作成します。

#include <openssl/bio.h>
#include <openssl/err.h>
int main() {
    const int maxrd = 4096;
    char line[maxrd];
    int rd;
    BIO* bio = BIO_new_file("test.txt","r");
    while((rd = BIO_gets(bio, line, maxrd)) > 0) {
        printf("%s",line);
        }
    if (rd == -1) {
        printf("BIO error %ld\n", ERR_get_error());
        }
    }

問題ない。

私たちはM2Crypto-0.21.1/SWIG / _bio.iラッパーファイルを調査しており、問題の原因がわかっている可能性があると考えています。行109は、BIO_gets()からの戻り値をテストします。

if (r < 0) {
    // return Py_None
    }

しかし、BIO_gets()のマニュアルページは、ストリームの終わりを示すために0または-1のいずれかを返す可能性があることを示唆しています。

私はそれがすべきだと信じています

if (r < 1) {
    // return Py_None
    }

しかし、他の人が遭遇したかどうか、またはBIO_gets()システムの理解に誤りがないかどうかを確認したかったのです。

---詳細---Pythong2.7 M2Crypto 0.21.1 OpenSSL0.9.8q-fips2010年12月2日FreeBSD8.2-RELEASE-p4

4

2 に答える 2

0

将来、他の人がこれに遭遇した場合に備えて、パッチを共有したいと思いました。

--- M2Crypto-0.21.1.orig/SWIG/_bio.i  2011-01-15 14:10:06.000000000 -0500
+++ M2Crypto-0.21.1/SWIG/_bio.i   2012-02-14 11:34:15.000000000 -0500
@@ -106,7 +106,7 @@
     Py_BEGIN_ALLOW_THREADS
     r = BIO_gets(bio, buf, num);
     Py_END_ALLOW_THREADS
-    if (r < 0) {
+    if (r < 1) {
         PyMem_Free(buf);
         if (ERR_peek_error()) {
             PyErr_SetString(_bio_err, ERR_reason_error_string(ERR_get_error()));

注:M2Cryptoの内部に精通している人にとって、この問題には基本的に3つの解決策がありました。1つ目は上記のパッチです。これはBIO_gets()のマニュアルページの意図と一致すると考えられるため、これが私たちが選択したソリューションです。

2番目の解決策は、M2Crypto/BIO.pyにパッチを適用することでした。具体的には、BIO.readlines()を実装するコードにパッチを適用して、m2.bio.gets()からの戻り値をNoneまたはlen(buf)== 0のいずれかでテストし、両方をストリームの終わりとして扱います。

3番目の解決策は、BIO.readlines()の呼び出しを避け、BIO.readline()の呼び出しに制限し(注--singluar readlineとreadlines)、BIO.readline()からの戻り値をNoneまたはlen(buf)==0。

3番目の解決策は、選択肢の多くではないように思われるかもしれません-回避のようです。ただし、M2Cryptoにパッチが適用されていない可能性のある環境にアプリケーションをデプロイすることを懸念している場合は、このアプローチが最も互換性があることが保証されます。

レコードHeikkiの開発者にパッチを提出しましたが、彼はまだ私たちの提案をレビューする機会がありませんでした。いずれかの公式の答えが出るまで、私は私たちの考えを共有したいと思いました。

于 2012-02-15T15:14:17.333 に答える
0

この問題は、Debian Linuxのバグ#717675に関連しています。

BIO.pyFedora 21では再現できず、またはを変更するFedoraのパッチは見つかりませんでした_bio.i

Debian用に投稿されたパッチは次のとおりです。

--- /usr/lib64/python2.7/site-packages/M2Crypto/BIO.py  2011-01-15 20:10:05.000000000 +0100
+++ BIO.py  2015-05-20 09:24:46.600582999 +0200
@@ -73,6 +73,8 @@
             buf=m2.bio_gets(self.bio, 4096)
             if buf is None:
                 break
+       if len(buf)==0:
+       break
             lines.append(buf)
         return lines
于 2015-05-20T13:33:48.150 に答える