适用于Linux的PHP扩展:需要进行现实检查!

时间:2010-09-28 05:54:39

标签: php c memory-management php-extension

好的,我已经编写了我的第一个功能PHP扩展。它有效,但它只是一个概念验证。现在我正在写另一个实际上做老板想要的东西。

我想知道的是,你们所有的PHP负责人都知道这段代码是否有意义。我是否已经很好地掌握了emalloc之类的东西,或者那里的东西是否会在以后扭转并尝试咬掉我的手?

以下是其中一个功能的代码。它返回一个字符串的base64,该字符串也是Blowfish加密的。调用该函数时,它会提供两个字符串,即要加密和编码的文本,以及加密阶段的密钥。它不使用PHP自己的base64函数,因为在这一点上,我不知道如何链接它们。并且由于同样的原因,它没有使用PHP自己的mcrypt函数。相反,它链接在SSLeay BF_ecb_encrypt函数中。

PHP_FUNCTION(Blowfish_Base64_encode)
{
    char *psData = NULL;
    char *psKey = NULL;
    int argc = ZEND_NUM_ARGS();
    int psData_len;
    int psKey_len;

    char *Buffer = NULL;
    char *pBuffer = NULL;

    char *Encoded = NULL;

    BF_KEY Context;

    int i = 0;

    unsigned char Block[ 8 ];
    unsigned char * pBlock = Block;

    char *plaintext;
    int plaintext_len;
    int cipher_len = 0;

    if (zend_parse_parameters(argc TSRMLS_CC, "ss", &psData, &psData_len, &psKey, &psKey_len) == FAILURE) 
        return;

    Buffer = (char *) emalloc( psData_len * 2 );
    pBuffer = Buffer;

    Encoded = (char *) emalloc( psData_len * 4 );

    BF_set_key( &Context, psKey_len, psKey );

    plaintext = psData;
    plaintext_len = psData_len;

    for (;;)
    {
        if (plaintext_len--)
        {
            Block[ i++ ] = *plaintext++;
            if (i == 8 )
            {
                BF_ecb_encrypt( Block, pBuffer, &Context, BF_ENCRYPT );
                pBuffer += 8;
                cipher_len += 8;
                memset( Block, 0, 8 );
                i = 0;
            }
        } else {
            BF_ecb_encrypt( Block, pBuffer, &Context, BF_ENCRYPT );
            cipher_len += 8;
            break;
        }
    }
    b64_encode( Encoded, Buffer, cipher_len );
    RETURN_STRINGL( Encoded, strlen( Encoded ), 0 );
}

您会注意到,emallocEncoded有两次Buffer次来电。只有Encoded被传递回调用者,因此我担心缓冲区不会被释放。是这样的吗?我应该为Buffer使用malloc / free吗?

如果还有其他明显的错误,我真的很感激。

2 个答案:

答案 0 :(得分:2)

emalloc()为每个请求分配内存,并在运行时结束时自动释放()。

但是,您应该使用

编译PHP
  

- enable-debug --enable-maintainer-zts

它会告诉您是否出现任何问题(如果您使用了e *()函数并且在php.ini中设置了report_memleaks,它可以检测到内存泄漏)。

是的,你应该efree()缓冲区。

答案 1 :(得分:1)

  

您会注意到我有两个电话号码,EncodedBuffer。只有Encoded被传递给调用者,所以我担心Buffer将不会被释放。是这样的吗?我应该使用malloc / free作为Buffer吗?

是的,你应该在返回之前用efree释放它。

尽管PHP有安全网,并且在请求结束时将释放分配有emalloc的内存,但它仍然是泄漏内存的错误,并且取决于您是否会在运行{{1}的调试版本时发出警告}。