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

发布于 2024-09-24 20:44:48 字数 1984 浏览 4 评论 0原文

好的,我已经编写了第一个 PHP 函数扩展。它有效,但只是一个概念验证。现在我正在写另一篇文章,它实际上符合老板的要求。

我想从所有 PHP 专家那里知道这段代码是否有意义。我是否已经很好地掌握了诸如 emalloc 之类的东西,或者是否有一些东西稍后会扭转并试图咬掉我的手?

以下是其中一项功能的代码。它返回一个经过 Blowfish 加密的字符串的 base64。调用该函数时,会为其提供两个字符串:要加密和编码的文本以及加密阶段的密钥。它没有使用 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 );
}

您会注意到我有两个 emalloc 调用,分别针对 EncodedBuffer。只有 Encoded 被传递回调用者,所以我担心 Buffer 不会被释放。是这样吗?我应该使用 malloc/free 作为缓冲区吗?

如果还有任何其他明显的错误,我真的很高兴知道。

Okay, I've written my first functional PHP extension. It worked but it was a proof-of-concept only. Now I'm writing another one which actually does what the boss wants.

What I'd like to know, from all you PHP-heads out there, is whether this code makes sense. Have I got a good grasp of things like emalloc and the like, or is there stuff there that's going to turn around later and try to bite my hand off?

Below is the code for one of the functions. It returns a base64 of a string that has also been Blowfish encrypted. When the function is called, it is supplied with two strings, the text to encrypt and encode, and the key for the encryption phase. It's not using PHP's own base64 functions because, at this point, I don't know how to link to them. And it's not using PHP's own mcrypt functions for the same reason. Instead, it links in the SSLeay BF_ecb_encrypt functions.

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 );
}

You'll notice that I have two emalloc calls, for Encoded and for Buffer. Only Encoded is passed back to the caller, so I'm concerned that Buffer won't be freed. Is that the case? Should I use malloc/free for Buffer?

If there are any other glaring errors, I'd really appreciate knowing.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

你丑哭了我 2024-10-01 20:44:48

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

但是,您应该使用以下命令编译 PHP

--enable-debug --enable-maintainer-zts

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

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

emalloc() allocates memory per request, and it's free()'d automatically when the runtime ends.

You should, however, compile PHP with

--enable-debug --enable-maintainer-zts

It will tell you if anything goes wrong (it can detect memory leaks if you've used the e*() functions and report_memleaks is set in your php.ini).

And yes, you should efree() Buffer.

爱冒险 2024-10-01 20:44:48

您会注意到我有两个 emalloc 调用,分别针对 EncodedBuffer。只有 Encoded 会传递回调用者,因此我担心 Buffer 不会被释放。是这样吗?我应该对 Buffer 使用 malloc/free 吗?

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

尽管 PHP 有安全网,并且使用 emalloc 分配的内存将在请求结束时释放,但泄漏内存仍然是一个错误,并且如果使用 report_memleaks 运行调试构建,则会发出警告= 开

You'll notice that I have two emalloc calls, for Encoded and for Buffer. Only Encoded is passed back to the caller, so I'm concerned that Buffer won't be freed. Is that the case? Should I use malloc/free for Buffer?

Yes, you should free it with efree before returning.

Although PHP has safety net and memory allocated with emalloc will be freed at the end of the request, it's still a bug to leak memory and, depending you will warned if running a debug build with report_memleaks = On.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文