From: Stanislav Malyshev Date: Mon, 17 Aug 2015 00:16:15 +0000 (-0700) Subject: Fix for bug #69782 X-Git-Tag: php-5.5.29~9^2~1 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1744be2d17befc69bf00033993f4081852a747d6;p=php Fix for bug #69782 --- diff --git a/ext/xsl/xsltprocessor.c b/ext/xsl/xsltprocessor.c index 67c90f501f..d21a8ebcb7 100644 --- a/ext/xsl/xsltprocessor.c +++ b/ext/xsl/xsltprocessor.c @@ -81,10 +81,10 @@ ZEND_END_ARG_INFO(); /* }}} */ /* -* class xsl_xsltprocessor +* class xsl_xsltprocessor * * URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html# -* Since: +* Since: */ const zend_function_entry php_xsl_xsltprocessor_class_functions[] = { @@ -111,9 +111,9 @@ static char *php_xsl_xslt_string_to_xpathexpr(const char *str TSRMLS_DC) xmlChar *value; int str_len; - + str_len = xmlStrlen(string) + 3; - + if (xmlStrchr(string, '"')) { if (xmlStrchr(string, '\'')) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create XPath expression (string contains both quote and double-quotes)"); @@ -133,7 +133,7 @@ static char *php_xsl_xslt_string_to_xpathexpr(const char *str TSRMLS_DC) Translates a PHP array to a libxslt parameters array */ static char **php_xsl_xslt_make_params(HashTable *parht, int xpath_params TSRMLS_DC) { - + int parsize; zval **value; char *xpath_expr, *string_key = NULL; @@ -158,7 +158,7 @@ static char **php_xsl_xslt_make_params(HashTable *parht, int xpath_params TSRMLS SEPARATE_ZVAL(value); convert_to_string(*value); } - + if (!xpath_params) { xpath_expr = php_xsl_xslt_string_to_xpathexpr(Z_STRVAL_PP(value) TSRMLS_CC); } else { @@ -192,7 +192,7 @@ static void xsl_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs, int t char *str; char *callable = NULL; xsl_object *intern; - + TSRMLS_FETCH(); if (! zend_is_executing(TSRMLS_C)) { @@ -219,15 +219,17 @@ static void xsl_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs, int t } } } - + if (error == 1) { for (i = nargs - 1; i >= 0; i--) { obj = valuePop(ctxt); - xmlXPathFreeObject(obj); + if (obj) { + xmlXPathFreeObject(obj); + } } return; } - + fci.param_count = nargs - 1; if (fci.param_count > 0) { fci.params = safe_emalloc(fci.param_count, sizeof(zval**), 0); @@ -265,7 +267,7 @@ static void xsl_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs, int t if (node->type == XML_NAMESPACE_DECL) { xmlNsPtr curns; xmlNodePtr nsparent; - + nsparent = node->_private; curns = xmlNewNs(NULL, node->name, NULL); if (node->children) { @@ -297,14 +299,16 @@ static void xsl_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs, int t xmlXPathFreeObject(obj); fci.params[i] = &args[i]; } - + fci.size = sizeof(fci); fci.function_table = EG(function_table); - + obj = valuePop(ctxt); - if (obj->stringval == NULL) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Handler name must be a string"); - xmlXPathFreeObject(obj); + if (obj == NULL || obj->stringval == NULL) { + if (obj) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Handler name must be a string"); + xmlXPathFreeObject(obj); + } valuePush(ctxt, xmlXPathNewString("")); if (fci.param_count > 0) { for (i = 0; i < nargs - 1; i++) { @@ -313,12 +317,12 @@ static void xsl_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs, int t efree(args); efree(fci.params); } - return; + return; } INIT_PZVAL(&handler); ZVAL_STRING(&handler, obj->stringval, 1); xmlXPathFreeObject(obj); - + fci.function_name = &handler; fci.symbol_table = NULL; fci.object_ptr = NULL; @@ -328,7 +332,7 @@ static void xsl_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs, int t if (!zend_make_callable(&handler, &callable TSRMLS_CC)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call handler %s()", callable); valuePush(ctxt, xmlXPathNewString("")); - } else if ( intern->registerPhpFunctions == 2 && zend_hash_exists(intern->registered_phpfunctions, callable, strlen(callable) + 1) == 0) { + } else if ( intern->registerPhpFunctions == 2 && zend_hash_exists(intern->registered_phpfunctions, callable, strlen(callable) + 1) == 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Not allowed to call handler '%s()'", callable); /* Push an empty string, so that we at least have an xslt result... */ valuePush(ctxt, xmlXPathNewString("")); @@ -392,7 +396,7 @@ void xsl_ext_function_object_php(xmlXPathParserContextPtr ctxt, int nargs) /* {{ /* {{{ proto void xsl_xsltprocessor_import_stylesheet(domdocument doc); URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html# -Since: +Since: */ PHP_FUNCTION(xsl_xsltprocessor_import_stylesheet) { @@ -404,13 +408,13 @@ PHP_FUNCTION(xsl_xsltprocessor_import_stylesheet) xmlNode *nodep = NULL; zend_object_handlers *std_hnd; zval *cloneDocu, *member; - + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oo", &id, xsl_xsltprocessor_class_entry, &docp) == FAILURE) { RETURN_FALSE; } nodep = php_libxml_import_node(docp TSRMLS_CC); - + if (nodep) { doc = nodep->doc; } @@ -419,7 +423,7 @@ PHP_FUNCTION(xsl_xsltprocessor_import_stylesheet) RETURN_FALSE; } - /* libxslt uses _private, so we must copy the imported + /* libxslt uses _private, so we must copy the imported stylesheet document otherwise the node proxies will be a mess */ newdoc = xmlCopyDoc(doc, 1); xmlNodeSetBase((xmlNodePtr) newdoc, (xmlChar *)doc->URL); @@ -436,7 +440,7 @@ PHP_FUNCTION(xsl_xsltprocessor_import_stylesheet) RETURN_FALSE; } - intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC); + intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC); std_hnd = zend_get_std_object_handlers(); MAKE_STD_ZVAL(member); @@ -463,10 +467,10 @@ PHP_FUNCTION(xsl_xsltprocessor_import_stylesheet) intern->hasKeys = clone_docu; } - if ((oldsheetp = (xsltStylesheetPtr)intern->ptr)) { + if ((oldsheetp = (xsltStylesheetPtr)intern->ptr)) { /* free wrapper */ if (((xsltStylesheetPtr) intern->ptr)->_private != NULL) { - ((xsltStylesheetPtr) intern->ptr)->_private = NULL; + ((xsltStylesheetPtr) intern->ptr)->_private = NULL; } xsltFreeStylesheet((xsltStylesheetPtr) intern->ptr); intern->ptr = NULL; @@ -494,7 +498,7 @@ static xmlDocPtr php_xsl_apply_stylesheet(zval *id, xsl_object *intern, xsltStyl xsltSecurityPrefsPtr secPrefs = NULL; node = php_libxml_import_node(docp TSRMLS_CC); - + if (node) { doc = node->doc; } @@ -507,7 +511,7 @@ static xmlDocPtr php_xsl_apply_stylesheet(zval *id, xsl_object *intern, xsltStyl php_error_docref(NULL TSRMLS_CC, E_WARNING, "No stylesheet associated to this object"); return NULL; } - + if (intern->profiling) { if (php_check_open_basedir(intern->profiling TSRMLS_CC)) { f = NULL; @@ -517,7 +521,7 @@ static xmlDocPtr php_xsl_apply_stylesheet(zval *id, xsl_object *intern, xsltStyl } else { f = NULL; } - + if (intern->parameter) { params = php_xsl_xslt_make_params(intern->parameter, 0 TSRMLS_CC); } @@ -549,7 +553,7 @@ static xmlDocPtr php_xsl_apply_stylesheet(zval *id, xsl_object *intern, xsltStyl efree(member); secPrefsValue = intern->securityPrefs; - + /* This whole if block can be removed, when we remove the xsl.security_prefs php.ini option in PHP 6+ */ secPrefsIni= INI_INT("xsl.security_prefs"); /* if secPrefsIni has the same value as secPrefsValue, all is fine */ @@ -569,38 +573,38 @@ static xmlDocPtr php_xsl_apply_stylesheet(zval *id, xsl_object *intern, xsltStyl /* if securityPrefs is set to NONE, we don't have to do any checks, but otherwise... */ if (secPrefsValue != XSL_SECPREF_NONE) { - secPrefs = xsltNewSecurityPrefs(); - if (secPrefsValue & XSL_SECPREF_READ_FILE ) { - if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_READ_FILE, xsltSecurityForbid)) { + secPrefs = xsltNewSecurityPrefs(); + if (secPrefsValue & XSL_SECPREF_READ_FILE ) { + if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_READ_FILE, xsltSecurityForbid)) { secPrefsError = 1; } } - if (secPrefsValue & XSL_SECPREF_WRITE_FILE ) { - if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_WRITE_FILE, xsltSecurityForbid)) { + if (secPrefsValue & XSL_SECPREF_WRITE_FILE ) { + if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_WRITE_FILE, xsltSecurityForbid)) { secPrefsError = 1; } } - if (secPrefsValue & XSL_SECPREF_CREATE_DIRECTORY ) { - if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_CREATE_DIRECTORY, xsltSecurityForbid)) { + if (secPrefsValue & XSL_SECPREF_CREATE_DIRECTORY ) { + if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_CREATE_DIRECTORY, xsltSecurityForbid)) { secPrefsError = 1; } } - if (secPrefsValue & XSL_SECPREF_READ_NETWORK) { - if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_READ_NETWORK, xsltSecurityForbid)) { + if (secPrefsValue & XSL_SECPREF_READ_NETWORK) { + if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_READ_NETWORK, xsltSecurityForbid)) { secPrefsError = 1; } } - if (secPrefsValue & XSL_SECPREF_WRITE_NETWORK) { - if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_WRITE_NETWORK, xsltSecurityForbid)) { + if (secPrefsValue & XSL_SECPREF_WRITE_NETWORK) { + if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_WRITE_NETWORK, xsltSecurityForbid)) { secPrefsError = 1; } } - - if (0 != xsltSetCtxtSecurityPrefs(secPrefs, ctxt)) { + + if (0 != xsltSetCtxtSecurityPrefs(secPrefs, ctxt)) { secPrefsError = 1; } } - + if (secPrefsError == 1) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't set libxslt security properties, not doing transformation for security reasons"); } else { @@ -609,7 +613,7 @@ static xmlDocPtr php_xsl_apply_stylesheet(zval *id, xsl_object *intern, xsltStyl if (f) { fclose(f); } - + xsltFreeTransformContext(ctxt); if (secPrefs) { xsltFreeSecurityPrefs(secPrefs); @@ -617,7 +621,7 @@ static xmlDocPtr php_xsl_apply_stylesheet(zval *id, xsl_object *intern, xsltStyl if (intern->node_list != NULL) { zend_hash_destroy(intern->node_list); - FREE_HASHTABLE(intern->node_list); + FREE_HASHTABLE(intern->node_list); intern->node_list = NULL; } @@ -640,7 +644,7 @@ static xmlDocPtr php_xsl_apply_stylesheet(zval *id, xsl_object *intern, xsltStyl /* {{{ proto domdocument xsl_xsltprocessor_transform_to_doc(domnode doc); URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html# -Since: +Since: */ PHP_FUNCTION(xsl_xsltprocessor_transform_to_doc) { @@ -677,13 +681,13 @@ PHP_FUNCTION(xsl_xsltprocessor_transform_to_doc) found = zend_lookup_class(ret_class, ret_class_len, &ce TSRMLS_CC); if ((found != SUCCESS) || !instanceof_function(*ce, curce TSRMLS_CC)) { xmlFreeDoc(newdocp); - php_error_docref(NULL TSRMLS_CC, E_WARNING, + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Expecting class compatible with %s, '%s' given", curclass_name, ret_class); RETURN_FALSE; } object_init_ex(return_value, *ce); - + interndoc = (php_libxml_node_object *)zend_objects_get_address(return_value TSRMLS_CC); php_libxml_increment_doc_ref(interndoc, newdocp TSRMLS_CC); php_libxml_increment_node_ptr(interndoc, (xmlNodePtr)newdocp, (void *)interndoc TSRMLS_CC); @@ -693,7 +697,7 @@ PHP_FUNCTION(xsl_xsltprocessor_transform_to_doc) } else { RETURN_FALSE; } - + } /* }}} end xsl_xsltprocessor_transform_to_doc */ @@ -707,7 +711,7 @@ PHP_FUNCTION(xsl_xsltprocessor_transform_to_uri) int ret, uri_len; char *uri; xsl_object *intern; - + id = getThis(); intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC); sheetp = (xsltStylesheetPtr) intern->ptr; @@ -739,7 +743,7 @@ PHP_FUNCTION(xsl_xsltprocessor_transform_to_xml) xmlChar *doc_txt_ptr; int doc_txt_len; xsl_object *intern; - + id = getThis(); intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC); sheetp = (xsltStylesheetPtr) intern->ptr; @@ -770,7 +774,7 @@ PHP_FUNCTION(xsl_xsltprocessor_transform_to_xml) */ PHP_FUNCTION(xsl_xsltprocessor_set_parameter) { - + zval *id; zval *array_value, **entry, *new_string; xsl_object *intern; @@ -786,34 +790,34 @@ PHP_FUNCTION(xsl_xsltprocessor_set_parameter) while (zend_hash_get_current_data(Z_ARRVAL_P(array_value), (void **)&entry) == SUCCESS) { SEPARATE_ZVAL(entry); convert_to_string_ex(entry); - + if (zend_hash_get_current_key_ex(Z_ARRVAL_P(array_value), &string_key, &string_key_len, &idx, 0, NULL) != HASH_KEY_IS_STRING) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid parameter array"); RETURN_FALSE; } - + ALLOC_ZVAL(new_string); Z_ADDREF_PP(entry); COPY_PZVAL_TO_ZVAL(*new_string, *entry); - + zend_hash_update(intern->parameter, string_key, string_key_len, &new_string, sizeof(zval*), NULL); zend_hash_move_forward(Z_ARRVAL_P(array_value)); } RETURN_TRUE; } else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "sss", &namespace, &namespace_len, &name, &name_len, &value, &value_len) == SUCCESS) { - + intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC); - + MAKE_STD_ZVAL(new_string); ZVAL_STRING(new_string, value, 1); - + zend_hash_update(intern->parameter, name, name_len + 1, &new_string, sizeof(zval*), NULL); RETURN_TRUE; } else { WRONG_PARAM_COUNT; } - + } /* }}} end xsl_xsltprocessor_set_parameter */ @@ -828,7 +832,7 @@ PHP_FUNCTION(xsl_xsltprocessor_get_parameter) xsl_object *intern; DOM_GET_THIS(id); - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &namespace, &namespace_len, &name, &name_len) == FAILURE) { RETURN_FALSE; } @@ -852,7 +856,7 @@ PHP_FUNCTION(xsl_xsltprocessor_remove_parameter) xsl_object *intern; DOM_GET_THIS(id); - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &namespace, &namespace_len, &name, &name_len) == FAILURE) { RETURN_FALSE; } @@ -876,7 +880,7 @@ PHP_FUNCTION(xsl_xsltprocessor_register_php_functions) char *name; DOM_GET_THIS(id); - + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "a", &array_value) == SUCCESS) { intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC); zend_hash_internal_pointer_reset(Z_ARRVAL_P(array_value)); @@ -884,10 +888,10 @@ PHP_FUNCTION(xsl_xsltprocessor_register_php_functions) while (zend_hash_get_current_data(Z_ARRVAL_P(array_value), (void **)&entry) == SUCCESS) { SEPARATE_ZVAL(entry); convert_to_string_ex(entry); - + MAKE_STD_ZVAL(new_string); ZVAL_LONG(new_string,1); - + zend_hash_update(intern->registered_phpfunctions, Z_STRVAL_PP(entry), Z_STRLEN_PP(entry) + 1, &new_string, sizeof(zval*), NULL); zend_hash_move_forward(Z_ARRVAL_P(array_value)); } @@ -895,17 +899,17 @@ PHP_FUNCTION(xsl_xsltprocessor_register_php_functions) } else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == SUCCESS) { intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC); - + MAKE_STD_ZVAL(new_string); ZVAL_LONG(new_string,1); zend_hash_update(intern->registered_phpfunctions, name, name_len + 1, &new_string, sizeof(zval*), NULL); intern->registerPhpFunctions = 2; - + } else { intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC); intern->registerPhpFunctions = 1; } - + } /* }}} end xsl_xsltprocessor_register_php_functions(); */ @@ -947,7 +951,7 @@ PHP_FUNCTION(xsl_xsltprocessor_set_security_prefs) return; } intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC); - oldSecurityPrefs = intern->securityPrefs; + oldSecurityPrefs = intern->securityPrefs; intern->securityPrefs = securityPrefs; /* set this to 1 so that we know, it was set through this method. Can be removed, when we remove the ini setting */ intern->securityPrefsSet = 1;