Skip to content

Commit e1f8434

Browse files
author
Mikko Koppanen
committed
Delete the object if exception happens in callback
1 parent eb604a7 commit e1f8434

File tree

1 file changed

+22
-13
lines changed

1 file changed

+22
-13
lines changed

Diff for: php_memcached.c

+22-13
Original file line numberDiff line numberDiff line change
@@ -300,13 +300,13 @@ static int php_memc_do_result_callback(zval *memc_obj, zend_fcall_info *fci, zen
300300
static memcached_return php_memc_do_serverlist_callback(const memcached_st *ptr, memcached_server_instance_st instance, void *in_context);
301301
static memcached_return php_memc_do_stats_callback(const memcached_st *ptr, memcached_server_instance_st instance, void *in_context);
302302
static memcached_return php_memc_do_version_callback(const memcached_st *ptr, memcached_server_instance_st instance, void *in_context);
303-
303+
static void php_memc_destroy(struct memc_obj *m_obj, zend_bool persistent TSRMLS_DC);
304304

305305
/****************************************
306306
Method implementations
307307
****************************************/
308308

309-
static void php_memcached_on_new_callback(zval *object, zend_fcall_info *fci, zend_fcall_info_cache *fci_cache, char *persistent_id, int persistent_id_len)
309+
static zend_bool php_memcached_on_new_callback(zval *object, zend_fcall_info *fci, zend_fcall_info_cache *fci_cache, char *persistent_id, int persistent_id_len)
310310
{
311311
zval *retval_ptr, *pid_z;
312312
zval **params[2];
@@ -330,12 +330,14 @@ static void php_memcached_on_new_callback(zval *object, zend_fcall_info *fci, ze
330330

331331
if (zend_call_function(fci, fci_cache TSRMLS_CC) == FAILURE) {
332332
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to invoke 'on_new' callback %s()", Z_STRVAL_P(fci->function_name));
333+
return 0;
333334
}
334335
zval_ptr_dtor(&pid_z);
335336

336337
if (retval_ptr) {
337338
zval_ptr_dtor(&retval_ptr);
338339
}
340+
return 1;
339341
}
340342

341343
/* {{{ Memcached::__construct([string persistent_id[, callback on_new]]))
@@ -374,7 +376,7 @@ static PHP_METHOD(Memcached, __construct)
374376

375377
if (plist_key == NULL) {
376378
efree(plist_key);
377-
php_error_docref(NULL TSRMLS_CC, E_ERROR, "out of memory: cannot allocate peristent list handler");
379+
php_error_docref(NULL TSRMLS_CC, E_ERROR, "out of memory: cannot allocate persistent list handler");
378380
/* not reached */
379381
}
380382

@@ -383,8 +385,11 @@ static PHP_METHOD(Memcached, __construct)
383385
m_obj = (struct memc_obj *) le->ptr;
384386
}
385387
}
388+
i_obj->obj = m_obj;
386389
}
387-
390+
391+
i_obj->is_persistent = is_persistent;
392+
388393
if (!m_obj) {
389394
m_obj = pecalloc(1, sizeof(*m_obj), is_persistent);
390395
if (m_obj == NULL) {
@@ -403,8 +408,21 @@ static PHP_METHOD(Memcached, __construct)
403408
m_obj->serializer = MEMC_G(serializer);
404409
m_obj->compression_type = MEMC_G(compression_type_real);
405410
m_obj->compression = 1;
411+
412+
i_obj->obj = m_obj;
406413
i_obj->is_pristine = 1;
407414

415+
if (ZEND_NUM_ARGS() >= 2) {
416+
if (!php_memcached_on_new_callback(object, &fci, &fci_cache, persistent_id, persistent_id_len) || EG(exception)) {
417+
/* error calling or exception thrown from callback */
418+
if (plist_key != NULL) {
419+
efree(plist_key);
420+
}
421+
php_memc_destroy(m_obj, is_persistent TSRMLS_CC);
422+
return;
423+
}
424+
}
425+
408426
if (is_persistent) {
409427
zend_rsrc_list_entry le;
410428

@@ -417,19 +435,10 @@ static PHP_METHOD(Memcached, __construct)
417435
/* not reached */
418436
}
419437
}
420-
invoke_callback = 1;
421438
}
422-
423-
i_obj->is_persistent = is_persistent;
424-
i_obj->obj = m_obj;
425-
426439
if (plist_key != NULL) {
427440
efree(plist_key);
428441
}
429-
430-
if (ZEND_NUM_ARGS() >= 2 && invoke_callback) {
431-
php_memcached_on_new_callback(object, &fci, &fci_cache, persistent_id, persistent_id_len);
432-
}
433442
}
434443
/* }}} */
435444

0 commit comments

Comments
 (0)