]> granicus.if.org Git - php/commitdiff
Fix for bug #69782
authorStanislav Malyshev <stas@php.net>
Mon, 17 Aug 2015 00:16:15 +0000 (17:16 -0700)
committerStanislav Malyshev <stas@php.net>
Mon, 17 Aug 2015 00:16:15 +0000 (17:16 -0700)
ext/xsl/xsltprocessor.c

index 67c90f501f1b9a89d72756537d76e3266ddb8a21..d21a8ebcb70c08e8a69f0395b42ee850112e846a 100644 (file)
@@ -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;