Расширение PHP для Linux: нужна проверка реальности! - PullRequest
1 голос
/ 28 сентября 2010

Хорошо, я написал свое первое функциональное расширение PHP. Это сработало, но это было только доказательством концепции. Сейчас я пишу еще один, который на самом деле делает то, что хочет босс.

Что бы я хотел знать от всех вас, PHP-руководителей, это то, имеет ли этот код смысл. Хорошо ли я понимаю такие вещи, как emalloc и тому подобное, или есть вещи, которые потом повернутся и попытаются откусить мне руку?

Ниже приведен код для одной из функций. Возвращает base64 строки, которая также была зашифрована Blowfish. Когда функция вызывается, она поставляется с двумя строками: текстом для шифрования и кодирования и ключом для фазы шифрования. Он не использует собственные функции base64 в PHP, потому что на данный момент я не знаю, как ссылаться на них. И это не использует собственные функции 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 звонка, для Encoded и для Buffer. Только Encoded передается обратно вызывающей стороне, поэтому я обеспокоен тем, что Buffer не будет освобожден. Это тот случай? Должен ли я использовать malloc / free для Buffer?

Если есть какие-либо иные явные ошибки, я бы очень хотел знать.

Ответы [ 2 ]

2 голосов
/ 28 сентября 2010

emalloc () выделяет память для запроса, и она автоматически освобождается () по окончании времени выполнения.

Однако вы должны скомпилировать PHP с

- включить-debug --enable-keeper-zts

Он сообщит вам, если что-то пойдет не так (он может обнаружить утечки памяти, если вы использовали функции e * (), а report_memleaks установленоваш php.ini).

И да, вы должны efree () Buffer.

1 голос
/ 28 сентября 2010

Вы заметите, что у меня есть два вызова emalloc, для Encoded и для Buffer.Только Encoded передается обратно вызывающей стороне, поэтому я обеспокоен тем, что Buffer не будет освобожден.Это тот случай?Должен ли я использовать malloc / free для Buffer?

Да, вы должны освободить его с помощью efree перед возвратом.

Хотя PHP имеет защитную сеть и памятьвыделенный с emalloc будет освобожден в конце запроса, это все еще ошибка для утечки памяти и, в зависимости от того, вы будете предупреждены при запуске отладочной сборки с report_memleaks = On.

...