Skip to content

Commit 42cac9d

Browse files
committed
Don't call Reflection::export() internally
export() methods were implemented in a roundabout way, where they would call Reflection::export(), which would then call __toString(). Cut out the middleman by directly calling __toString().
1 parent 17997a9 commit 42cac9d

File tree

1 file changed

+32
-52
lines changed

1 file changed

+32
-52
lines changed

ext/reflection/php_reflection.c

Lines changed: 32 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1256,6 +1256,35 @@ static void reflection_class_constant_factory(zend_class_entry *ce, zend_string
12561256
}
12571257
/* }}} */
12581258

1259+
static void reflection_export_impl(zval *return_value, zval *object, zend_bool return_output) {
1260+
zval fname, retval;
1261+
int result;
1262+
1263+
/* Invoke the __toString() method */
1264+
ZVAL_STRINGL(&fname, "__tostring", sizeof("__tostring") - 1);
1265+
result = call_user_function(NULL, object, &fname, &retval, 0, NULL);
1266+
zval_ptr_dtor_str(&fname);
1267+
1268+
if (result == FAILURE) {
1269+
_DO_THROW("Invocation of method __toString() failed");
1270+
return;
1271+
}
1272+
1273+
if (Z_TYPE(retval) == IS_UNDEF) {
1274+
php_error_docref(NULL, E_WARNING, "%s::__toString() did not return anything", ZSTR_VAL(Z_OBJCE_P(object)->name));
1275+
RETURN_FALSE;
1276+
}
1277+
1278+
if (return_output) {
1279+
ZVAL_COPY_VALUE(return_value, &retval);
1280+
} else {
1281+
/* No need for _r variant, return of __toString should always be a string */
1282+
zend_print_zval(&retval, 0);
1283+
zend_printf("\n");
1284+
zval_ptr_dtor(&retval);
1285+
}
1286+
}
1287+
12591288
/* {{{ _reflection_export */
12601289
static void _reflection_export(INTERNAL_FUNCTION_PARAMETERS, zend_class_entry *ce_ptr, int ctor_argc)
12611290
{
@@ -1315,33 +1344,7 @@ static void _reflection_export(INTERNAL_FUNCTION_PARAMETERS, zend_class_entry *c
13151344
return;
13161345
}
13171346

1318-
/* Call static reflection::export */
1319-
ZVAL_COPY_VALUE(&params[0], &reflector);
1320-
ZVAL_BOOL(&params[1], return_output);
1321-
1322-
ZVAL_STRINGL(&fci.function_name, "reflection::export", sizeof("reflection::export") - 1);
1323-
fci.object = NULL;
1324-
fci.retval = &retval;
1325-
fci.param_count = 2;
1326-
fci.params = params;
1327-
fci.no_separation = 1;
1328-
1329-
result = zend_call_function(&fci, NULL);
1330-
1331-
zval_ptr_dtor(&fci.function_name);
1332-
1333-
if (result == FAILURE && EG(exception) == NULL) {
1334-
zval_ptr_dtor(&reflector);
1335-
zval_ptr_dtor(&retval);
1336-
_DO_THROW("Could not execute reflection::export()");
1337-
return;
1338-
}
1339-
1340-
if (return_output) {
1341-
ZVAL_COPY_VALUE(return_value, &retval);
1342-
} else {
1343-
zval_ptr_dtor(&retval);
1344-
}
1347+
reflection_export_impl(return_value, &reflector, return_output);
13451348

13461349
/* Destruct reflector which is no longer needed */
13471350
zval_ptr_dtor(&reflector);
@@ -1404,8 +1407,7 @@ ZEND_METHOD(reflection, __clone)
14041407
Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */
14051408
ZEND_METHOD(reflection, export)
14061409
{
1407-
zval *object, fname, retval;
1408-
int result;
1410+
zval *object;
14091411
zend_bool return_output = 0;
14101412

14111413
ZEND_PARSE_PARAMETERS_START(1, 2)
@@ -1414,29 +1416,7 @@ ZEND_METHOD(reflection, export)
14141416
Z_PARAM_BOOL(return_output)
14151417
ZEND_PARSE_PARAMETERS_END();
14161418

1417-
/* Invoke the __toString() method */
1418-
ZVAL_STRINGL(&fname, "__tostring", sizeof("__tostring") - 1);
1419-
result= call_user_function(NULL, object, &fname, &retval, 0, NULL);
1420-
zval_ptr_dtor_str(&fname);
1421-
1422-
if (result == FAILURE) {
1423-
_DO_THROW("Invocation of method __toString() failed");
1424-
return;
1425-
}
1426-
1427-
if (Z_TYPE(retval) == IS_UNDEF) {
1428-
php_error_docref(NULL, E_WARNING, "%s::__toString() did not return anything", ZSTR_VAL(Z_OBJCE_P(object)->name));
1429-
RETURN_FALSE;
1430-
}
1431-
1432-
if (return_output) {
1433-
ZVAL_COPY_VALUE(return_value, &retval);
1434-
} else {
1435-
/* No need for _r variant, return of __toString should always be a string */
1436-
zend_print_zval(&retval, 0);
1437-
zend_printf("\n");
1438-
zval_ptr_dtor(&retval);
1439-
}
1419+
reflection_export_impl(return_value, object, return_output);
14401420
}
14411421
/* }}} */
14421422

0 commit comments

Comments
 (0)