Skip to content

Commit

Permalink
Merge pull request #1984 from sjinks/issue-1983
Browse files Browse the repository at this point in the history
Fix #1983
  • Loading branch information
Phalcon committed Feb 7, 2014
2 parents c614d87 + c12d4e6 commit 7259ca2
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 22 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
(#801, #802, #810, #825, #827, #838, #849, #942, #968, #1001, #1093, #1169, #1214, #1223, #1224, #1375, #1430, #1787, #1794, #1828)
- Fixed various memory leaks (#469, #860, #910, #914, #916, #1031, #1067, #1249, #1273, #1291, #1309, #1345, #1455, #1470, #1700)
- Fixed memory access violations / segmentation faults / etc (#469, #849, #851, #852, #858, #860, #861, #895, #911, #918, #927, #928, #1000, #1077, #1112, #1113, #1131, #1149, #1173,
#1272, #1284, #1302, #1340, #1343, #1368, #1369, #1371, #1376, #1379, #1392, #1451, #1466, #1485, #1494, #1501, #1504, #1509, #1567, #1607)
#1272, #1284, #1302, #1340, #1343, #1368, #1369, #1371, #1376, #1379, #1392, #1451, #1466, #1485, #1494, #1501, #1504, #1509, #1567, #1607, #1983)
- Fixed PHP notices, warnings and other incompatibilities (#894, #1222, #1315, #1413, #1427, #1428, #1529)
- Fixed inheritance chain for Phalcon\Forms\Exception, Phalcon\Loader\Exception, Phalcon\Http\Request\Exception (#1770)
- Major source code optimizations (#1785)
Expand Down
44 changes: 27 additions & 17 deletions ext/di/injectable.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@
#include "kernel/array.h"
#include "kernel/operators.h"

#include "internal/arginfo.h"
#include "interned-strings.h"

/**
* Phalcon\DI\Injectable
*
Expand All @@ -52,7 +55,7 @@ static const zend_function_entry phalcon_di_injectable_method_entry[] = {
PHP_ME(Phalcon_DI_Injectable, getDI, arginfo_phalcon_di_injectionawareinterface_getdi, ZEND_ACC_PUBLIC)
PHP_ME(Phalcon_DI_Injectable, setEventsManager, arginfo_phalcon_events_eventsawareinterface_seteventsmanager, ZEND_ACC_PUBLIC)
PHP_ME(Phalcon_DI_Injectable, getEventsManager, arginfo_phalcon_events_eventsawareinterface_geteventsmanager, ZEND_ACC_PUBLIC)
PHP_ME(Phalcon_DI_Injectable, __get, arginfo_phalcon_di_injectable___get, ZEND_ACC_PUBLIC)
PHP_ME(Phalcon_DI_Injectable, __get, arginfo___get, ZEND_ACC_PUBLIC)
PHP_FE_END
};

Expand Down Expand Up @@ -140,12 +143,13 @@ PHP_METHOD(Phalcon_DI_Injectable, getEventsManager){
*/
PHP_METHOD(Phalcon_DI_Injectable, __get){

zval *property_name, *dependency_injector = NULL;
zval *has_service, *service = NULL, *class_name, *arguments;
zval **property_name, *dependency_injector = NULL;
zval *has_service, *service = NULL, *class_name, *arguments, *result = NULL;

PHALCON_MM_GROW();
phalcon_fetch_params_ex(1, 0, &property_name);
PHALCON_ENSURE_IS_STRING(property_name);

phalcon_fetch_params(1, 1, 0, &property_name);
PHALCON_MM_GROW();

PHALCON_OBS_VAR(dependency_injector);
phalcon_read_property_this(&dependency_injector, this_ptr, SL("_dependencyInjector"), PH_NOISY_CC);
Expand All @@ -164,40 +168,46 @@ PHP_METHOD(Phalcon_DI_Injectable, __get){
* Fallback to the PHP userland if the cache is not available
*/
PHALCON_INIT_VAR(has_service);
phalcon_call_method_p1(has_service, dependency_injector, "has", property_name);
phalcon_call_method_p1(has_service, dependency_injector, "has", *property_name);
if (zend_is_true(has_service)) {
phalcon_return_call_method_p1(dependency_injector, "getshared", property_name);
phalcon_update_property_zval_zval(this_ptr, property_name, (return_value_ptr ? *return_value_ptr : return_value) TSRMLS_CC);
phalcon_call_method_p1_ex(result, &result, dependency_injector, "getshared", *property_name);
phalcon_update_property_zval_zval(this_ptr, *property_name, result TSRMLS_CC);
RETVAL_ZVAL(result, 1, 1);
RETURN_MM();
}

if (PHALCON_IS_STRING(property_name, "di")) {
phalcon_update_property_this(this_ptr, SL("di"), dependency_injector TSRMLS_CC);
assert(Z_TYPE_PP(property_name) == IS_STRING);

if (Z_STRLEN_PP(property_name) == sizeof("di")-1 && !memcmp(Z_STRVAL_PP(property_name), "di", sizeof("di")-1)) {
zend_update_property(phalcon_di_injectable_ce, getThis(), SL("di"), dependency_injector TSRMLS_CC);
RETURN_CCTOR(dependency_injector);
}

/**
* Accessing the persistent property will create a session bag in any class
*/
if (PHALCON_IS_STRING(property_name, "persistent")) {
PHALCON_INIT_VAR(class_name);
phalcon_get_class(class_name, this_ptr, 0 TSRMLS_CC);
if (Z_STRLEN_PP(property_name) == sizeof("persistent")-1 && !memcmp(Z_STRVAL_PP(property_name), "persistent", sizeof("persistent")-1)) {
const char *cn = Z_OBJCE_P(getThis())->name;

MAKE_STD_ZVAL(class_name);
PHALCON_ZVAL_MAYBE_INTERNED_STRING(class_name, cn);

PHALCON_INIT_VAR(arguments);
array_init_size(arguments, 1);
phalcon_array_append(&arguments, class_name, 0);
add_next_index_zval(arguments, class_name);

PHALCON_INIT_NVAR(service);
ZVAL_STRING(service, "sessionBag", 1);

phalcon_return_call_method_p2(dependency_injector, "get", service, arguments);
zend_update_property(phalcon_di_injectable_ce, getThis(), SL("persistent"), (return_value_ptr ? *return_value_ptr : return_value) TSRMLS_CC);
phalcon_call_method_p2_ex(result, &result, dependency_injector, "get", service, arguments);
zend_update_property(phalcon_di_injectable_ce, getThis(), SL("persistent"), result TSRMLS_CC);
RETVAL_ZVAL(result, 1, 1);
RETURN_MM();
}

/**
* A notice is shown if the property is not defined and isn't a valid service
*/
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Access to undefined property %s", Z_STRVAL_P(property_name));
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Access to undefined property %s::%s", Z_OBJCE_P(getThis())->name, Z_STRVAL_PP(property_name));
RETURN_MM_NULL();
}
4 changes: 0 additions & 4 deletions ext/di/injectable.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,4 @@ extern zend_class_entry *phalcon_di_injectable_ce;

PHALCON_INIT_CLASS(Phalcon_DI_Injectable);

ZEND_BEGIN_ARG_INFO_EX(arginfo_phalcon_di_injectable___get, 0, 0, 1)
ZEND_ARG_INFO(0, propertyName)
ZEND_END_ARG_INFO()

#endif /* PHALCON_DI_INJECTABLE_H */
21 changes: 21 additions & 0 deletions ext/tests/issue-1983.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
--TEST--
Segmentation Fault in Phalcon\DI\Injectable::__get() - https://github.com/phalcon/cphalcon/issues/1983
--SKIPIF--
<?php include('skipif.inc'); ?>
--FILE--
<?php

class TestClass extends \Phalcon\DI\Injectable
{
public function test()
{
$a = $this->__get(1);
}
}

new \Phalcon\DI;
$x = new TestClass();
$x->test();
?>
--EXPECTF--
Warning: %s::__get(): Access to undefined property %s::1 in %s on line %d

0 comments on commit 7259ca2

Please sign in to comment.