簡體   English   中英

`python'出錯:大小與prev_size相比已損壞

[英]Error in `python': corrupted size vs. prev_size

我用c來編寫python擴展。
我使用c程序加密字符串。
我的c程序:

#include <Python.h>

static const char *codes = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

static const unsigned char map[256] = {
        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 253, 255,
        255, 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
        255, 255, 255, 255, 255, 255, 255, 255, 253, 255, 255, 255,
        255, 255, 255, 255, 255, 255, 255,  62, 255, 255, 255,  63,
        52,  53,  54,  55,  56,  57,  58,  59,  60,  61, 255, 255,
        255, 254, 255, 255, 255,   0,   1,   2,   3,   4,   5,   6,
        7,   8,   9,  10,  11,  12,  13,  14,  15,  16,  17,  18,
        19,  20,  21,  22,  23,  24,  25, 255, 255, 255, 255, 255,
        255,  26,  27,  28,  29,  30,  31,  32,  33,  34,  35,  36,
        37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47,  48,
        49,  50,  51, 255, 255, 255, 255, 255, 255, 255, 255, 255,
        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
        255, 255, 255, 255
};

int length(char *str){
    int i = 0;
    while (str[i] != '\0') i++;
    return i;
}

char *str_encrypt(char *in) {
    unsigned long len = (unsigned long)length(in);
    unsigned long index, l_even;
    char *p;
    char *out = (char *) PyMem_Malloc (len * 4 / 3 + 1);
    p = out;
    /* valid output size ? */
    l_even = 3 * (len / 3);
    for (index = 0; index < l_even; index += 3) {
        *p++ = codes[in[0] >> 2];
        *p++ = codes[((in[0] & 3) << 4) + (in[1] >> 4)];
        *p++ = codes[((in[1] & 0xf) << 2) + (in[2] >> 6)];
        *p++ = codes[in[2] & 0x3f];
        in += 3;
    }
    /* Pad it if necessary...  */
    if (index < len) {
        unsigned a = (unsigned)in[0];
        unsigned b = (unsigned)((index+1 < len) ? in[1] : 0);
        unsigned c = 0;
        *p++ = codes[a >> 2];
        *p++ = codes[((a & 3) << 4) + (b >> 4)];
        *p++ = (char)((index+1 < len) ? codes[((b & 0xf) << 2) + (c >> 6)] : '=');
        *p++ = '=';
    }
    /* append a NULL byte */
    *p = '\0';
    return out;
}

static PyObject *wrap_encrypt_str(PyObject *self, PyObject *args) {
    char *input_str;
    if (!PyArg_ParseTuple(args, "s", &input_str)) {
        return NULL;
    }
    char *result = str_encrypt(input_str);
    PyObject *pyObject = Py_BuildValue("s", result);
    PyMem_Free(result);
    return pyObject;
}

/* registration table  */
static PyMethodDef wrap_methods[] ={
        {"encrypt_str", wrap_encrypt_str, METH_VARARGS},       /* method name, C func ptr, always-tuple */
        {NULL, NULL}                   /* end of table marker */
};

/* module initializer */
PyMODINIT_FUNC initencryption(void)                       /* called on first import */
{                                      /* name matters if loaded dynamically */
    (void) Py_InitModule("encryption", wrap_methods);   /* mod name, table ptr */
}

然后我寫了一個名為setup.py的文件。
setup.py中的程序在這里:

from setuptools import setup, Extension
setup(
    name="extest",
    packages=["extest", "extest.math", "extest.test"],
    version="0.0.1",
    zip_safe=False,
    ext_modules=[
        Extension("extest.test.encryption", sources=['extest/test/encryption.c'], extra_compile_args=["-Wno-char-subscripts"])
    ],
    long_description='',
    classifiers=[
        "Environment :: Web Environment",
        "Intended Audience :: Developers",
        "Operating System :: OS Independent",
        'Programming Language :: Python :: 2',
        'Programming Language :: Python :: 2.6',
        'Programming Language :: Python :: 2.7'
    ]
)

我運行python setup.py install並成功安裝擴展。
我在python程序中導入模塊。
像這樣:

from extest.test.encryption import encrypt_str
a = encrypt_str("asdfg")
print a

運行成功。
但當我用a = encrypt_str("/static/hello.js")替換a = encrypt_str("asdfg")時,我收到錯誤,程序崩潰了! 錯誤信息在這里:

*** Error in `python': corrupted size vs. prev_size: 0x0000000000aaca00 ***

是什么原因? 怎么解決?

您沒有MALLOC為值足夠的內存out ,我修改這行代碼char *out = (char *) PyMem_Malloc (len * 4 / 3 + 1); to char *out = (char *) PyMem_Malloc (len * 2); 然后重建這個程序。 我看到問題解決了。

你是通過迭代in以3個字節的塊,寫4個字節來out每個塊。 然后,最后,你用4個字節填充(如果in不是3的倍數),最后,你附加一個空字節。

所以你需要分配4 * ((len + 2) / 3) + 1個字節。

為了驗證這是正確的,我們可以看一些小例子:如果len為0,則只需要1個字節用於null。 如果len是1或2,則需要4個字節的填充,加上null。 如果len為3,則單個塊需要4個字節,加上null。 如果len為4,則單個塊需要4個字節,加上4個字節的填充,加上null。 等等。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM