various memory optimizations

This commit is contained in:
Thilo Raufeisen 2005-11-10 20:24:27 +00:00
parent 95ed1d656f
commit 1bf61c6980
3 changed files with 127 additions and 48 deletions

96
gnupg.c
View file

@ -67,7 +67,7 @@ static zend_object_handlers gnupg_object_handlers;
}else{ \
php_error_docref(NULL TSRMLS_CC, E_WARNING, (char*)error); \
} \
RETURN_FALSE;
RETVAL_FALSE;
/* }}} */
/* {{{ free encryptkeys */
@ -554,6 +554,7 @@ PHP_FUNCTION(gnupg_keyinfo)
}
if((intern->err = gpgme_op_keylist_start(intern->ctx, searchkey, 0)) != GPG_ERR_NO_ERROR){
GNUPG_ERR("could not init keylist");
return;
}
array_init(return_value);
@ -652,6 +653,7 @@ PHP_FUNCTION(gnupg_addsignkey){
}
if((intern->err = gpgme_get_key(intern->ctx, key_id, &gpgme_key, 1)) != GPG_ERR_NO_ERROR){
GNUPG_ERR("get_key failed");
return;
}
if(passphrase){
gpgme_subkey = gpgme_key->subkeys;
@ -664,10 +666,10 @@ PHP_FUNCTION(gnupg_addsignkey){
}
if((intern->err = gpgme_signers_add(intern->ctx, gpgme_key))!=GPG_ERR_NO_ERROR){
GNUPG_ERR("could not add signer");
}else{
RETVAL_TRUE;
}
/* dont need the keyref anymore */
gpgme_key_unref(gpgme_key);
RETURN_TRUE;
}
/* }}} */
@ -695,6 +697,7 @@ PHP_FUNCTION(gnupg_adddecryptkey){
}
if((intern->err = gpgme_get_key(intern->ctx, key_id, &gpgme_key, 1)) != GPG_ERR_NO_ERROR){
GNUPG_ERR("get_key failed");
return;
}
gpgme_subkey = gpgme_key->subkeys;
while(gpgme_subkey){
@ -730,6 +733,7 @@ PHP_FUNCTION(gnupg_addencryptkey){
if((intern->err = gpgme_get_key(intern->ctx, key_id, &gpgme_key, 0)) != GPG_ERR_NO_ERROR){
GNUPG_ERR("get_key failed");
return;
}
intern->encryptkeys = erealloc(intern->encryptkeys, sizeof(intern->encryptkeys) * (intern->encrypt_size + 1));
intern->encryptkeys[intern->encrypt_size] = gpgme_key;
@ -825,19 +829,31 @@ PHP_FUNCTION(gnupg_sign){
gpgme_set_passphrase_cb (intern->ctx, (void*) passphrase_cb, intern);
if((intern->err = gpgme_data_new_from_mem (&in, value, value_len, 0))!=GPG_ERR_NO_ERROR){
GNUPG_ERR("could not create in-data buffer");
return;
}
if((intern->err = gpgme_data_new(&out))!=GPG_ERR_NO_ERROR){
GNUPG_ERR("could not create out-data buffer");
gpgme_data_release(in);
return;
}
if((intern->err = gpgme_op_sign(intern->ctx, in, out, intern->signmode))!=GPG_ERR_NO_ERROR){
GNUPG_ERR("data signing failed");
gpgme_data_release(in);
gpgme_data_release(out);
return;
}
result = gpgme_op_sign_result (intern->ctx);
if(result->invalid_signers){
GNUPG_ERR("invalid signers found");
gpgme_data_release(in);
gpgme_data_release(out);
return;
}
if(!result->signatures){
GNUPG_ERR("no signature in result");
gpgme_data_release(in);
gpgme_data_release(out);
return;
}
userret = gpgme_data_release_and_get_mem(out,&ret_size);
if(ret_size < 1){
@ -879,19 +895,29 @@ PHP_FUNCTION(gnupg_encrypt){
}
if(!intern->encryptkeys){
GNUPG_ERR("no key for encryption set");
return;
}
if((intern->err = gpgme_data_new_from_mem (&in, value, value_len, 0))!=GPG_ERR_NO_ERROR){
GNUPG_ERR("could no create in-data buffer");
return;
}
if((intern->err = gpgme_data_new(&out))!=GPG_ERR_NO_ERROR){
GNUPG_ERR("could not create out-data buffer");
gpgme_data_release(in);
return;
}
if((intern->err = gpgme_op_encrypt(intern->ctx, intern->encryptkeys, GPGME_ENCRYPT_ALWAYS_TRUST, in, out))!=GPG_ERR_NO_ERROR){
GNUPG_ERR("encrypt failed");
gpgme_data_release(in);
gpgme_data_release(out);
return;
}
result = gpgme_op_encrypt_result (intern->ctx);
if (result->invalid_recipients){
GNUPG_ERR("Invalid recipient encountered");
gpgme_data_release(in);
gpgme_data_release(out);
return;
}
userret = gpgme_data_release_and_get_mem(out,&ret_size);
gpgme_data_release (in);
@ -933,29 +959,45 @@ PHP_FUNCTION(gnupg_encryptsign){
if(!intern->encryptkeys){
GNUPG_ERR("no key for encryption set");
return;
}
gpgme_set_passphrase_cb (intern->ctx, (void*) passphrase_cb, intern);
if((intern->err = gpgme_data_new_from_mem (&in, value, value_len, 0))!=GPG_ERR_NO_ERROR){
GNUPG_ERR("could not create in-data buffer");
return;
}
if((intern->err = gpgme_data_new(&out))!=GPG_ERR_NO_ERROR){
GNUPG_ERR("could not create out-data buffer");
gpgme_data_release(in);
return;
}
if((intern->err = gpgme_op_encrypt_sign(intern->ctx, intern->encryptkeys, GPGME_ENCRYPT_ALWAYS_TRUST, in, out))!=GPG_ERR_NO_ERROR){
GNUPG_ERR("encrypt-sign failed");
gpgme_data_release(in);
gpgme_data_release(out);
return;
}
result = gpgme_op_encrypt_result (intern->ctx);
if (result->invalid_recipients){
GNUPG_ERR("Invalid recipient encountered");
gpgme_data_release(in);
gpgme_data_release(out);
return;
}
sign_result = gpgme_op_sign_result (intern->ctx);
if(sign_result->invalid_signers){
GNUPG_ERR("invalid signers found");
gpgme_data_release(in);
gpgme_data_release(out);
return;
}
if(!sign_result->signatures){
GNUPG_ERR("could not find a signature");
gpgme_data_release(in);
gpgme_data_release(out);
return;
}
userret = gpgme_data_release_and_get_mem(out,&ret_size);
@ -1001,9 +1043,12 @@ PHP_FUNCTION(gnupg_verify){
if(Z_STRVAL_P(signature)){
if((intern->err = gpgme_data_new_from_mem (&gpgme_sig, Z_STRVAL_P(signature), Z_STRLEN_P(signature), 0))!=GPG_ERR_NO_ERROR){
GNUPG_ERR("could not create signature-databuffer");
return;
}
if((intern->err = gpgme_data_new (&gpgme_text))!=GPG_ERR_NO_ERROR){
GNUPG_ERR("could not create text-databuffer");
gpgme_data_release(gpgme_sig);
return;
}
}else{
/* no separate signature was passed
@ -1013,23 +1058,31 @@ PHP_FUNCTION(gnupg_verify){
*/
if((intern->err = gpgme_data_new_from_mem (&gpgme_sig, text, text_len, 0))!=GPG_ERR_NO_ERROR){
GNUPG_ERR("could not create signature-databuffer");
return;
}
if((intern->err = gpgme_data_new_from_mem (&gpgme_text, NULL, 0, 0))!=GPG_ERR_NO_ERROR){
GNUPG_ERR("could not create text-databuffer");
gpgme_data_release(gpgme_sig);
gpgme_data_release(gpgme_text);
return;
}
}
if((intern->err = gpgme_op_verify (intern->ctx, gpgme_sig, NULL, gpgme_text))!=GPG_ERR_NO_ERROR){
GNUPG_ERR("verify failed");
gpgme_data_release(gpgme_sig);
gpgme_data_release(gpgme_text);
return;
}
gpgme_result = gpgme_op_verify_result (intern->ctx);
if(!gpgme_result->signatures){
GNUPG_ERR ("no signature found");
}
}else{
gnupg_fetchsignatures (gpgme_result->signatures,sig_arr,return_value);
gpg_plain = gpgme_data_release_and_get_mem(gpgme_text,&gpg_plain_len);
if(plaintext){
ZVAL_STRINGL (plaintext,gpg_plain,gpg_plain_len,1);
}
}
gpgme_data_release (gpgme_sig);
free (gpgme_text);
free (gpg_plain);
@ -1069,13 +1122,21 @@ PHP_FUNCTION(gnupg_decrypt){
}
if((intern->err = gpgme_data_new (&out))!=GPG_ERR_NO_ERROR){
GNUPG_ERR("could not create out-data buffer");
gpgme_data_release(in);
return;
}
if((intern->err = gpgme_op_decrypt (intern->ctx, in, out))!=GPG_ERR_NO_ERROR){
GNUPG_ERR("decrypt failed");
gpgme_data_release(in);
gpgme_data_release(out);
return;
}
result = gpgme_op_decrypt_result (intern->ctx);
if (result->unsupported_algorithm){
GNUPG_ERR("unsupported algorithm");
gpgme_data_release(in);
gpgme_data_release(out);
return;
}
userret = gpgme_data_release_and_get_mem(out,&ret_size);
gpgme_data_release (in);
@ -1125,9 +1186,14 @@ PHP_FUNCTION(gnupg_decryptverify){
}
if((intern->err = gpgme_data_new (&out))!=GPG_ERR_NO_ERROR){
GNUPG_ERR("could not create out-data buffer");
gpgme_data_release(in);
return;
}
if((intern->err = gpgme_op_decrypt_verify (intern->ctx, in, out))!=GPG_ERR_NO_ERROR){
GNUPG_ERR("decrypt-verify failed");
gpgme_data_release(in);
gpgme_data_release(out);
return;
}
userret = gpgme_data_release_and_get_mem(out,&ret_size);
ZVAL_STRINGL (plaintext,userret,ret_size,1);
@ -1135,10 +1201,16 @@ PHP_FUNCTION(gnupg_decryptverify){
decrypt_result = gpgme_op_decrypt_result (intern->ctx);
if (decrypt_result->unsupported_algorithm){
GNUPG_ERR ("unsupported algorithm");
gpgme_data_release(in);
free(out);
return;
}
verify_result = gpgme_op_verify_result (intern->ctx);
if(!verify_result->signatures){
GNUPG_ERR ("no signature found");
gpgme_data_release(in);
free(out);
return;
}
gnupg_fetchsignatures (verify_result->signatures,sig_arr,return_value);
gpgme_data_release (in);
@ -1171,9 +1243,12 @@ PHP_FUNCTION(gnupg_export){
}
if((intern->err = gpgme_data_new (&out))!=GPG_ERR_NO_ERROR){
GNUPG_ERR("could not create data buffer");
return;
}
if((intern->err = gpgme_op_export (intern->ctx, searchkey, 0, out))!=GPG_ERR_NO_ERROR){
GNUPG_ERR("export failed");
gpgme_data_release(out);
return;
}
userret = gpgme_data_release_and_get_mem(out,&ret_size);
RETVAL_STRINGL (userret,ret_size,1);
@ -1209,9 +1284,12 @@ PHP_FUNCTION(gnupg_import){
}
if((intern->err = gpgme_data_new_from_mem (&in, importkey, importkey_len, 0))!=GPG_ERR_NO_ERROR){
GNUPG_ERR("could not create in-data buffer");
return;
}
if((intern->err = gpgme_op_import(intern->ctx,in))!=GPG_ERR_NO_ERROR){
GNUPG_ERR("import failed");
gpgme_data_release(in);
return;
}
gpgme_data_release(in);
result = gpgme_op_import_result (intern->ctx);
@ -1254,12 +1332,15 @@ PHP_FUNCTION(gnupg_deletekey){
if((intern->err = gpgme_get_key(intern->ctx, key, &gpgme_key, 0)) != GPG_ERR_NO_ERROR){
GNUPG_ERR("get_key failed");
return;
}
if((intern->err = gpgme_op_delete(intern->ctx,gpgme_key,allow_secret))!=GPG_ERR_NO_ERROR){
GNUPG_ERR("delete failed");
RETVAL_FALSE;
}else{
RETVAL_TRUE;
}
gpgme_key_unref(gpgme_key);
RETURN_TRUE;
}
/* }}} */
@ -1287,6 +1368,7 @@ PHP_FUNCTION(gnupg_gettrustlist){
}
if((intern->err = gpgme_op_trustlist_start (intern->ctx, pattern, 0))!=GPG_ERR_NO_ERROR){
GNUPG_ERR("could not start trustlist");
return;
}
array_init(return_value);
while (!(intern->err = gpgme_op_trustlist_next (intern->ctx, &item))){
@ -1332,12 +1414,16 @@ PHP_FUNCTION(gnupg_listsignatures){
}
if((intern->err = gpgme_set_keylist_mode(intern->ctx,GPGME_KEYLIST_MODE_SIGS))!=GPG_ERR_NO_ERROR){
GNUPG_ERR("could not switch to sigmode");
return;
}
if((intern->err = gpgme_get_key(intern->ctx, keyid, &gpgme_key, 0)) != GPG_ERR_NO_ERROR){
GNUPG_ERR("get_key failed. given key not unique?");
return;
}
if(!gpgme_key->uids){
GNUPG_ERR("no uids found");
gpgme_key_unref(gpgme_key);
return;
}
array_init(return_value);
gpgme_userid = gpgme_key->uids;

View file

@ -37,31 +37,29 @@ static int le_gnupg_keylistiterator;
static zend_object_handlers gnupg_keylistiterator_object_handlers;
/* {{{ defs */
#define GNUPG_GET_ITERATOR() \
zval *this = getThis(); \
gnupg_keylistiterator_object *intern; \
ze_gnupg_keylistiterator_object *obj = (ze_gnupg_keylistiterator_object*) zend_object_store_get_object(getThis() TSRMLS_CC); \
intern = obj->gnupg_keylistiterator_ptr; \
if(this){ \
intern = (gnupg_keylistiterator_object*) zend_object_store_get_object(getThis() TSRMLS_CC); \
if(!intern){ \
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid or unitialized gnupg iterator object"); \
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid or unitialized gnupg object"); \
RETURN_FALSE; \
} \
}
/* }}} */
/* {{{ free_iterator_storage */
static void gnupg_keylistiterator_object_free_storage(void *object TSRMLS_DC){
ze_gnupg_keylistiterator_object *intern = (ze_gnupg_keylistiterator_object *) object;
static void gnupg_keylistiterator_dtor(gnupg_keylistiterator_object *intern TSRMLS_DC){
if(!intern){
return;
}
if(intern->gnupg_keylistiterator_ptr){
gpgme_op_keylist_end(intern->gnupg_keylistiterator_ptr->ctx);
gpgme_key_release(intern->gnupg_keylistiterator_ptr->gpgkey);
gpgme_release(intern->gnupg_keylistiterator_ptr->ctx);
zval_dtor(&intern->gnupg_keylistiterator_ptr->pattern);
efree(intern->gnupg_keylistiterator_ptr);
}
gpgme_op_keylist_end(intern->ctx);
gpgme_key_release(intern->gpgkey);
gpgme_release(intern->ctx);
/*
zval_dtor(&intern->pattern);
*/
if(intern->zo.properties){
zend_hash_destroy(intern->zo.properties);
FREE_HASHTABLE(intern->zo.properties);
@ -72,25 +70,20 @@ static void gnupg_keylistiterator_object_free_storage(void *object TSRMLS_DC){
/* {{{ keylistiterator_objects_new */
zend_object_value gnupg_keylistiterator_objects_new(zend_class_entry *class_type TSRMLS_DC){
ze_gnupg_keylistiterator_object *intern;
gnupg_keylistiterator_object *intern;
zend_object_value retval;
gnupg_keylistiterator_object *gnupg_keylistiterator_ptr;
gpgme_ctx_t ctx;
intern = emalloc(sizeof(ze_gnupg_keylistiterator_object));
intern = emalloc(sizeof(gnupg_keylistiterator_object));
intern->zo.ce = class_type;
intern->zo.in_get = 0;
intern->zo.in_set = 0;
intern->zo.properties = NULL;
retval.handle = zend_objects_store_put(intern,NULL,(zend_objects_free_object_storage_t) gnupg_keylistiterator_object_free_storage,NULL TSRMLS_CC);
retval.handle = zend_objects_store_put(intern,NULL,(zend_objects_free_object_storage_t) gnupg_keylistiterator_dtor,NULL TSRMLS_CC);
retval.handlers = (zend_object_handlers *) & gnupg_keylistiterator_object_handlers;
gpgme_new(&ctx);
gnupg_keylistiterator_ptr = emalloc(sizeof(gnupg_keylistiterator_object));
gnupg_keylistiterator_ptr->ctx = ctx;
intern->gnupg_keylistiterator_ptr = gnupg_keylistiterator_ptr;
intern->ctx = ctx;
return retval;
}
/* }}} */
@ -141,7 +134,7 @@ PHP_FUNCTION(gnupg_keylistiterator___construct){
intern->pattern = *pattern;
zval_copy_ctor(&intern->pattern);
}else{
convert_to_string(&intern->pattern);
ZVAL_EMPTY_STRING(&intern->pattern);
}
}
PHP_FUNCTION(gnupg_keylistiterator_current){
@ -159,6 +152,10 @@ PHP_FUNCTION(gnupg_keylistiterator_key){
PHP_FUNCTION(gnupg_keylistiterator_next){
GNUPG_GET_ITERATOR();
if(intern->gpgkey){
gpgme_key_release(intern->gpgkey);
}
if(intern->err = gpgme_op_keylist_next(intern->ctx, &intern->gpgkey)){
gpgme_key_release(intern->gpgkey);
intern->gpgkey = NULL;

View file

@ -39,17 +39,13 @@ extern zend_module_entry gnupg_keyiterator_module_entry;
extern int _gnupg_keylistiterator_init(INIT_FUNC_ARGS);
typedef struct _gnupg_keylistiterator_object{
zend_object zo;
gpgme_ctx_t ctx;
gpgme_error_t err;
gpgme_key_t gpgkey;
zval pattern;
} gnupg_keylistiterator_object;
typedef struct _ze_gnupg_keylistiterator_object{
zend_object zo;
gnupg_keylistiterator_object *gnupg_keylistiterator_ptr;
} ze_gnupg_keylistiterator_object;
zend_class_entry *gnupg_keylistiterator_class_entry;
PHP_FUNCTION(gnupg_keylistiterator___construct);