1

さて、私は最初の機能的な PHP 拡張機能を作成しました。それは機能しましたが、概念実証のみでした。今、私は上司が望んでいることを実際に行う別のものを書いています。

私が知りたいのは、そこにいるすべての PHP ヘッズから、このコードが意味をなすかどうかです。などのことをよく把握してemallocいますか、それとも後で好転して手をかみ切ろうとするものはありますか?

以下は、関数の 1 つのコードです。Blowfish で暗号化された文字列の base64 を返します。関数が呼び出されると、暗号化およびエンコードするテキストと暗号化フェーズのキーの 2 つの文字列が渡されます。PHP 独自の base64 関数を使用していないのは、この時点ではそれらへのリンク方法がわからないためです。同じ理由で、PHP 独自の mcrypt 関数を使用していません。代わりに、SSLeayBF_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 );
}

forと forの 2 つのemalloc呼び出しがあることに気付くでしょう。のみが呼び出し元に返されるため、Buffer が解放されないことが懸念されます。そうですか?に malloc/free を使用する必要がありますか?EncodedBufferEncodedBuffer

他に明らかなエラーがある場合は、お知らせいただければ幸いです。

4

2 に答える 2

2

emalloc() はリクエストごとにメモリを割り当て、ランタイムが終了すると自動的に free() されます。

ただし、PHP を次のようにコンパイルする必要があります。

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

report_memleaks問題が発生した場合は通知されます (e*() 関数を使用し、php.ini で設定されている場合は、メモリ リークを検出できます)。

はい、efree() バッファを使用する必要があります。

于 2010-09-28T06:49:29.073 に答える
1

Encodedforと forの 2 つの emalloc 呼び出しがあることに気付くでしょうBuffer。のみEncodedが呼び出し元に返されるため、Buffer解放されないことが懸念されます。そうですか?malloc/freeを使用する必要がありBufferますか?

efreeはい、戻る前にで解放する必要があります。

PHP にはセーフティ ネットがあり、 で割り当てられたメモリemallocはリクエストの最後に解放されますが、それでもメモリ リークはバグであり、場合によっては でデバッグ ビルドを実行すると警告が表示されreport_memleaks = Onます。

于 2010-09-28T11:55:54.970 に答える