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() 系统的理解是否有误。

--- 详细信息 --- Pythong 2.7 M2Crypto 0.21.1 OpenSSL 0.9.8q-fips 2010 年 12 月 2 日 FreeBSD 8.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 内部的人来说,这个问题基本上有三种解决方案。第一个是上面发布的补丁。由于我们认为这符合 BIO_gets() 手册页的意图,因此我们选择了这种解决方案。

第二种解决方案是修补 M2Crypto/BIO.py。具体来说,修补实现 BIO.readlines() 的代码以测试来自 m2.bio.gets() 的返回值是否为 None 或 len(buf) == 0,并将两者都视为流结束。

第三种解决方案是简单地避免调用 BIO.readlines(),并限制自己调用 BIO.readline()(注意 - singluar readline vs readlines),并测试 BIO.readline() 的返回值是否为 None 或len(buf) == 0。

第三种解决方案似乎不是一个很好的选择——更像是回避。但是,如果您担心将应用程序部署到可能无法修补 M2Crypto 的环境中,那么这种方法可以保证是最兼容的。

我们已将补丁提交给唱片的开发者 Heikki,但他还没有机会审查我们的建议。在官方以一种或另一种方式回答之前,我想分享我们的想法。

于 2012-02-15T15:14:17.333 回答
0

此问题与Debian Linux中的错误 #717675有关。

它在 Fedora 21 中无法重现,而且我没有找到任何适用于 Fedora 的补丁来修改BIO.py_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 回答