chregu Mon Jan 19 10:07:09 2004 EDT Modified files: /php-src/ext/xsl php_xsl.c php_xsl.h xsl_fe.h xsltprocessor.c Log: @- added XsltProcessor->registerPhpFunctions() (Christian) without that method call, it is not allowed to call php functions from xslt stylesheets for security reasons.
http://cvs.php.net/diff.php/php-src/ext/xsl/php_xsl.c?r1=1.17&r2=1.18&ty=u Index: php-src/ext/xsl/php_xsl.c diff -u php-src/ext/xsl/php_xsl.c:1.17 php-src/ext/xsl/php_xsl.c:1.18 --- php-src/ext/xsl/php_xsl.c:1.17 Thu Jan 8 03:17:48 2004 +++ php-src/ext/xsl/php_xsl.c Mon Jan 19 10:07:08 2004 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_xsl.c,v 1.17 2004/01/08 08:17:48 andi Exp $ */ +/* $Id: php_xsl.c,v 1.18 2004/01/19 15:07:08 chregu Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -27,8 +27,6 @@ #include "ext/standard/info.h" #include "php_xsl.h" -static void xsl_ext_function_string_php(xmlXPathParserContextPtr ctxt, int nargs); -static void xsl_ext_function_object_php(xmlXPathParserContextPtr ctxt, int nargs); /* If you declare any globals in php_xsl.h uncomment this: ZEND_DECLARE_MODULE_GLOBALS(xsl) @@ -114,6 +112,7 @@ intern->prop_handler = NULL; intern->parameter = NULL; intern->hasKeys = 0; + intern->registerPhpFunctions = 0; ALLOC_HASHTABLE(intern->std.properties); zend_hash_init(intern->std.properties, 0, NULL, ZVAL_PTR_DTOR, 0); @@ -140,12 +139,6 @@ #if HAVE_XSL_EXSLT exsltRegisterAll(); #endif - xsltRegisterExtModuleFunction ((const xmlChar *) "functionString", - (const xmlChar *) "http://php.net/xsl", - xsl_ext_function_string_php); - xsltRegisterExtModuleFunction ((const xmlChar *) "function", - (const xmlChar *) "http://php.net/xsl", - xsl_ext_function_object_php); REGISTER_LONG_CONSTANT("XSL_CLONE_AUTO", 0, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("XSL_CLONE_NEVER", -1, CONST_CS | CONST_PERSISTENT); @@ -155,157 +148,6 @@ } /* }}} */ - -static void xsl_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs, int type) -{ - xsltTransformContextPtr tctxt; - zval **args; - zval *retval; - int result, i, ret; - zend_fcall_info fci; - zval handler; - xmlXPathObjectPtr obj; - char *str; - - TSRMLS_FETCH(); - - tctxt = xsltXPathGetTransformContext(ctxt); - if (tctxt == NULL) { - xsltGenericError(xsltGenericErrorContext, - "xsltExtFunctionTest: failed to get the transformation context\n"); - return; - } - - fci.param_count = nargs - 1; - fci.params = safe_emalloc(fci.param_count, sizeof(zval**), 0); - - args = safe_emalloc(nargs - 1, sizeof(zval *), 0); - /* Reverse order to pop values off ctxt stack */ - for (i = nargs - 2; i >= 0; i--) { - obj = valuePop(ctxt); - MAKE_STD_ZVAL(args[i]); - switch (obj->type) { - case XPATH_STRING: - ZVAL_STRING(args[i], obj->stringval, 1); - break; - case XPATH_BOOLEAN: - ZVAL_BOOL(args[i], obj->boolval); - break; - case XPATH_NUMBER: - ZVAL_DOUBLE(args[i], obj->floatval); - break; - case XPATH_NODESET: - if (type == 1) { - str = xmlXPathCastToString(obj); - ZVAL_STRING(args[i], str, 1); - xmlFree(str); - } else if (type == 2) { - int j; - dom_object *intern; - array_init(args[i]); - if (obj->nodesetval->nodeNr > 0) { - intern = (dom_object *) php_dom_object_get_data((void *) obj->nodesetval->nodeTab[0]->doc); - for (j = 0; j < obj->nodesetval->nodeNr; j++) { - xmlNodePtr node = obj->nodesetval->nodeTab[j]; - zval *child; - - MAKE_STD_ZVAL(child); - /* not sure, if we need this... it's copied from xpath.c */ - if (node->type == XML_NAMESPACE_DECL) { - xmlNsPtr curns; - xmlNodePtr nsparent; - - nsparent = node->_private; - curns = xmlNewNs(NULL, node->name, NULL); - if (node->children) { - curns->prefix = xmlStrdup((char *) node->children); - } - if (node->children) { - node = xmlNewDocNode(node->doc, NULL, (char *) node->children, node->name); - } else { - node = xmlNewDocNode(node->doc, NULL, "xmlns", node->name); - } - node->type = XML_NAMESPACE_DECL; - node->parent = nsparent; - node->ns = curns; - } - child = php_dom_create_object(node, &ret, NULL, child, intern TSRMLS_CC); - add_next_index_zval(args[i], child); - } - } - } - break; - default: - php_error_docref(NULL TSRMLS_CC, E_WARNING, "php:function object type %d is not supported yet", obj->type); - ZVAL_STRING(args[i], "", 0); - } - 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); - for (i = 0; i < nargs - 1; i++) { - zval_ptr_dtor(&args[i]); - } - efree(args); - efree(fci.params); - return; - } - INIT_PZVAL(&handler); - ZVAL_STRING(&handler, obj->stringval, 1); - xmlXPathFreeObject(obj); - - fci.function_name = &handler; - fci.symbol_table = NULL; - fci.object_pp = NULL; - fci.retval_ptr_ptr = &retval; - fci.no_separation = 0; - /*fci.function_handler_cache = &function_ptr;*/ - - result = zend_call_function(&fci, NULL TSRMLS_CC); - if (result == FAILURE) { - if (Z_TYPE(handler) == IS_STRING) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call handler %s()", Z_STRVAL_P(&handler)); - } - } else { - if (retval->type == IS_OBJECT && instanceof_function( Z_OBJCE_P(retval), dom_node_class_entry TSRMLS_CC)) { - xmlNode *nodep; - dom_object *obj; - obj = (dom_object *)zend_object_store_get_object(retval TSRMLS_CC); - nodep = dom_object_get_node(obj); - valuePush(ctxt, xmlXPathNewNodeSet(nodep)); - } else if (retval->type == IS_BOOL) { - valuePush(ctxt, xmlXPathNewBoolean(retval->value.lval)); - } else { - convert_to_string_ex(&retval); - valuePush(ctxt, xmlXPathNewString( Z_STRVAL_P(retval))); - } - zval_ptr_dtor(&retval); - } - zval_dtor(&handler); - for (i = 0; i < nargs - 1; i++) { - zval_ptr_dtor(&args[i]); - } - efree(args); - efree(fci.params); -} - -static void xsl_ext_function_string_php(xmlXPathParserContextPtr ctxt, int nargs) -{ - xsl_ext_function_php(ctxt, nargs, 1); -} - -static void xsl_ext_function_object_php(xmlXPathParserContextPtr ctxt, int nargs) -{ - xsl_ext_function_php(ctxt, nargs, 2); -} - /* {{{ xsl_object_get_data */ zval *xsl_object_get_data(void *obj) { http://cvs.php.net/diff.php/php-src/ext/xsl/php_xsl.h?r1=1.8&r2=1.9&ty=u Index: php-src/ext/xsl/php_xsl.h diff -u php-src/ext/xsl/php_xsl.h:1.8 php-src/ext/xsl/php_xsl.h:1.9 --- php-src/ext/xsl/php_xsl.h:1.8 Thu Jan 8 12:33:01 2004 +++ php-src/ext/xsl/php_xsl.h Mon Jan 19 10:07:08 2004 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_xsl.h,v 1.8 2004/01/08 17:33:01 sniper Exp $ */ +/* $Id: php_xsl.h,v 1.9 2004/01/19 15:07:08 chregu Exp $ */ #ifndef PHP_XSL_H #define PHP_XSL_H @@ -56,6 +56,7 @@ zend_object_handle handle; HashTable *parameter; int hasKeys; + int registerPhpFunctions; } xsl_object; void php_xsl_set_object(zval *wrapper, void *obj TSRMLS_DC); http://cvs.php.net/diff.php/php-src/ext/xsl/xsl_fe.h?r1=1.5&r2=1.6&ty=u Index: php-src/ext/xsl/xsl_fe.h diff -u php-src/ext/xsl/xsl_fe.h:1.5 php-src/ext/xsl/xsl_fe.h:1.6 --- php-src/ext/xsl/xsl_fe.h:1.5 Thu Jan 8 12:33:01 2004 +++ php-src/ext/xsl/xsl_fe.h Mon Jan 19 10:07:08 2004 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: xsl_fe.h,v 1.5 2004/01/08 17:33:01 sniper Exp $ */ +/* $Id: xsl_fe.h,v 1.6 2004/01/19 15:07:08 chregu Exp $ */ #ifndef XSL_FE_H #define XSL_FE_H @@ -32,4 +32,5 @@ PHP_FUNCTION(xsl_xsltprocessor_get_parameter); PHP_FUNCTION(xsl_xsltprocessor_remove_parameter); PHP_FUNCTION(xsl_xsltprocessor_has_exslt_support); +PHP_FUNCTION(xsl_xsltprocessor_register_php_functions); #endif http://cvs.php.net/diff.php/php-src/ext/xsl/xsltprocessor.c?r1=1.20&r2=1.21&ty=u Index: php-src/ext/xsl/xsltprocessor.c diff -u php-src/ext/xsl/xsltprocessor.c:1.20 php-src/ext/xsl/xsltprocessor.c:1.21 --- php-src/ext/xsl/xsltprocessor.c:1.20 Thu Jan 8 03:17:48 2004 +++ php-src/ext/xsl/xsltprocessor.c Mon Jan 19 10:07:08 2004 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: xsltprocessor.c,v 1.20 2004/01/08 08:17:48 andi Exp $ */ +/* $Id: xsltprocessor.c,v 1.21 2004/01/19 15:07:08 chregu Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -27,6 +27,9 @@ #include "php_xsl.h" #include "ext/libxml/php_libxml.h" +static void xsl_ext_function_string_php(xmlXPathParserContextPtr ctxt, int nargs); +static void xsl_ext_function_object_php(xmlXPathParserContextPtr ctxt, int nargs); + /* * class xsl_xsltprocessor * @@ -43,6 +46,7 @@ PHP_FALIAS(getParameter, xsl_xsltprocessor_get_parameter, NULL) PHP_FALIAS(removeParameter, xsl_xsltprocessor_remove_parameter, NULL) PHP_FALIAS(hasExsltSupport, xsl_xsltprocessor_has_exslt_support, NULL) + PHP_FALIAS(registerPhpFunctions, xsl_xsltprocessor_register_php_functions, NULL) {NULL, NULL, NULL} }; @@ -72,6 +76,14 @@ return (char *) value; } +static void php_xsl_unregister_php_functions() { + xsltUnregisterExtModuleFunction ((const xmlChar *) "functionString", + (const xmlChar *) "http://php.net/xsl"); + xsltUnregisterExtModuleFunction ((const xmlChar *) "function", + (const xmlChar *) "http://php.net/xsl"); +} + + /* {{{ php_xsl_xslt_make_params() Translates a PHP array to a libxslt parameters array */ static char **php_xsl_xslt_make_params(HashTable *parht, int xpath_params TSRMLS_DC) @@ -118,6 +130,162 @@ return params; } /* }}} */ + + +static void xsl_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs, int type) +{ + xsltTransformContextPtr tctxt; + zval **args; + zval *retval; + int result, i, ret; + zend_fcall_info fci; + zval handler; + xmlXPathObjectPtr obj; + char *str; + + TSRMLS_FETCH(); + + tctxt = xsltXPathGetTransformContext(ctxt); + if (tctxt == NULL) { + xsltGenericError(xsltGenericErrorContext, + "xsltExtFunctionTest: failed to get the transformation context\n"); + return; + } + + fci.param_count = nargs - 1; + fci.params = safe_emalloc(fci.param_count, sizeof(zval**), 0); + + args = safe_emalloc(nargs - 1, sizeof(zval *), 0); + /* Reverse order to pop values off ctxt stack */ + for (i = nargs - 2; i >= 0; i--) { + obj = valuePop(ctxt); + MAKE_STD_ZVAL(args[i]); + switch (obj->type) { + case XPATH_STRING: + ZVAL_STRING(args[i], obj->stringval, 1); + break; + case XPATH_BOOLEAN: + ZVAL_BOOL(args[i], obj->boolval); + break; + case XPATH_NUMBER: + ZVAL_DOUBLE(args[i], obj->floatval); + break; + case XPATH_NODESET: + if (type == 1) { + str = xmlXPathCastToString(obj); + ZVAL_STRING(args[i], str, 1); + xmlFree(str); + } else if (type == 2) { + int j; + dom_object *intern; + array_init(args[i]); + if (obj->nodesetval->nodeNr > 0) { + intern = (dom_object *) php_dom_object_get_data((void *) obj->nodesetval->nodeTab[0]->doc); + for (j = 0; j < obj->nodesetval->nodeNr; j++) { + xmlNodePtr node = obj->nodesetval->nodeTab[j]; + zval *child; + + MAKE_STD_ZVAL(child); + /* not sure, if we need this... it's copied from xpath.c */ + if (node->type == XML_NAMESPACE_DECL) { + xmlNsPtr curns; + xmlNodePtr nsparent; + + nsparent = node->_private; + curns = xmlNewNs(NULL, node->name, NULL); + if (node->children) { + curns->prefix = xmlStrdup((char *) node->children); + } + if (node->children) { + node = xmlNewDocNode(node->doc, NULL, (char *) node->children, node->name); + } else { + node = xmlNewDocNode(node->doc, NULL, "xmlns", node->name); + } + node->type = XML_NAMESPACE_DECL; + node->parent = nsparent; + node->ns = curns; + } + child = php_dom_create_object(node, &ret, NULL, child, intern TSRMLS_CC); + add_next_index_zval(args[i], child); + } + } + } + break; + default: + php_error_docref(NULL TSRMLS_CC, E_WARNING, "php:function object type %d is not supported yet", obj->type); + ZVAL_STRING(args[i], "", 0); + } + 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); + for (i = 0; i < nargs - 1; i++) { + zval_ptr_dtor(&args[i]); + } + efree(args); + efree(fci.params); + return; + } + INIT_PZVAL(&handler); + ZVAL_STRING(&handler, obj->stringval, 1); + xmlXPathFreeObject(obj); + + fci.function_name = &handler; + fci.symbol_table = NULL; + fci.object_pp = NULL; + fci.retval_ptr_ptr = &retval; + fci.no_separation = 0; + /*fci.function_handler_cache = &function_ptr;*/ + + result = zend_call_function(&fci, NULL TSRMLS_CC); + if (result == FAILURE) { + if (Z_TYPE(handler) == IS_STRING) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call handler %s()", Z_STRVAL_P(&handler)); + } + } else { + if (retval->type == IS_OBJECT && instanceof_function( Z_OBJCE_P(retval), dom_node_class_entry TSRMLS_CC)) { + xmlNode *nodep; + dom_object *obj; + obj = (dom_object *)zend_object_store_get_object(retval TSRMLS_CC); + nodep = dom_object_get_node(obj); + valuePush(ctxt, xmlXPathNewNodeSet(nodep)); + } else if (retval->type == IS_BOOL) { + valuePush(ctxt, xmlXPathNewBoolean(retval->value.lval)); + } else if (retval->type == IS_OBJECT) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "A PHP Object can not be converted to a XPath-string"); + valuePush(ctxt, xmlXPathNewString("")); + } else { + convert_to_string_ex(&retval); + valuePush(ctxt, xmlXPathNewString( Z_STRVAL_P(retval))); + } + zval_ptr_dtor(&retval); + } + zval_dtor(&handler); + for (i = 0; i < nargs - 1; i++) { + zval_ptr_dtor(&args[i]); + } + efree(args); + efree(fci.params); +} + +static void xsl_ext_function_string_php(xmlXPathParserContextPtr ctxt, int nargs) +{ + xsl_ext_function_php(ctxt, nargs, 1); +} + +static void xsl_ext_function_object_php(xmlXPathParserContextPtr ctxt, int nargs) +{ + xsl_ext_function_php(ctxt, nargs, 2); +} + + /* {{{ proto xsl_xsltdocucument xsl_xsltprocessor_import_stylesheet(node index); URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html# Since: @@ -228,6 +396,11 @@ doc = xmlCopyDoc(doc, 1); } newdocp = xsltApplyStylesheet(sheetp, doc, (const char**) params); + + if (intern->registerPhpFunctions == 1) { + php_xsl_unregister_php_functions(); + } + if (intern->hasKeys == 1) { xmlFreeDoc(doc); } @@ -282,7 +455,11 @@ } newdocp = xsltApplyStylesheet(sheetp, doc, (const char**)params); - + + if (intern->registerPhpFunctions == 1) { + php_xsl_unregister_php_functions(); + } + if (intern->hasKeys == 1) { xmlFreeDoc(doc); } @@ -339,7 +516,11 @@ } newdocp = xsltApplyStylesheet(sheetp, doc, (const char**)params); - + + if (intern->registerPhpFunctions == 1) { + php_xsl_unregister_php_functions(); + } + if (intern->hasKeys == 1) { xmlFreeDoc(doc); } @@ -442,6 +623,28 @@ } /* }}} end xsl_xsltprocessor_remove_parameter */ +/* {{{ proto xsl_xsltprocessor_register_php_functions(); +*/ +PHP_FUNCTION(xsl_xsltprocessor_register_php_functions) +{ + zval *id; + xsl_object *intern; + + DOM_GET_THIS(id); + + + intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC); + intern->registerPhpFunctions = 1; + + xsltRegisterExtModuleFunction ((const xmlChar *) "functionString", + (const xmlChar *) "http://php.net/xsl", + xsl_ext_function_string_php); + xsltRegisterExtModuleFunction ((const xmlChar *) "function", + (const xmlChar *) "http://php.net/xsl", + xsl_ext_function_object_php); +} +/* }}} end xsl_xsltprocessor_register_php_functions(); */ + /* {{{ proto xsl_xsltprocessor_has_exslt_support(); */ PHP_FUNCTION(xsl_xsltprocessor_has_exslt_support)
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php