Skip to content

Commit c405f03

Browse files
committed
Only use FCC for libxml entity loader callback
1 parent bbeb6c3 commit c405f03

File tree

2 files changed

+27
-43
lines changed

2 files changed

+27
-43
lines changed

ext/libxml/libxml.c

Lines changed: 26 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -228,9 +228,7 @@ static PHP_GINIT_FUNCTION(libxml)
228228
ZVAL_UNDEF(&libxml_globals->stream_context);
229229
libxml_globals->error_buffer.s = NULL;
230230
libxml_globals->error_list = NULL;
231-
ZVAL_NULL(&libxml_globals->entity_loader.callback);
232-
libxml_globals->entity_loader.fci.size = 0;
233-
libxml_globals->entity_loader_disabled = 0;
231+
libxml_globals->entity_loader_callback = empty_fcall_info_cache;
234232
}
235233

236234
/* Channel libxml file io layer through the PHP streams subsystem.
@@ -573,13 +571,9 @@ static xmlParserInputPtr _php_libxml_external_entity_loader(const char *URL,
573571
const char *resource = NULL;
574572
zval *ctxzv, retval;
575573
zval params[3];
576-
int status;
577-
zend_fcall_info *fci;
578574

579-
fci = &LIBXML(entity_loader).fci;
580-
581-
if (fci->size == 0) {
582-
/* no custom user-land callback set up; delegate to original loader */
575+
/* no custom user-land callback set up; delegate to original loader */
576+
if (!ZEND_FCC_INITIALIZED(LIBXML(entity_loader_callback))) {
583577
return _php_libxml_default_entity_loader(URL, ID, context);
584578
}
585579

@@ -611,24 +605,14 @@ static xmlParserInputPtr _php_libxml_external_entity_loader(const char *URL,
611605

612606
#undef ADD_NULL_OR_STRING_KEY
613607

614-
fci->retval = &retval;
615-
fci->params = params;
616-
fci->param_count = sizeof(params)/sizeof(*params);
608+
zend_call_known_fcc(&LIBXML(entity_loader_callback), &retval, 3, params, /* named_params */ NULL);
617609

618-
status = zend_call_function(fci, &LIBXML(entity_loader).fcc);
619-
if (status != SUCCESS || Z_ISUNDEF(retval)) {
610+
if (Z_ISUNDEF(retval)) {
620611
php_libxml_ctx_error(context,
621612
"Call to user entity loader callback '%s' has failed",
622-
Z_STRVAL(fci->function_name));
613+
ZSTR_VAL(LIBXML(entity_loader_callback).function_handler->common.function_name));
623614
} else {
624-
/*
625-
retval_ptr = *fci->retval_ptr_ptr;
626-
if (retval_ptr == NULL) {
627-
php_libxml_ctx_error(context,
628-
"Call to user entity loader callback '%s' has failed; "
629-
"probably it has thrown an exception",
630-
fci->function_name);
631-
} else */ if (Z_TYPE(retval) == IS_STRING) {
615+
if (Z_TYPE(retval) == IS_STRING) {
632616
is_string:
633617
resource = Z_STRVAL(retval);
634618
} else if (Z_TYPE(retval) == IS_RESOURCE) {
@@ -638,7 +622,7 @@ static xmlParserInputPtr _php_libxml_external_entity_loader(const char *URL,
638622
php_libxml_ctx_error(context,
639623
"The user entity loader callback '%s' has returned a "
640624
"resource, but it is not a stream",
641-
Z_STRVAL(fci->function_name));
625+
ZSTR_VAL(LIBXML(entity_loader_callback).function_handler->common.function_name));
642626
} else {
643627
/* TODO: allow storing the encoding in the stream context? */
644628
xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
@@ -839,9 +823,9 @@ static PHP_RINIT_FUNCTION(libxml)
839823

840824
static PHP_RSHUTDOWN_FUNCTION(libxml)
841825
{
842-
LIBXML(entity_loader).fci.size = 0;
843-
zval_ptr_dtor_nogc(&LIBXML(entity_loader).callback);
844-
ZVAL_NULL(&LIBXML(entity_loader).callback);
826+
if (ZEND_FCC_INITIALIZED(LIBXML(entity_loader_callback))) {
827+
zend_fcc_dtor(&LIBXML(entity_loader_callback));
828+
}
845829

846830
return SUCCESS;
847831
}
@@ -1061,24 +1045,20 @@ PHP_FUNCTION(libxml_disable_entity_loader)
10611045
/* {{{ Changes the default external entity loader */
10621046
PHP_FUNCTION(libxml_set_external_entity_loader)
10631047
{
1064-
zval *callback;
10651048
zend_fcall_info fci;
10661049
zend_fcall_info_cache fcc;
10671050

10681051
ZEND_PARSE_PARAMETERS_START(1, 1)
1069-
Z_PARAM_FUNC_OR_NULL_WITH_ZVAL(fci, fcc, callback)
1052+
Z_PARAM_FUNC_OR_NULL(fci, fcc)
10701053
ZEND_PARSE_PARAMETERS_END();
10711054

1072-
if (ZEND_FCI_INITIALIZED(fci)) { /* argument not null */
1073-
LIBXML(entity_loader).fci = fci;
1074-
LIBXML(entity_loader).fcc = fcc;
1075-
} else {
1076-
LIBXML(entity_loader).fci.size = 0;
1055+
/* Unset old callback if it's defined */
1056+
if (ZEND_FCC_INITIALIZED(LIBXML(entity_loader_callback))) {
1057+
zend_fcc_dtor(&LIBXML(entity_loader_callback));
10771058
}
1078-
if (!Z_ISNULL(LIBXML(entity_loader).callback)) {
1079-
zval_ptr_dtor_nogc(&LIBXML(entity_loader).callback);
1059+
if (ZEND_FCI_INITIALIZED(fci)) { /* argument not null */
1060+
zend_fcc_dup(&LIBXML(entity_loader_callback), &fcc);
10801061
}
1081-
ZVAL_COPY(&LIBXML(entity_loader).callback, callback);
10821062
RETURN_TRUE;
10831063
}
10841064
/* }}} */
@@ -1087,7 +1067,15 @@ PHP_FUNCTION(libxml_set_external_entity_loader)
10871067
PHP_FUNCTION(libxml_get_external_entity_loader)
10881068
{
10891069
ZEND_PARSE_PARAMETERS_NONE();
1090-
RETURN_COPY(&LIBXML(entity_loader).callback);
1070+
1071+
if (ZEND_FCC_INITIALIZED(LIBXML(entity_loader_callback))) {
1072+
zval tmp;
1073+
zend_get_callable_zval_from_fcc(&LIBXML(entity_loader_callback), &tmp);
1074+
RETVAL_COPY(&tmp);
1075+
zval_ptr_dtor(&tmp);
1076+
return;
1077+
}
1078+
RETURN_NULL();
10911079
}
10921080
/* }}} */
10931081

ext/libxml/php_libxml.h

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,7 @@ ZEND_BEGIN_MODULE_GLOBALS(libxml)
4242
zval stream_context;
4343
smart_str error_buffer;
4444
zend_llist *error_list;
45-
struct _php_libxml_entity_resolver {
46-
zval callback;
47-
zend_fcall_info fci;
48-
zend_fcall_info_cache fcc;
49-
} entity_loader;
45+
zend_fcall_info_cache entity_loader_callback;
5046
bool entity_loader_disabled;
5147
ZEND_END_MODULE_GLOBALS(libxml)
5248

0 commit comments

Comments
 (0)