summaryrefslogtreecommitdiff
path: root/ext/xsl
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@baserock.org>2013-03-14 05:42:27 +0000
committer <>2013-04-03 16:25:08 +0000
commitc4dd7a1a684490673e25aaf4fabec5df138854c4 (patch)
tree4d57c44caae4480efff02b90b9be86f44bf25409 /ext/xsl
downloadphp2-master.tar.gz
Imported from /home/lorry/working-area/delta_php2/php-5.4.13.tar.bz2.HEADphp-5.4.13master
Diffstat (limited to 'ext/xsl')
-rw-r--r--ext/xsl/CREDITS2
-rw-r--r--ext/xsl/config.m467
-rw-r--r--ext/xsl/config.w3249
-rw-r--r--ext/xsl/php_xsl.c339
-rw-r--r--ext/xsl/php_xsl.h135
-rw-r--r--ext/xsl/tests/area_list.xsl10
-rw-r--r--ext/xsl/tests/area_name.xml12
-rw-r--r--ext/xsl/tests/bug26384.phpt33
-rw-r--r--ext/xsl/tests/bug33853.phpt33
-rw-r--r--ext/xsl/tests/bug48221.phpt17
-rw-r--r--ext/xsl/tests/bug54446.phpt95
-rw-r--r--ext/xsl/tests/bug54446_with_ini.phpt135
-rw-r--r--ext/xsl/tests/documentxpath.xsl10
-rw-r--r--ext/xsl/tests/exslt.xml15
-rw-r--r--ext/xsl/tests/exslt.xsl45
-rw-r--r--ext/xsl/tests/phpfunc-nostring.xsl10
-rw-r--r--ext/xsl/tests/phpfunc-undef.xsl10
-rw-r--r--ext/xsl/tests/phpfunc.xsl11
-rw-r--r--ext/xsl/tests/prepare.inc20
-rw-r--r--ext/xsl/tests/skipif.inc1
-rw-r--r--ext/xsl/tests/streamsinclude.xsl6
-rw-r--r--ext/xsl/tests/xsl-phpinfo.phpt18
-rw-r--r--ext/xsl/tests/xslt.xml28
-rw-r--r--ext/xsl/tests/xslt.xsl26
-rw-r--r--ext/xsl/tests/xslt.xsl.gzbin0 -> 395 bytes
-rw-r--r--ext/xsl/tests/xslt001.phpt22
-rw-r--r--ext/xsl/tests/xslt002.phpt29
-rw-r--r--ext/xsl/tests/xslt003.phpt23
-rw-r--r--ext/xsl/tests/xslt004.phpt29
-rw-r--r--ext/xsl/tests/xslt005.phpt31
-rw-r--r--ext/xsl/tests/xslt006.phpt23
-rw-r--r--ext/xsl/tests/xslt007.phpt24
-rw-r--r--ext/xsl/tests/xslt008.phpt31
-rw-r--r--ext/xsl/tests/xslt009.phpt28
-rw-r--r--ext/xsl/tests/xslt010.phpt206
-rw-r--r--ext/xsl/tests/xslt011.phpt59
-rw-r--r--ext/xsl/tests/xslt011.xml1
-rw-r--r--ext/xsl/tests/xslt011.xsl25
-rw-r--r--ext/xsl/tests/xslt012.phpt52
-rw-r--r--ext/xsl/tests/xslt012.xsl29
-rw-r--r--ext/xsl/tests/xsltprocessor_getParameter-invalidparam.phpt17
-rw-r--r--ext/xsl/tests/xsltprocessor_getParameter-wrongparam.phpt26
-rw-r--r--ext/xsl/tests/xsltprocessor_getParameter.phpt19
-rw-r--r--ext/xsl/tests/xsltprocessor_registerPHPFunctions-allfuncs.phpt30
-rw-r--r--ext/xsl/tests/xsltprocessor_registerPHPFunctions-array-multiple.phpt34
-rw-r--r--ext/xsl/tests/xsltprocessor_registerPHPFunctions-array-notallowed.phpt28
-rw-r--r--ext/xsl/tests/xsltprocessor_registerPHPFunctions-array.phpt26
-rw-r--r--ext/xsl/tests/xsltprocessor_registerPHPFunctions-funcnostring.phpt31
-rw-r--r--ext/xsl/tests/xsltprocessor_registerPHPFunctions-funcundef.phpt30
-rw-r--r--ext/xsl/tests/xsltprocessor_registerPHPFunctions-null.phpt32
-rw-r--r--ext/xsl/tests/xsltprocessor_registerPHPFunctions-string-multiple.phpt32
-rw-r--r--ext/xsl/tests/xsltprocessor_registerPHPFunctions-string-notallowed.phpt28
-rw-r--r--ext/xsl/tests/xsltprocessor_registerPHPFunctions-string.phpt26
-rw-r--r--ext/xsl/tests/xsltprocessor_removeParameter-invalidparam.phpt18
-rw-r--r--ext/xsl/tests/xsltprocessor_removeParameter-wrongparams.phpt23
-rw-r--r--ext/xsl/tests/xsltprocessor_removeParameter.phpt20
-rw-r--r--ext/xsl/tests/xsltprocessor_setparameter-errorquote.phpt21
-rw-r--r--ext/xsl/tests/xsltprocessor_setparameter-nostring.phpt22
-rw-r--r--ext/xsl/xsl.dsp120
-rw-r--r--ext/xsl/xsl_fe.h49
-rw-r--r--ext/xsl/xsltprocessor.c992
61 files changed, 3363 insertions, 0 deletions
diff --git a/ext/xsl/CREDITS b/ext/xsl/CREDITS
new file mode 100644
index 0000000..2f33c88
--- /dev/null
+++ b/ext/xsl/CREDITS
@@ -0,0 +1,2 @@
+XSL
+Christian Stocker, Rob Richards
diff --git a/ext/xsl/config.m4 b/ext/xsl/config.m4
new file mode 100644
index 0000000..a2b16d2
--- /dev/null
+++ b/ext/xsl/config.m4
@@ -0,0 +1,67 @@
+dnl
+dnl $Id$
+dnl
+
+PHP_ARG_WITH(xsl, for XSL support,
+[ --with-xsl[=DIR] Include XSL support. DIR is the libxslt base
+ install directory (libxslt >= 1.1.0 required)])
+
+if test "$PHP_XSL" != "no"; then
+
+ if test "$PHP_LIBXML" = "no"; then
+ AC_MSG_ERROR([XSL extension requires LIBXML extension, add --enable-libxml])
+ fi
+
+ if test "$PHP_DOM" = "no"; then
+ AC_MSG_ERROR([XSL extension requires DOM extension, add --enable-dom])
+ fi
+
+ for i in $PHP_XSL /usr/local /usr; do
+ if test -x "$i/bin/xslt-config"; then
+ XSLT_CONFIG=$i/bin/xslt-config
+ break
+ fi
+ done
+
+ if test -z "$XSLT_CONFIG"; then
+ AC_MSG_ERROR([xslt-config not found. Please reinstall the libxslt >= 1.1.0 distribution])
+ else
+ libxslt_full_version=`$XSLT_CONFIG --version`
+ ac_IFS=$IFS
+ IFS="."
+ set $libxslt_full_version
+ IFS=$ac_IFS
+ LIBXSLT_VERSION=`expr [$]1 \* 1000000 + [$]2 \* 1000 + [$]3`
+ if test "$LIBXSLT_VERSION" -ge "1001000"; then
+ XSL_LIBS=`$XSLT_CONFIG --libs`
+ XSL_INCS=`$XSLT_CONFIG --cflags`
+ PHP_EVAL_LIBLINE($XSL_LIBS, XSL_SHARED_LIBADD)
+ PHP_EVAL_INCLINE($XSL_INCS)
+
+ AC_MSG_CHECKING([for EXSLT support])
+ for i in $PHP_XSL /usr/local /usr; do
+ if test -r "$i/include/libexslt/exslt.h"; then
+ PHP_XSL_EXSL_DIR=$i
+ break
+ fi
+ done
+ if test -z "$PHP_XSL_EXSL_DIR"; then
+ AC_MSG_RESULT(not found)
+ else
+ AC_MSG_RESULT(found)
+ PHP_ADD_LIBRARY_WITH_PATH(exslt, $PHP_XSL_EXSL_DIR/$PHP_LIBDIR, XSL_SHARED_LIBADD)
+ PHP_ADD_INCLUDE($PHP_XSL_EXSL_DIR/include)
+ AC_DEFINE(HAVE_XSL_EXSLT,1,[ ])
+ fi
+ else
+ AC_MSG_ERROR([libxslt version 1.1.0 or greater required.])
+ fi
+
+
+ fi
+
+ AC_DEFINE(HAVE_XSL,1,[ ])
+ PHP_NEW_EXTENSION(xsl, php_xsl.c xsltprocessor.c, $ext_shared)
+ PHP_SUBST(XSL_SHARED_LIBADD)
+ PHP_ADD_EXTENSION_DEP(xsl, libxml)
+fi
diff --git a/ext/xsl/config.w32 b/ext/xsl/config.w32
new file mode 100644
index 0000000..1b3864d
--- /dev/null
+++ b/ext/xsl/config.w32
@@ -0,0 +1,49 @@
+// $Id$
+// vim: ft=javascript
+
+ARG_WITH("xsl", "xsl support", "no");
+
+if (PHP_XSL != "no") {
+ if (PHP_DOM == "yes" && PHP_LIBXML == "yes"
+ && ADD_EXTENSION_DEP('xsl', 'libxml')
+ && ADD_EXTENSION_DEP('xsl', 'dom')) {
+ var ext_xsl_lib_found = false;
+ var ext_exslt_lib_found = false;
+
+ if (CHECK_LIB("libxslt_a.lib", "xsl", PHP_XSL)) {
+ ext_xsl_lib_found = true;
+ ADD_FLAG("CFLAGS_XSL", "/D LIBXSLT_STATIC ");
+ if (CHECK_LIB("libexslt_a.lib", "xsl", PHP_XSL)) {
+ ADD_FLAG("CFLAGS_XSL", "/D LIBEXSLT_STATIC ");
+ ext_exslt_lib_found = true;
+ }
+ } else if (CHECK_LIB("libxslt.lib", "xsl", PHP_XSL)) {
+ ext_xsl_lib_found = true;
+ if (CHECK_LIB("libexslt.lib", "xsl", PHP_XSL)) {
+ ext_exslt_lib_found = true;
+ }
+ }
+
+ if (ext_xsl_lib_found && CHECK_HEADER_ADD_INCLUDE("libxslt\\xslt.h", "CFLAGS_XSL")) {
+ if (ext_exslt_lib_found) {
+ if (CHECK_HEADER_ADD_INCLUDE("libexslt\\exslt.h", "CFLAGS_XSL")) {
+ AC_DEFINE("HAVE_XSL_EXSLT", 1, "");
+ }
+ }
+ EXTENSION("xsl", "php_xsl.c xsltprocessor.c", PHP_XSL_SHARED);
+ AC_DEFINE("HAVE_XSL", 1, "Define if xsl extension is enabled");
+ if (! PHP_XSL_SHARED) {
+ ADD_FLAG("CFLAGS_XSL", "/D DOM_EXPORTS /D LIBXML_STATIC");
+ } else {
+ if (PHP_DEBUG == "yes") {
+ ADD_FLAG("LDFLAGS_XSL", "/nodefaultlib:msvcrt");
+ }
+ }
+
+ } else {
+ WARNING("xsl not enabled; libraries and headers not found");
+ }
+ } else {
+ WARNING("xsl not enabled; DOM extension required");
+ }
+}
diff --git a/ext/xsl/php_xsl.c b/ext/xsl/php_xsl.c
new file mode 100644
index 0000000..6cbd91a
--- /dev/null
+++ b/ext/xsl/php_xsl.c
@@ -0,0 +1,339 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Christian Stocker <chregu@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#include "php_ini.h"
+#include "ext/standard/info.h"
+#include "php_xsl.h"
+
+zend_class_entry *xsl_xsltprocessor_class_entry;
+static zend_object_handlers xsl_object_handlers;
+
+/* {{{ xsl_functions[]
+ *
+ * Every user visible function must have an entry in xsl_functions[].
+ */
+const zend_function_entry xsl_functions[] = {
+ PHP_FE_END
+};
+/* }}} */
+
+static const zend_module_dep xsl_deps[] = {
+ ZEND_MOD_REQUIRED("libxml")
+ ZEND_MOD_END
+};
+
+/* {{{ xsl_module_entry
+ */
+zend_module_entry xsl_module_entry = {
+#if ZEND_MODULE_API_NO >= 20050617
+ STANDARD_MODULE_HEADER_EX, NULL,
+ xsl_deps,
+#elif ZEND_MODULE_API_NO >= 20010901
+ STANDARD_MODULE_HEADER,
+#endif
+ "xsl",
+ xsl_functions,
+ PHP_MINIT(xsl),
+ PHP_MSHUTDOWN(xsl),
+ PHP_RINIT(xsl), /* Replace with NULL if there's nothing to do at request start */
+ PHP_RSHUTDOWN(xsl), /* Replace with NULL if there's nothing to do at request end */
+ PHP_MINFO(xsl),
+#if ZEND_MODULE_API_NO >= 20010901
+ "0.1", /* Replace with version number for your extension */
+#endif
+ STANDARD_MODULE_PROPERTIES
+};
+/* }}} */
+
+#ifdef COMPILE_DL_XSL
+ZEND_GET_MODULE(xsl)
+#endif
+
+/* {{{ xsl_objects_free_storage */
+void xsl_objects_free_storage(void *object TSRMLS_DC)
+{
+ xsl_object *intern = (xsl_object *)object;
+
+ zend_object_std_dtor(&intern->std TSRMLS_CC);
+
+ zend_hash_destroy(intern->parameter);
+ FREE_HASHTABLE(intern->parameter);
+
+ zend_hash_destroy(intern->registered_phpfunctions);
+ FREE_HASHTABLE(intern->registered_phpfunctions);
+
+ if (intern->node_list) {
+ zend_hash_destroy(intern->node_list);
+ FREE_HASHTABLE(intern->node_list);
+ }
+
+ if (intern->doc) {
+ php_libxml_decrement_doc_ref(intern->doc TSRMLS_CC);
+ efree(intern->doc);
+ }
+
+ if (intern->ptr) {
+ /* free wrapper */
+ if (((xsltStylesheetPtr) intern->ptr)->_private != NULL) {
+ ((xsltStylesheetPtr) intern->ptr)->_private = NULL;
+ }
+
+ xsltFreeStylesheet((xsltStylesheetPtr) intern->ptr);
+ intern->ptr = NULL;
+ }
+ if (intern->profiling) {
+ efree(intern->profiling);
+ }
+ efree(object);
+}
+/* }}} */
+
+/* {{{ xsl_objects_new */
+zend_object_value xsl_objects_new(zend_class_entry *class_type TSRMLS_DC)
+{
+ zend_object_value retval;
+ xsl_object *intern;
+
+ intern = emalloc(sizeof(xsl_object));
+ intern->ptr = NULL;
+ intern->prop_handler = NULL;
+ intern->parameter = NULL;
+ intern->hasKeys = 0;
+ intern->registerPhpFunctions = 0;
+ intern->registered_phpfunctions = NULL;
+ intern->node_list = NULL;
+ intern->doc = NULL;
+ intern->profiling = NULL;
+ intern->securityPrefs = XSL_SECPREF_DEFAULT;
+ intern->securityPrefsSet = 0;
+
+ zend_object_std_init(&intern->std, class_type TSRMLS_CC);
+ object_properties_init(&intern->std, class_type);
+ ALLOC_HASHTABLE(intern->parameter);
+ zend_hash_init(intern->parameter, 0, NULL, ZVAL_PTR_DTOR, 0);
+ ALLOC_HASHTABLE(intern->registered_phpfunctions);
+ zend_hash_init(intern->registered_phpfunctions, 0, NULL, ZVAL_PTR_DTOR, 0);
+ retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t) xsl_objects_free_storage, NULL TSRMLS_CC);
+ intern->handle = retval.handle;
+ retval.handlers = &xsl_object_handlers;
+ return retval;
+}
+/* }}} */
+
+PHP_INI_BEGIN()
+/* Default is not allowing any write operations.
+ XSL_SECPREF_CREATE_DIRECTORY | XSL_SECPREF_WRITE_NETWORK | XSL_SECPREF_WRITE_FILE == 44
+*/
+PHP_INI_ENTRY("xsl.security_prefs", "44", PHP_INI_ALL, NULL)
+PHP_INI_END()
+
+/* {{{ PHP_MINIT_FUNCTION
+ */
+PHP_MINIT_FUNCTION(xsl)
+{
+
+ zend_class_entry ce;
+
+ memcpy(&xsl_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
+ xsl_object_handlers.clone_obj = NULL;
+
+ REGISTER_XSL_CLASS(ce, "XSLTProcessor", NULL, php_xsl_xsltprocessor_class_functions, xsl_xsltprocessor_class_entry);
+#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);
+ REGISTER_LONG_CONSTANT("XSL_CLONE_ALWAYS", 1, CONST_CS | CONST_PERSISTENT);
+
+ REGISTER_LONG_CONSTANT("XSL_SECPREF_NONE", XSL_SECPREF_NONE, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("XSL_SECPREF_READ_FILE", XSL_SECPREF_READ_FILE, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("XSL_SECPREF_WRITE_FILE", XSL_SECPREF_WRITE_FILE, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("XSL_SECPREF_CREATE_DIRECTORY", XSL_SECPREF_CREATE_DIRECTORY, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("XSL_SECPREF_READ_NETWORK", XSL_SECPREF_READ_NETWORK, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("XSL_SECPREF_WRITE_NETWORK", XSL_SECPREF_WRITE_NETWORK, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("XSL_SECPREF_DEFAULT", XSL_SECPREF_DEFAULT, CONST_CS | CONST_PERSISTENT);
+
+ REGISTER_LONG_CONSTANT("LIBXSLT_VERSION", LIBXSLT_VERSION, CONST_CS | CONST_PERSISTENT);
+ REGISTER_STRING_CONSTANT("LIBXSLT_DOTTED_VERSION", LIBXSLT_DOTTED_VERSION, CONST_CS | CONST_PERSISTENT);
+
+#if HAVE_XSL_EXSLT
+ REGISTER_LONG_CONSTANT("LIBEXSLT_VERSION", LIBEXSLT_VERSION, CONST_CS | CONST_PERSISTENT);
+ REGISTER_STRING_CONSTANT("LIBEXSLT_DOTTED_VERSION", LIBEXSLT_DOTTED_VERSION, CONST_CS | CONST_PERSISTENT);
+#endif
+
+ REGISTER_INI_ENTRIES();
+
+ return SUCCESS;
+}
+/* }}} */
+
+/* {{{ xsl_object_get_data */
+zval *xsl_object_get_data(void *obj)
+{
+ zval *dom_wrapper;
+ dom_wrapper = ((xsltStylesheetPtr) obj)->_private;
+ return dom_wrapper;
+}
+/* }}} */
+
+/* {{{ xsl_object_set_data */
+static void xsl_object_set_data(void *obj, zval *wrapper TSRMLS_DC)
+{
+ ((xsltStylesheetPtr) obj)->_private = wrapper;
+}
+/* }}} */
+
+/* {{{ php_xsl_set_object */
+void php_xsl_set_object(zval *wrapper, void *obj TSRMLS_DC)
+{
+ xsl_object *object;
+
+ object = (xsl_object *)zend_objects_get_address(wrapper TSRMLS_CC);
+ object->ptr = obj;
+ xsl_object_set_data(obj, wrapper TSRMLS_CC);
+}
+/* }}} */
+
+/* {{{ php_xsl_create_object */
+zval *php_xsl_create_object(xsltStylesheetPtr obj, int *found, zval *wrapper_in, zval *return_value TSRMLS_DC)
+{
+ zval *wrapper;
+ zend_class_entry *ce;
+
+ *found = 0;
+
+ if (!obj) {
+ if(!wrapper_in) {
+ ALLOC_ZVAL(wrapper);
+ } else {
+ wrapper = wrapper_in;
+ }
+ ZVAL_NULL(wrapper);
+ return wrapper;
+ }
+
+ if ((wrapper = (zval *) xsl_object_get_data((void *) obj))) {
+ zval_add_ref(&wrapper);
+ *found = 1;
+ return wrapper;
+ }
+
+ if(!wrapper_in) {
+ wrapper = return_value;
+ } else {
+ wrapper = wrapper_in;
+ }
+
+
+ ce = xsl_xsltprocessor_class_entry;
+
+ if(!wrapper_in) {
+ object_init_ex(wrapper, ce);
+ }
+ php_xsl_set_object(wrapper, (void *) obj TSRMLS_CC);
+ return (wrapper);
+}
+/* }}} */
+
+/* {{{ PHP_MSHUTDOWN_FUNCTION
+ */
+PHP_MSHUTDOWN_FUNCTION(xsl)
+{
+ xsltUnregisterExtModuleFunction ((const xmlChar *) "functionString",
+ (const xmlChar *) "http://php.net/xsl");
+ xsltUnregisterExtModuleFunction ((const xmlChar *) "function",
+ (const xmlChar *) "http://php.net/xsl");
+
+ xsltCleanupGlobals();
+
+ UNREGISTER_INI_ENTRIES();
+
+ return SUCCESS;
+}
+/* }}} */
+
+/* {{{ PHP_RINIT_FUNCTION
+ */
+PHP_RINIT_FUNCTION(xsl)
+{
+ xsltSetGenericErrorFunc(NULL, php_libxml_error_handler);
+ return SUCCESS;
+}
+/* }}} */
+
+/* {{{ PHP_RSHUTDOWN_FUNCTION
+ */
+PHP_RSHUTDOWN_FUNCTION(xsl)
+{
+ xsltSetGenericErrorFunc(NULL, NULL);
+ return SUCCESS;
+}
+/* }}} */
+
+/* {{{ PHP_MINFO_FUNCTION
+ */
+PHP_MINFO_FUNCTION(xsl)
+{
+ php_info_print_table_start();
+ {
+ char buffer[128];
+ int major, minor, subminor;
+
+ php_info_print_table_row(2, "XSL", "enabled");
+ major = xsltLibxsltVersion/10000;
+ minor = (xsltLibxsltVersion - major * 10000) / 100;
+ subminor = (xsltLibxsltVersion - major * 10000 - minor * 100);
+ snprintf(buffer, 128, "%d.%d.%d", major, minor, subminor);
+ php_info_print_table_row(2, "libxslt Version", buffer);
+ major = xsltLibxmlVersion/10000;
+ minor = (xsltLibxmlVersion - major * 10000) / 100;
+ subminor = (xsltLibxmlVersion - major * 10000 - minor * 100);
+ snprintf(buffer, 128, "%d.%d.%d", major, minor, subminor);
+ php_info_print_table_row(2, "libxslt compiled against libxml Version", buffer);
+ }
+#if HAVE_XSL_EXSLT
+ php_info_print_table_row(2, "EXSLT", "enabled");
+ php_info_print_table_row(2, "libexslt Version", LIBEXSLT_DOTTED_VERSION);
+#endif
+ php_info_print_table_end();
+}
+/* }}} */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/ext/xsl/php_xsl.h b/ext/xsl/php_xsl.h
new file mode 100644
index 0000000..e1a792e
--- /dev/null
+++ b/ext/xsl/php_xsl.h
@@ -0,0 +1,135 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifndef PHP_XSL_H
+#define PHP_XSL_H
+
+extern zend_module_entry xsl_module_entry;
+#define phpext_xsl_ptr &xsl_module_entry
+
+#ifdef ZTS
+#include "TSRM.h"
+#endif
+
+#include <libxslt/xsltconfig.h>
+#include <libxslt/xsltInternals.h>
+#include <libxslt/xsltutils.h>
+#include <libxslt/transform.h>
+#include <libxslt/security.h>
+#if HAVE_XSL_EXSLT
+#include <libexslt/exslt.h>
+#include <libexslt/exsltconfig.h>
+#endif
+
+#include "../dom/xml_common.h"
+#include "xsl_fe.h"
+
+#include <libxslt/extensions.h>
+#include <libxml/xpathInternals.h>
+
+#define XSL_SECPREF_NONE 0
+#define XSL_SECPREF_READ_FILE 2
+#define XSL_SECPREF_WRITE_FILE 4
+#define XSL_SECPREF_CREATE_DIRECTORY 8
+#define XSL_SECPREF_READ_NETWORK 16
+#define XSL_SECPREF_WRITE_NETWORK 32
+/* Default == disable all write access == XSL_SECPREF_WRITE_NETWORK | XSL_SECPREF_CREATE_DIRECTORY | XSL_SECPREF_WRITE_FILE */
+#define XSL_SECPREF_DEFAULT 44
+
+typedef struct _xsl_object {
+ zend_object std;
+ void *ptr;
+ HashTable *prop_handler;
+ zend_object_handle handle;
+ HashTable *parameter;
+ int hasKeys;
+ int registerPhpFunctions;
+ HashTable *registered_phpfunctions;
+ HashTable *node_list;
+ php_libxml_node_object *doc;
+ char *profiling;
+ long securityPrefs;
+ int securityPrefsSet;
+} xsl_object;
+
+void php_xsl_set_object(zval *wrapper, void *obj TSRMLS_DC);
+void xsl_objects_free_storage(void *object TSRMLS_DC);
+zval *php_xsl_create_object(xsltStylesheetPtr obj, int *found, zval *wrapper_in, zval *return_value TSRMLS_DC);
+
+void xsl_ext_function_string_php(xmlXPathParserContextPtr ctxt, int nargs);
+void xsl_ext_function_object_php(xmlXPathParserContextPtr ctxt, int nargs);
+
+#define REGISTER_XSL_CLASS(ce, name, parent_ce, funcs, entry) \
+INIT_CLASS_ENTRY(ce, name, funcs); \
+ce.create_object = xsl_objects_new; \
+entry = zend_register_internal_class_ex(&ce, parent_ce, NULL TSRMLS_CC);
+
+#define XSL_DOMOBJ_NEW(zval, obj, ret) \
+ if (NULL == (zval = php_xsl_create_object(obj, ret, zval, return_value TSRMLS_CC))) { \
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object"); \
+ RETURN_FALSE; \
+ }
+
+
+
+PHP_MINIT_FUNCTION(xsl);
+PHP_MSHUTDOWN_FUNCTION(xsl);
+PHP_RINIT_FUNCTION(xsl);
+PHP_RSHUTDOWN_FUNCTION(xsl);
+PHP_MINFO_FUNCTION(xsl);
+
+
+/*
+ Declare any global variables you may need between the BEGIN
+ and END macros here:
+
+ZEND_BEGIN_MODULE_GLOBALS(xsl)
+ long global_value;
+ char *global_string;
+ZEND_END_MODULE_GLOBALS(xsl)
+*/
+
+/* In every utility function you add that needs to use variables
+ in php_xsl_globals, call TSRM_FETCH(); after declaring other
+ variables used by that function, or better yet, pass in TSRMLS_CC
+ after the last function argument and declare your utility function
+ with TSRMLS_DC after the last declared argument. Always refer to
+ the globals in your function as XSL_G(variable). You are
+ encouraged to rename these macros something shorter, see
+ examples in any other php module directory.
+*/
+
+#ifdef ZTS
+#define XSL_G(v) TSRMG(xsl_globals_id, zend_xsl_globals *, v)
+#else
+#define XSL_G(v) (xsl_globals.v)
+#endif
+
+#endif /* PHP_XSL_H */
+
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/ext/xsl/tests/area_list.xsl b/ext/xsl/tests/area_list.xsl
new file mode 100644
index 0000000..e0c88c6
--- /dev/null
+++ b/ext/xsl/tests/area_list.xsl
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+ <xsl:output method="text" encoding="UTF-8"/>
+
+ <xsl:key name="area" match="ROW" use="substring(translate(AREA_NAME, '&quot;', ''), 1, 1)"/>
+<xsl:template match="*">
+ HERE
+</xsl:template>
+</xsl:stylesheet>
diff --git a/ext/xsl/tests/area_name.xml b/ext/xsl/tests/area_name.xml
new file mode 100644
index 0000000..76cea58
--- /dev/null
+++ b/ext/xsl/tests/area_name.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<AREA_NAME>
+ <ROW>
+ <AREA_CODE>13</AREA_CODE>
+ <AREA_NAME>&quot;Автово&quot; м.</AREA_NAME>
+ <AREA_NAME_ENG>m.&quot;Avtovo&quot;</AREA_NAME_ENG>
+ </ROW>
+</AREA_NAME>
+
+
+
diff --git a/ext/xsl/tests/bug26384.phpt b/ext/xsl/tests/bug26384.phpt
new file mode 100644
index 0000000..e415ec9
--- /dev/null
+++ b/ext/xsl/tests/bug26384.phpt
@@ -0,0 +1,33 @@
+--TEST--
+Bug #26384 (domxslt->process causes segfault with xsl:key)
+--SKIPIF--
+<?php require_once dirname(__FILE__) .'/skipif.inc'; ?>
+--FILE--
+<?php
+$dom = new domDocument;
+$dom->load(dirname(__FILE__)."/area_name.xml");
+if(!$dom) {
+ echo "Error while parsing the document\n";
+ exit;
+}
+$xsl = new domDocument;
+$xsl->load(dirname(__FILE__)."/area_list.xsl");
+if(!$xsl) {
+ echo "Error while parsing the document\n";
+ exit;
+}
+$proc = new xsltprocessor;
+if(!$proc) {
+ echo "Error while making xsltprocessor object\n";
+ exit;
+}
+
+$proc->importStylesheet($xsl);
+print $proc->transformToXml($dom);
+
+//this segfaulted before
+print $dom->documentElement->firstChild->nextSibling->nodeName;
+
+--EXPECT--
+HERE
+ROW
diff --git a/ext/xsl/tests/bug33853.phpt b/ext/xsl/tests/bug33853.phpt
new file mode 100644
index 0000000..bcf30f6
--- /dev/null
+++ b/ext/xsl/tests/bug33853.phpt
@@ -0,0 +1,33 @@
+--TEST--
+Bug #33853 (php:function call __autoload with lowercase param)
+--SKIPIF--
+<?php if (!extension_loaded('xsl')) die('skip xsl not loaded'); ?>
+--FILE--
+<?php
+
+function __autoload($className) {
+ var_dump($className);
+ exit();
+}
+
+$xsl = new DomDocument();
+$xsl->loadXML('<?xml version="1.0" encoding="iso-8859-1" ?>
+<xsl:stylesheet version="1.0"
+xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+xmlns:php="http://php.net/xsl">
+<xsl:template match="/">
+<xsl:value-of select="php:function(\'TeSt::dateLang\')" />
+</xsl:template>
+</xsl:stylesheet>');
+$inputdom = new DomDocument();
+$inputdom->loadXML('<?xml version="1.0" encoding="iso-8859-1" ?>
+<today></today>');
+
+$proc = new XsltProcessor();
+$proc->registerPhpFunctions();
+$xsl = $proc->importStylesheet($xsl);
+$newdom = $proc->transformToDoc($inputdom);
+?>
+===DONE===
+--EXPECT--
+string(4) "TeSt"
diff --git a/ext/xsl/tests/bug48221.phpt b/ext/xsl/tests/bug48221.phpt
new file mode 100644
index 0000000..2d08b3d
--- /dev/null
+++ b/ext/xsl/tests/bug48221.phpt
@@ -0,0 +1,17 @@
+--TEST--
+Bug #48221 (memory leak when passing invalid xslt parameter)
+--SKIPIF--
+<?php
+if (!extension_loaded('xsl')) die("skip Extension XSL is required\n");
+?>
+--FILE--
+<?php
+include('prepare.inc');
+$proc->importStylesheet($xsl);
+$proc->setParameter('', '', '"\'');
+$proc->transformToXml($dom);
+--EXPECTF--
+Warning: XSLTProcessor::transformToXml(): Cannot create XPath expression (string contains both quote and double-quotes) in %s on line %d
+--CREDITS--
+Christian Weiske, cweiske@php.net
+PHP Testfest Berlin 2009-05-09
diff --git a/ext/xsl/tests/bug54446.phpt b/ext/xsl/tests/bug54446.phpt
new file mode 100644
index 0000000..f00b118
--- /dev/null
+++ b/ext/xsl/tests/bug54446.phpt
@@ -0,0 +1,95 @@
+--TEST--
+Bug #54446 (Arbitrary file creation via libxslt 'output' extension)
+--SKIPIF--
+<?php
+if (!extension_loaded('xsl')) die("skip Extension XSL is required\n");
+?>
+--FILE--
+<?php
+include("prepare.inc");
+
+$outputfile = dirname(__FILE__)."/bug54446test.txt";
+if (file_exists($outputfile)) {
+ unlink($outputfile);
+}
+
+$sXsl = <<<EOT
+<xsl:stylesheet version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:sax="http://icl.com/saxon"
+ extension-element-prefixes="sax">
+
+ <xsl:template match="/">
+ <sax:output href="$outputfile" method="text">
+ <xsl:value-of select="'0wn3d via PHP and libxslt ...'"/>
+ </sax:output>
+ </xsl:template>
+
+</xsl:stylesheet>
+EOT;
+
+$xsl->loadXML( $sXsl );
+
+# START XSLT
+$proc->importStylesheet( $xsl );
+
+# TRASNFORM & PRINT
+print $proc->transformToXML( $dom );
+
+
+if (file_exists($outputfile)) {
+ print "$outputfile exists, but shouldn't!\n";
+} else {
+ print "OK, no file created\n";
+}
+
+#SET NO SECURITY PREFS
+$proc->setSecurityPrefs(XSL_SECPREF_NONE);
+
+# TRASNFORM & PRINT
+print $proc->transformToXML( $dom );
+
+
+if (file_exists($outputfile)) {
+ print "OK, file exists\n";
+} else {
+ print "$outputfile doesn't exist, but should!\n";
+}
+
+unlink($outputfile);
+
+#SET SECURITY PREFS AGAIN
+$proc->setSecurityPrefs( XSL_SECPREF_WRITE_FILE | XSL_SECPREF_WRITE_NETWORK | XSL_SECPREF_CREATE_DIRECTORY);
+
+# TRASNFORM & PRINT
+print $proc->transformToXML( $dom );
+
+if (file_exists($outputfile)) {
+ print "$outputfile exists, but shouldn't!\n";
+} else {
+ print "OK, no file created\n";
+}
+
+
+--EXPECTF--
+Warning: XSLTProcessor::transformToXml(): runtime error: file %s line %s element output in %s on line %d
+
+Warning: XSLTProcessor::transformToXml(): File write for %s/bug54446test.txt refused in %s on line %s
+
+Warning: XSLTProcessor::transformToXml(): runtime error: file %s line %d element output in %s on line %d
+
+Warning: XSLTProcessor::transformToXml(): xsltDocumentElem: write rights for %s/bug54446test.txt denied in %s on line %d
+OK, no file created
+OK, file exists
+
+Warning: XSLTProcessor::transformToXml(): runtime error: file %s line %s element output in %s on line %d
+
+Warning: XSLTProcessor::transformToXml(): File write for %s/bug54446test.txt refused in %s on line %s
+
+Warning: XSLTProcessor::transformToXml(): runtime error: file %s line %d element output in %s on line %d
+
+Warning: XSLTProcessor::transformToXml(): xsltDocumentElem: write rights for %s/bug54446test.txt denied in %s on line %d
+OK, no file created
+--CREDITS--
+Christian Stocker, chregu@php.net
+
diff --git a/ext/xsl/tests/bug54446_with_ini.phpt b/ext/xsl/tests/bug54446_with_ini.phpt
new file mode 100644
index 0000000..fbe0365
--- /dev/null
+++ b/ext/xsl/tests/bug54446_with_ini.phpt
@@ -0,0 +1,135 @@
+--TEST--
+Bug #54446 (Arbitrary file creation via libxslt 'output' extension with php.ini setting)
+--SKIPIF--
+<?php
+if (!extension_loaded('xsl')) die("skip Extension XSL is required\n");
+?>
+--FILE--
+<?php
+include("prepare.inc");
+
+$outputfile = dirname(__FILE__)."/bug54446test.txt";
+if (file_exists($outputfile)) {
+ unlink($outputfile);
+}
+
+$sXsl = <<<EOT
+<xsl:stylesheet version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:sax="http://icl.com/saxon"
+ extension-element-prefixes="sax">
+
+ <xsl:template match="/">
+ <sax:output href="$outputfile" method="text">
+ <xsl:value-of select="'0wn3d via PHP and libxslt ...'"/>
+ </sax:output>
+ </xsl:template>
+
+</xsl:stylesheet>
+EOT;
+
+$xsl->loadXML( $sXsl );
+
+# START XSLT
+$proc->importStylesheet( $xsl );
+
+# TRASNFORM & PRINT
+print $proc->transformToXML( $dom );
+
+
+if (file_exists($outputfile)) {
+ print "$outputfile exists, but shouldn't!\n";
+} else {
+ print "OK, no file created\n";
+}
+
+#SET NO SECURITY PREFS
+ini_set("xsl.security_prefs", XSL_SECPREF_NONE);
+
+# TRASNFORM & PRINT
+print $proc->transformToXML( $dom );
+
+
+if (file_exists($outputfile)) {
+ print "OK, file exists\n";
+} else {
+ print "$outputfile doesn't exist, but should!\n";
+}
+
+unlink($outputfile);
+
+#SET SECURITY PREFS AGAIN
+ini_set("xsl.security_prefs", XSL_SECPREF_WRITE_FILE | XSL_SECPREF_WRITE_NETWORK | XSL_SECPREF_CREATE_DIRECTORY);
+
+# TRASNFORM & PRINT
+print $proc->transformToXML( $dom );
+
+if (file_exists($outputfile)) {
+ print "$outputfile exists, but shouldn't!\n";
+} else {
+ print "OK, no file created\n";
+}
+
+#SET NO SECURITY PREFS with ini, but set them with ->setSecurityPrefs
+ini_set("xsl.security_prefs", XSL_SECPREF_NONE);
+$proc->setSecurityPrefs( XSL_SECPREF_WRITE_FILE | XSL_SECPREF_WRITE_NETWORK | XSL_SECPREF_CREATE_DIRECTORY);
+
+print $proc->transformToXML( $dom );
+if (file_exists($outputfile)) {
+ print "$outputfile exists, but shouldn't!\n";
+} else {
+ print "OK, no file created\n";
+}
+
+#don't throw a warning if both ini and through-the-method have the same value
+$proc->setSecurityPrefs(XSL_SECPREF_NONE);
+
+print $proc->transformToXML( $dom );
+
+if (file_exists($outputfile)) {
+ print "OK, file exists\n";
+} else {
+ print "$outputfile doesn't exist, but should!\n";
+}
+unlink($outputfile);
+
+
+
+--EXPECTF--
+Warning: XSLTProcessor::transformToXml(): runtime error: file %s line %s element output in %s on line %d
+
+Warning: XSLTProcessor::transformToXml(): File write for %s/bug54446test.txt refused in %s on line %s
+
+Warning: XSLTProcessor::transformToXml(): runtime error: file %s line %d element output in %s on line %d
+
+Warning: XSLTProcessor::transformToXml(): xsltDocumentElem: write rights for %s/bug54446test.txt denied in %s on line %d
+OK, no file created
+
+Deprecated: XSLTProcessor::transformToXml(): The xsl.security_prefs php.ini option is deprecated; use XsltProcessor->setSecurityPrefs() instead in %s on line %d
+OK, file exists
+
+Warning: XSLTProcessor::transformToXml(): runtime error: file %s line %s element output in %s on line %d
+
+Warning: XSLTProcessor::transformToXml(): File write for %s/bug54446test.txt refused in %s on line %s
+
+Warning: XSLTProcessor::transformToXml(): runtime error: file %s line %d element output in %s on line %d
+
+Warning: XSLTProcessor::transformToXml(): xsltDocumentElem: write rights for %s/bug54446test.txt denied in %s on line %d
+OK, no file created
+
+Deprecated: XSLTProcessor::transformToXml(): The xsl.security_prefs php.ini option is deprecated; use XsltProcessor->setSecurityPrefs() instead in %s on line %d
+
+Notice: XSLTProcessor::transformToXml(): The xsl.security_prefs php.ini was not used, since the XsltProcessor->setSecurityPrefs() method was used in %s on line %d
+
+Warning: XSLTProcessor::transformToXml(): runtime error: file %s line %s element output in %s on line %d
+
+Warning: XSLTProcessor::transformToXml(): File write for %s/bug54446test.txt refused in %s on line %s
+
+Warning: XSLTProcessor::transformToXml(): runtime error: file %s line %d element output in %s on line %d
+
+Warning: XSLTProcessor::transformToXml(): xsltDocumentElem: write rights for %s/bug54446test.txt denied in %s on line %d
+OK, no file created
+OK, file exists
+--CREDITS--
+Christian Stocker, chregu@php.net
+
diff --git a/ext/xsl/tests/documentxpath.xsl b/ext/xsl/tests/documentxpath.xsl
new file mode 100644
index 0000000..0e5c5c1
--- /dev/null
+++ b/ext/xsl/tests/documentxpath.xsl
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!-- $Id: documentxpath.xsl,v 1.1 2003-10-27 15:12:20 chregu Exp $ -->
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
+ <xsl:output method="xml" encoding="iso-8859-1" indent="no"/>
+<xsl:template match="/">
+
+<xsl:value-of select="document('compress.zlib://ext/xsl/tests/xslt.xsl.gz')/xsl:stylesheet/xsl:param/@name"/>
+</xsl:template>
+
+ </xsl:stylesheet>
diff --git a/ext/xsl/tests/exslt.xml b/ext/xsl/tests/exslt.xml
new file mode 100644
index 0000000..562e08e
--- /dev/null
+++ b/ext/xsl/tests/exslt.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<page>
+ <!-- valid xs:date -->
+ <date date="0001-12-31Z"/>
+ <date date="3000-01-31"/>
+ <date date="2000-02-29"/>
+ <date date="9990001-12-31Z"/>
+ <date date="-0004-02-29"/>
+ <date date="1999-01-02"/>
+ <date date="1999-01-03"/>
+ <date date="2004-01-01"/>
+ <date date="2006-01-01"/>
+ <date date="2007-12-31"/>
+</page>
+
diff --git a/ext/xsl/tests/exslt.xsl b/ext/xsl/tests/exslt.xsl
new file mode 100644
index 0000000..8f0baef
--- /dev/null
+++ b/ext/xsl/tests/exslt.xsl
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<xsl:stylesheet version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:date="http://exslt.org/dates-and-times"
+ extension-element-prefixes="date">
+
+<xsl:output method="text"/>
+
+<xsl:template match="date">
+ Test Date : <xsl:value-of select="@date"/>
+ <!-- dateTime, date, gYearMonth or gYear; else NaN -->
+ year : <xsl:value-of select="date:year(@date)"/>
+ <!-- dateTime, date, gYearMonth or gYear; else NaN -->
+ leap-year : <xsl:value-of select="date:leap-year(@date)"/>
+ <!-- dateTime, date, gYearMonth, gMonth or gMonthDay; else NaN -->
+ month-in-year : <xsl:value-of select="date:month-in-year(@date)"/>
+ <!-- dateTime, date, gYearMonth or gMonth; else '' -->
+ month-name : <xsl:value-of select="date:month-name(@date)"/>
+ <!-- dateTime, date, gYearMonth or gMonth; else '' -->
+ month-abbreviation : <xsl:value-of select="date:month-abbreviation(@date)"/>
+ <!-- dateTime or date; else NaN -->
+ week-in-year : <xsl:value-of select="date:week-in-year(@date)"/>
+ <!-- dateTime, date; else NaN -->
+ day-in-year : <xsl:value-of select="date:day-in-year(@date)"/>
+ <!-- dateTime, date, gMonthDay or gDay; else NaN -->
+ day-in-month : <xsl:value-of select="date:day-in-month(@date)"/>
+ <!-- dateTime, date; else NaN -->
+ day-of-week-in-month : <xsl:value-of select="date:day-of-week-in-month(@date)"/>
+ <!-- dateTime, date; else NaN -->
+ day-in-week : <xsl:value-of select="date:day-in-week(@date)"/>
+ <!-- dateTime or date; else NaN -->
+ day-name : <xsl:value-of select="date:day-name(@date)"/>
+ <!-- dateTime or date; else NaN -->
+ day-abbreviation : <xsl:value-of select="date:day-abbreviation(@date)"/>
+ <!-- dateTime or time; else '' -->
+ time : <xsl:value-of select="date:time(@date)"/>
+ <!-- dateTime or time; else NaN -->
+ hour-in-day : <xsl:value-of select="date:hour-in-day(@date)"/>
+ <!-- dateTime or time; else NaN -->
+ minute-in-hour : <xsl:value-of select="date:minute-in-hour(@date)"/>
+ <!-- dateTime or time; else NaN -->
+ second-in-minute : <xsl:value-of select="date:second-in-minute(@date)"/>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/ext/xsl/tests/phpfunc-nostring.xsl b/ext/xsl/tests/phpfunc-nostring.xsl
new file mode 100644
index 0000000..f278faf
--- /dev/null
+++ b/ext/xsl/tests/phpfunc-nostring.xsl
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!-- $Id: phpfunc-nostring.xsl,v 1.1.2.2 2009-05-23 14:49:55 felipe Exp $ -->
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:php="http://php.net/xsl"
+>
+ <xsl:output method="text" encoding="iso-8859-1" indent="no"/>
+ <xsl:template match="/">
+ <xsl:value-of select="php:function(123,'this is an example')"/>
+ </xsl:template>
+</xsl:stylesheet>
diff --git a/ext/xsl/tests/phpfunc-undef.xsl b/ext/xsl/tests/phpfunc-undef.xsl
new file mode 100644
index 0000000..e05b03b
--- /dev/null
+++ b/ext/xsl/tests/phpfunc-undef.xsl
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!-- $Id: phpfunc-undef.xsl,v 1.1.2.2 2009-05-23 14:49:55 felipe Exp $ -->
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:php="http://php.net/xsl"
+>
+ <xsl:output method="text" encoding="iso-8859-1" indent="no"/>
+ <xsl:template match="/">
+ <xsl:value-of select="php:function('undefinedfunc','this is an example')"/>
+ </xsl:template>
+</xsl:stylesheet>
diff --git a/ext/xsl/tests/phpfunc.xsl b/ext/xsl/tests/phpfunc.xsl
new file mode 100644
index 0000000..3031ab7
--- /dev/null
+++ b/ext/xsl/tests/phpfunc.xsl
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!-- $Id: phpfunc.xsl,v 1.1.2.2 2009-05-23 14:49:55 felipe Exp $ -->
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:php="http://php.net/xsl"
+>
+ <xsl:output method="text" encoding="iso-8859-1" indent="no"/>
+<!-- <xsl:param name="foo" select="'bar'"/>-->
+ <xsl:template match="/">
+ <xsl:value-of select="php:function('ucwords','this is an example')"/>
+ </xsl:template>
+</xsl:stylesheet>
diff --git a/ext/xsl/tests/prepare.inc b/ext/xsl/tests/prepare.inc
new file mode 100644
index 0000000..bd5bbee
--- /dev/null
+++ b/ext/xsl/tests/prepare.inc
@@ -0,0 +1,20 @@
+<?php
+$dom = new domDocument;
+$dom->load(dirname(__FILE__)."/xslt.xml");
+if(!$dom) {
+ echo "Error while parsing the document\n";
+ exit;
+}
+$xsl = new domDocument;
+$xsl->load(dirname(__FILE__)."/xslt.xsl");
+if(!$xsl) {
+ echo "Error while parsing the document\n";
+ exit;
+}
+$proc = new xsltprocessor;
+if(!$proc) {
+ echo "Error while making xsltprocessor object\n";
+ exit;
+}
+
+?>
diff --git a/ext/xsl/tests/skipif.inc b/ext/xsl/tests/skipif.inc
new file mode 100644
index 0000000..0ef7372
--- /dev/null
+++ b/ext/xsl/tests/skipif.inc
@@ -0,0 +1 @@
+<?php if (!extension_loaded('xsl')) die('skip xsl extension not available');?>
diff --git a/ext/xsl/tests/streamsinclude.xsl b/ext/xsl/tests/streamsinclude.xsl
new file mode 100644
index 0000000..6f8bc40
--- /dev/null
+++ b/ext/xsl/tests/streamsinclude.xsl
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!-- $Id: streamsinclude.xsl,v 1.1 2003-10-27 15:12:20 chregu Exp $ -->
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
+ <xsl:output method="xml" encoding="iso-8859-1" indent="no"/>
+ <xsl:include href="compress.zlib://xslt.xsl.gz"/>
+</xsl:stylesheet>
diff --git a/ext/xsl/tests/xsl-phpinfo.phpt b/ext/xsl/tests/xsl-phpinfo.phpt
new file mode 100644
index 0000000..83e6729
--- /dev/null
+++ b/ext/xsl/tests/xsl-phpinfo.phpt
@@ -0,0 +1,18 @@
+--TEST--
+Test phpinfo() displays xsl info
+--SKIPIF--
+<?php
+ if (!extension_loaded("xsl")) {
+ die("SKIP extension gettext not loaded\n");
+ }
+?>
+--FILE--
+<?php
+phpinfo();
+?>
+--EXPECTF--
+%a
+libxslt compiled against libxml Version%a
+--CREDITS--
+Christian Weiske, cweiske@php.net
+PHP Testfest Berlin 2009-05-09
diff --git a/ext/xsl/tests/xslt.xml b/ext/xsl/tests/xslt.xml
new file mode 100644
index 0000000..b0e9506
--- /dev/null
+++ b/ext/xsl/tests/xslt.xml
@@ -0,0 +1,28 @@
+<?xml version='1.0' encoding="iso-8859-1" ?>
+<chapter language="en">
+ <title language="en">Title</title>
+ <para language="ge">
+
+<!-- comment -->
+ <informaltable>
+ <tgroup cols="3">
+ <tbody>
+ <row>
+ <entry>a1</entry>
+ <entry morerows="1">b1</entry>
+ <entry>c1</entry>
+ </row>
+ <row>
+ <entry>a2</entry>
+ <entry>c2</entry>
+ </row>
+ <row>
+ <entry>3</entry>
+ <entry>b3</entry>
+ <entry>c3</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </para>
+</chapter>
diff --git a/ext/xsl/tests/xslt.xsl b/ext/xsl/tests/xslt.xsl
new file mode 100644
index 0000000..8331ccc
--- /dev/null
+++ b/ext/xsl/tests/xslt.xsl
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!-- $Id: xslt.xsl,v 1.2 2003-11-29 13:01:19 chregu Exp $ -->
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
+
+ <xsl:output method="xml" encoding="iso-8859-1" indent="no"/>
+ <xsl:param name="foo" select="'bar'"/>
+ <xsl:template match="/">
+ <html>
+ <body>
+ <xsl:value-of select="$foo"/><xsl:text>
+</xsl:text>
+ <xsl:apply-templates select="/chapter/para/informaltable/tgroup/tbody/row"/>
+ </body>
+ </html>
+ </xsl:template>
+
+ <xsl:template match="row">
+ <xsl:for-each select="entry">
+ <xsl:value-of select="."/>
+ <xsl:text> </xsl:text>
+ </xsl:for-each>
+ <br/> <xsl:text>
+</xsl:text>
+
+ </xsl:template>
+</xsl:stylesheet>
diff --git a/ext/xsl/tests/xslt.xsl.gz b/ext/xsl/tests/xslt.xsl.gz
new file mode 100644
index 0000000..910bb63
--- /dev/null
+++ b/ext/xsl/tests/xslt.xsl.gz
Binary files differ
diff --git a/ext/xsl/tests/xslt001.phpt b/ext/xsl/tests/xslt001.phpt
new file mode 100644
index 0000000..ec5538a
--- /dev/null
+++ b/ext/xsl/tests/xslt001.phpt
@@ -0,0 +1,22 @@
+--TEST--
+Test 1: Transform To XML String
+--SKIPIF--
+<?php require_once dirname(__FILE__) .'/skipif.inc'; ?>
+--FILE--
+<?php
+echo "Test 1: Transform To XML String";
+include("prepare.inc");
+$proc->importStylesheet($xsl);
+print "\n";
+print $proc->transformToXml($dom);
+print "\n";
+
+
+--EXPECT--
+Test 1: Transform To XML String
+<?xml version="1.0" encoding="iso-8859-1"?>
+<html><body>bar
+a1 b1 c1 <br/>
+a2 c2 <br/>
+3 b3 c3 <br/>
+</body></html>
diff --git a/ext/xsl/tests/xslt002.phpt b/ext/xsl/tests/xslt002.phpt
new file mode 100644
index 0000000..5ce2eb9
--- /dev/null
+++ b/ext/xsl/tests/xslt002.phpt
@@ -0,0 +1,29 @@
+--TEST--
+Test 2: Transform To HTML String
+--SKIPIF--
+<?php require_once dirname(__FILE__) .'/skipif.inc'; ?>
+--FILE--
+<?php
+echo "Test 2: Transform To HTML String";
+include("prepare.inc");
+// changing output method to html
+$xp = new domxpath($xsl);
+$res = $xp->query("/xsl:stylesheet/xsl:output/@method");
+if ($res->length != 1) {
+ print "No or more than one xsl:output/@method found";
+ exit;
+}
+$res->item(0)->value = "html";
+$proc->importStylesheet($xsl);
+print "\n";
+print $proc->transformToXml($dom);
+print "\n";
+
+
+--EXPECT--
+Test 2: Transform To HTML String
+<html><body>bar
+a1 b1 c1 <br>
+a2 c2 <br>
+3 b3 c3 <br>
+</body></html>
diff --git a/ext/xsl/tests/xslt003.phpt b/ext/xsl/tests/xslt003.phpt
new file mode 100644
index 0000000..60a8427
--- /dev/null
+++ b/ext/xsl/tests/xslt003.phpt
@@ -0,0 +1,23 @@
+--TEST--
+Test 3: Using Parameters
+--SKIPIF--
+<?php require_once dirname(__FILE__) .'/skipif.inc'; ?>
+--FILE--
+<?php
+echo "Test 3: Using Parameters";
+include("prepare.inc");
+$proc->importStylesheet($xsl);
+$proc->setParameter( "", "foo","hello world");
+print "\n";
+print $proc->transformToXml($dom);
+print "\n";
+
+
+--EXPECT--
+Test 3: Using Parameters
+<?xml version="1.0" encoding="iso-8859-1"?>
+<html><body>hello world
+a1 b1 c1 <br/>
+a2 c2 <br/>
+3 b3 c3 <br/>
+</body></html>
diff --git a/ext/xsl/tests/xslt004.phpt b/ext/xsl/tests/xslt004.phpt
new file mode 100644
index 0000000..e543232
--- /dev/null
+++ b/ext/xsl/tests/xslt004.phpt
@@ -0,0 +1,29 @@
+--TEST--
+Test 4: Checking UTF8 Output
+--SKIPIF--
+<?php require_once dirname(__FILE__) .'/skipif.inc'; ?>
+--FILE--
+<?php
+echo "Test 4: Checking UTF8 Output";
+include("prepare.inc");
+$xp = new domxpath($xsl);
+$res = $xp->query("/xsl:stylesheet/xsl:output/@encoding");
+if ($res->length != 1) {
+ print "No or more than one xsl:output/@encoding found";
+ exit;
+}
+$res->item(0)->value = "utf-8";
+$proc->importStylesheet($xsl);
+print "\n";
+print $proc->transformToXml($dom);
+print "\n";
+
+
+--EXPECT--
+Test 4: Checking UTF8 Output
+<?xml version="1.0" encoding="utf-8"?>
+<html><body>bar
+a1 b1 c1 <br/>
+a2 c2 <br/>
+ä3 b3 c3 <br/>
+</body></html>
diff --git a/ext/xsl/tests/xslt005.phpt b/ext/xsl/tests/xslt005.phpt
new file mode 100644
index 0000000..5492bf8
--- /dev/null
+++ b/ext/xsl/tests/xslt005.phpt
@@ -0,0 +1,31 @@
+--TEST--
+Test 5: Checking Indent
+--SKIPIF--
+<?php require_once dirname(__FILE__) .'/skipif.inc'; ?>
+--FILE--
+<?php
+echo "Test 5: Checking Indent";
+include("prepare.inc");
+$xp = new domxpath($xsl);
+$res = $xp->query("/xsl:stylesheet/xsl:output/@indent");
+if ($res->length != 1) {
+ print "No or more than one xsl:output/@indent found";
+ exit;
+}
+$res->item(0)->value = "yes";
+$proc->importStylesheet($xsl);
+print "\n";
+print $proc->transformToXml($dom);
+print "\n";
+
+
+--EXPECT--
+Test 5: Checking Indent
+<?xml version="1.0" encoding="iso-8859-1"?>
+<html>
+ <body>bar
+a1 b1 c1 <br/>
+a2 c2 <br/>
+3 b3 c3 <br/>
+</body>
+</html>
diff --git a/ext/xsl/tests/xslt006.phpt b/ext/xsl/tests/xslt006.phpt
new file mode 100644
index 0000000..2c0cfed
--- /dev/null
+++ b/ext/xsl/tests/xslt006.phpt
@@ -0,0 +1,23 @@
+--TEST--
+Test 6: Transform To Doc
+--SKIPIF--
+<?php require_once dirname(__FILE__) .'/skipif.inc'; ?>
+--FILE--
+<?php
+echo "Test 6: Transform To Doc";
+include("prepare.inc");
+$proc->importStylesheet($xsl);
+print "\n";
+$doc = $proc->transformToDoc($dom);
+print $doc->saveXML();
+print "\n";
+
+
+--EXPECT--
+Test 6: Transform To Doc
+<?xml version="1.0" encoding="iso-8859-1"?>
+<html><body>bar
+a1 b1 c1 <br/>
+a2 c2 <br/>
+3 b3 c3 <br/>
+</body></html>
diff --git a/ext/xsl/tests/xslt007.phpt b/ext/xsl/tests/xslt007.phpt
new file mode 100644
index 0000000..486560b
--- /dev/null
+++ b/ext/xsl/tests/xslt007.phpt
@@ -0,0 +1,24 @@
+--TEST--
+Test 7: Transform To Uri
+--SKIPIF--
+<?php require_once dirname(__FILE__) .'/skipif.inc'; ?>
+--FILE--
+<?php
+echo "Test 7: Transform To Uri";
+include("prepare.inc");
+$proc->importStylesheet($xsl);
+print "\n";
+$doc = $proc->transformToUri($dom, "file://".dirname(__FILE__)."/out.xml");
+print file_get_contents(dirname(__FILE__)."/out.xml");
+unlink(dirname(__FILE__)."/out.xml");
+print "\n";
+
+
+--EXPECT--
+Test 7: Transform To Uri
+<?xml version="1.0" encoding="iso-8859-1"?>
+<html><body>bar
+a1 b1 c1 <br/>
+a2 c2 <br/>
+3 b3 c3 <br/>
+</body></html>
diff --git a/ext/xsl/tests/xslt008.phpt b/ext/xsl/tests/xslt008.phpt
new file mode 100644
index 0000000..438a566
--- /dev/null
+++ b/ext/xsl/tests/xslt008.phpt
@@ -0,0 +1,31 @@
+--TEST--
+Test 8: Stream Wrapper Includes
+--SKIPIF--
+<?php
+ require_once dirname(__FILE__) .'/skipif.inc';
+ if (!extension_loaded('zlib')) die('skip zlib extension not available');
+?>
+--FILE--
+<?php
+echo "Test 8: Stream Wrapper Includes ";
+include("prepare.inc");
+$xsl = new domDocument;
+$xsl->load(dirname(__FILE__)."/streamsinclude.xsl");
+if(!$xsl) {
+ echo "Error while parsing the document\n";
+ exit;
+}
+chdir(dirname(__FILE__));
+$proc->importStylesheet($xsl);
+print "\n";
+print $proc->transformToXML($dom);
+
+
+--EXPECT--
+Test 8: Stream Wrapper Includes
+<?xml version="1.0" encoding="iso-8859-1"?>
+<html><body>bar
+a1 b1 c1 <br/>
+a2 c2 <br/>
+3 b3 c3 <br/>
+</body></html>
diff --git a/ext/xsl/tests/xslt009.phpt b/ext/xsl/tests/xslt009.phpt
new file mode 100644
index 0000000..67b0d67
--- /dev/null
+++ b/ext/xsl/tests/xslt009.phpt
@@ -0,0 +1,28 @@
+--TEST--
+Test 9: Stream Wrapper XPath-Document()
+--SKIPIF--
+<?php
+ require_once dirname(__FILE__) .'/skipif.inc';
+ if (!extension_loaded('zlib')) die('skip zlib extension not available');
+?>
+--FILE--
+<?php
+echo "Test 9: Stream Wrapper XPath-Document()";
+include("prepare.inc");
+
+$xsl = new domDocument;
+$xsl->load(dirname(__FILE__)."/documentxpath.xsl");
+if(!$xsl) {
+ echo "Error while parsing the document\n";
+ exit;
+}
+
+$proc->importStylesheet($xsl);
+print "\n";
+print $proc->transformToXML($dom);
+
+
+--EXPECT--
+Test 9: Stream Wrapper XPath-Document()
+<?xml version="1.0" encoding="iso-8859-1"?>
+foo
diff --git a/ext/xsl/tests/xslt010.phpt b/ext/xsl/tests/xslt010.phpt
new file mode 100644
index 0000000..96ef8c6
--- /dev/null
+++ b/ext/xsl/tests/xslt010.phpt
@@ -0,0 +1,206 @@
+--TEST--
+Test 10: EXSLT Support
+--SKIPIF--
+<?php
+require_once dirname(__FILE__) .'/skipif.inc';
+$proc = new xsltprocessor;
+if (!$proc->hasExsltSupport()) die('skip EXSLT support not available');
+if (LIBXSLT_VERSION < 10117) die('skip too old libxsl');
+?>
+--FILE--
+<?php
+echo "Test 10: EXSLT Support";
+
+$dom = new domDocument();
+ $dom->load(dirname(__FILE__)."/exslt.xsl");
+ $proc = new xsltprocessor;
+ $xsl = $proc->importStylesheet($dom);
+
+ $xml = new DomDocument();
+ $xml->load(dirname(__FILE__)."/exslt.xml");
+
+ print $proc->transformToXml($xml);
+--EXPECT--
+Test 10: EXSLT Support
+
+
+ Test Date : 0001-12-31Z
+ year : 1
+ leap-year : false
+ month-in-year : 12
+ month-name : December
+ month-abbreviation : Dec
+ week-in-year : 1
+ day-in-year : 365
+ day-in-month : 31
+ day-of-week-in-month : 5
+ day-in-week : 2
+ day-name : Monday
+ day-abbreviation : Mon
+ time :
+ hour-in-day : NaN
+ minute-in-hour : NaN
+ second-in-minute : NaN
+
+ Test Date : 3000-01-31
+ year : 3000
+ leap-year : false
+ month-in-year : 1
+ month-name : January
+ month-abbreviation : Jan
+ week-in-year : 5
+ day-in-year : 31
+ day-in-month : 31
+ day-of-week-in-month : 5
+ day-in-week : 6
+ day-name : Friday
+ day-abbreviation : Fri
+ time :
+ hour-in-day : NaN
+ minute-in-hour : NaN
+ second-in-minute : NaN
+
+ Test Date : 2000-02-29
+ year : 2000
+ leap-year : true
+ month-in-year : 2
+ month-name : February
+ month-abbreviation : Feb
+ week-in-year : 9
+ day-in-year : 60
+ day-in-month : 29
+ day-of-week-in-month : 5
+ day-in-week : 3
+ day-name : Tuesday
+ day-abbreviation : Tue
+ time :
+ hour-in-day : NaN
+ minute-in-hour : NaN
+ second-in-minute : NaN
+
+ Test Date : 9990001-12-31Z
+ year : 9990001
+ leap-year : false
+ month-in-year : 12
+ month-name : December
+ month-abbreviation : Dec
+ week-in-year : 1
+ day-in-year : 365
+ day-in-month : 31
+ day-of-week-in-month : 5
+ day-in-week : 2
+ day-name : Monday
+ day-abbreviation : Mon
+ time :
+ hour-in-day : NaN
+ minute-in-hour : NaN
+ second-in-minute : NaN
+
+ Test Date : -0004-02-29
+ year : -4
+ leap-year : true
+ month-in-year : 2
+ month-name : February
+ month-abbreviation : Feb
+ week-in-year : 9
+ day-in-year : 60
+ day-in-month : 29
+ day-of-week-in-month : 5
+ day-in-week : 1
+ day-name : Sunday
+ day-abbreviation : Sun
+ time :
+ hour-in-day : NaN
+ minute-in-hour : NaN
+ second-in-minute : NaN
+
+ Test Date : 1999-01-02
+ year : 1999
+ leap-year : false
+ month-in-year : 1
+ month-name : January
+ month-abbreviation : Jan
+ week-in-year : 53
+ day-in-year : 2
+ day-in-month : 2
+ day-of-week-in-month : 1
+ day-in-week : 7
+ day-name : Saturday
+ day-abbreviation : Sat
+ time :
+ hour-in-day : NaN
+ minute-in-hour : NaN
+ second-in-minute : NaN
+
+ Test Date : 1999-01-03
+ year : 1999
+ leap-year : false
+ month-in-year : 1
+ month-name : January
+ month-abbreviation : Jan
+ week-in-year : 53
+ day-in-year : 3
+ day-in-month : 3
+ day-of-week-in-month : 1
+ day-in-week : 1
+ day-name : Sunday
+ day-abbreviation : Sun
+ time :
+ hour-in-day : NaN
+ minute-in-hour : NaN
+ second-in-minute : NaN
+
+ Test Date : 2004-01-01
+ year : 2004
+ leap-year : true
+ month-in-year : 1
+ month-name : January
+ month-abbreviation : Jan
+ week-in-year : 1
+ day-in-year : 1
+ day-in-month : 1
+ day-of-week-in-month : 1
+ day-in-week : 5
+ day-name : Thursday
+ day-abbreviation : Thu
+ time :
+ hour-in-day : NaN
+ minute-in-hour : NaN
+ second-in-minute : NaN
+
+ Test Date : 2006-01-01
+ year : 2006
+ leap-year : false
+ month-in-year : 1
+ month-name : January
+ month-abbreviation : Jan
+ week-in-year : 52
+ day-in-year : 1
+ day-in-month : 1
+ day-of-week-in-month : 1
+ day-in-week : 1
+ day-name : Sunday
+ day-abbreviation : Sun
+ time :
+ hour-in-day : NaN
+ minute-in-hour : NaN
+ second-in-minute : NaN
+
+ Test Date : 2007-12-31
+ year : 2007
+ leap-year : false
+ month-in-year : 12
+ month-name : December
+ month-abbreviation : Dec
+ week-in-year : 1
+ day-in-year : 365
+ day-in-month : 31
+ day-of-week-in-month : 5
+ day-in-week : 2
+ day-name : Monday
+ day-abbreviation : Mon
+ time :
+ hour-in-day : NaN
+ minute-in-hour : NaN
+ second-in-minute : NaN
+
diff --git a/ext/xsl/tests/xslt011.phpt b/ext/xsl/tests/xslt011.phpt
new file mode 100644
index 0000000..efa2dd7
--- /dev/null
+++ b/ext/xsl/tests/xslt011.phpt
@@ -0,0 +1,59 @@
+--TEST--
+Test 11: php:function Support
+--SKIPIF--
+<?php require_once dirname(__FILE__) .'/skipif.inc'; ?>
+--FILE--
+<?php
+print "Test 11: php:function Support\n";
+ Class foo {
+ function foo() {}
+ function __toString() { return "not a DomNode object";}
+ }
+
+$dom = new domDocument();
+ $dom->load(dirname(__FILE__)."/xslt011.xsl");
+ $proc = new xsltprocessor;
+ $xsl = $proc->importStylesheet($dom);
+
+ $xml = new DomDocument();
+ $xml->load(dirname(__FILE__)."/xslt011.xml");
+ $proc->registerPHPFunctions();
+ print $proc->transformToXml($xml);
+
+ function foobar($id, $secondArg = "" ) {
+ if (is_array($id)) {
+ return $id[0]->value . " - " . $secondArg;
+ } else {
+ return $id . " - " . $secondArg;
+ }
+ }
+ function nodeSet($id = null) {
+ if ($id and is_array($id)) {
+ return $id[0];
+ } else {
+ $dom = new domdocument;
+ $dom->loadXML("<root>this is from an external DomDocument</root>");
+ return $dom->documentElement;
+ }
+ }
+ function nonDomNode() {
+ return new foo();
+ }
+
+ class aClass {
+ static function aStaticFunction($id) {
+ return $id;
+ }
+ }
+
+--EXPECTF--
+Test 11: php:function Support
+
+Warning: XSLTProcessor::transformToXml(): A PHP Object cannot be converted to a XPath-string in %s on line 16
+<?xml version="1.0"?>
+foobar - secondArg
+foobar -
+this is from an external DomDocument
+from the Input Document
+static
+
diff --git a/ext/xsl/tests/xslt011.xml b/ext/xsl/tests/xslt011.xml
new file mode 100644
index 0000000..f40500b
--- /dev/null
+++ b/ext/xsl/tests/xslt011.xml
@@ -0,0 +1 @@
+<doc id="foobar">This is <i>from the Input Document</i></doc>
diff --git a/ext/xsl/tests/xslt011.xsl b/ext/xsl/tests/xslt011.xsl
new file mode 100644
index 0000000..e1960e5
--- /dev/null
+++ b/ext/xsl/tests/xslt011.xsl
@@ -0,0 +1,25 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:php="http://php.net/xsl"
+ xsl:extension-element-prefixes="php"
+ version='1.0'>
+<xsl:template match="/">
+<xsl:value-of select="php:functionString('foobar', /doc/@id, 'secondArg')"/>
+<xsl:text>
+</xsl:text>
+<xsl:value-of select="php:function('foobar', /doc/@id)"/>
+<xsl:text>
+</xsl:text>
+<xsl:value-of select="php:function('nodeSet')"/>
+<xsl:text>
+</xsl:text>
+<xsl:value-of select="php:function('nodeSet',/doc)/i"/>
+<xsl:text>
+</xsl:text>
+<xsl:value-of select="php:function('aClass::aStaticFunction','static')"/>
+<xsl:text>
+</xsl:text>
+
+<xsl:value-of select="php:function('nonDomNode')"/>
+</xsl:template>
+</xsl:stylesheet>
diff --git a/ext/xsl/tests/xslt012.phpt b/ext/xsl/tests/xslt012.phpt
new file mode 100644
index 0000000..9fd3fbd
--- /dev/null
+++ b/ext/xsl/tests/xslt012.phpt
@@ -0,0 +1,52 @@
+--TEST--
+Test 12: Using Associative Array of Parameters
+--SKIPIF--
+<?php require_once dirname(__FILE__) .'/skipif.inc'; ?>
+--FILE--
+<?php
+echo "Test 12: Using Associative Array of Parameters";
+
+$dom = new domDocument;
+$dom->load(dirname(__FILE__)."/xslt.xml");
+if(!$dom) {
+ echo "Error while parsing the document\n";
+ exit;
+}
+
+$xsl = new domDocument;
+$xsl->load(dirname(__FILE__)."/xslt012.xsl");
+if(!$xsl) {
+ echo "Error while parsing the document\n";
+ exit;
+}
+
+$proc = new xsltprocessor;
+if(!$proc) {
+ echo "Error while making xsltprocessor object\n";
+ exit;
+}
+
+
+$proc->importStylesheet($xsl);
+
+$parameters = Array(
+ 'foo' => 'barbar',
+ 'foo1' => 'test',
+ );
+
+$proc->setParameter( "", $parameters);
+
+print "\n";
+print $proc->transformToXml($dom);
+print "\n";
+
+
+--EXPECT--
+Test 12: Using Associative Array of Parameters
+<?xml version="1.0" encoding="iso-8859-1"?>
+<html><body>barbar
+test
+a1 b1 c1 <br/>
+a2 c2 <br/>
+3 b3 c3 <br/>
+</body></html>
diff --git a/ext/xsl/tests/xslt012.xsl b/ext/xsl/tests/xslt012.xsl
new file mode 100644
index 0000000..27f4138
--- /dev/null
+++ b/ext/xsl/tests/xslt012.xsl
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!-- $Id: xslt012.xsl,v 1.1 2004-08-05 13:31:17 tony2001 Exp $ -->
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
+
+ <xsl:output method="xml" encoding="iso-8859-1" indent="no"/>
+ <xsl:param name="foo" select="'bar'"/>
+ <xsl:param name="foo1" select="'bar1'"/>
+ <xsl:template match="/">
+ <html>
+ <body>
+ <xsl:value-of select="$foo"/><xsl:text>
+</xsl:text>
+ <xsl:value-of select="$foo1"/><xsl:text>
+</xsl:text>
+ <xsl:apply-templates select="/chapter/para/informaltable/tgroup/tbody/row"/>
+ </body>
+ </html>
+ </xsl:template>
+
+ <xsl:template match="row">
+ <xsl:for-each select="entry">
+ <xsl:value-of select="."/>
+ <xsl:text> </xsl:text>
+ </xsl:for-each>
+ <br/> <xsl:text>
+</xsl:text>
+
+ </xsl:template>
+</xsl:stylesheet>
diff --git a/ext/xsl/tests/xsltprocessor_getParameter-invalidparam.phpt b/ext/xsl/tests/xsltprocessor_getParameter-invalidparam.phpt
new file mode 100644
index 0000000..19f7791
--- /dev/null
+++ b/ext/xsl/tests/xsltprocessor_getParameter-invalidparam.phpt
@@ -0,0 +1,17 @@
+--TEST--
+Check xsltprocessor::getParameter with undefined parameter
+--SKIPIF--
+<?php
+ if (!extension_loaded('xsl')) {
+ die("skip\n");
+ }
+?>
+--FILE--
+<?php
+include dirname(__FILE__) .'/prepare.inc';
+var_dump($proc->getParameter('', 'doesnotexist'));
+--EXPECTF--
+bool(false)
+--CREDITS--
+Christian Weiske, cweiske@php.net
+PHP Testfest Berlin 2009-05-09
diff --git a/ext/xsl/tests/xsltprocessor_getParameter-wrongparam.phpt b/ext/xsl/tests/xsltprocessor_getParameter-wrongparam.phpt
new file mode 100644
index 0000000..758d4ba
--- /dev/null
+++ b/ext/xsl/tests/xsltprocessor_getParameter-wrongparam.phpt
@@ -0,0 +1,26 @@
+--TEST--
+Check xsltprocessor::getparameter error handling
+--SKIPIF--
+<?php
+ if (!extension_loaded('xsl')) {
+ die("skip\n");
+ }
+?>
+--FILE--
+<?php
+include dirname(__FILE__) .'/prepare.inc';
+var_dump($proc->getParameter());
+var_dump($proc->getParameter(array(), array()));
+var_dump($proc->getParameter('', array()));
+--EXPECTF--
+Warning: XSLTProcessor::getParameter() expects exactly 2 parameters, 0 given in %s on line %d
+bool(false)
+
+Warning: XSLTProcessor::getParameter() expects parameter 1 to be %binary_string_optional%, array given in %s on line %d
+bool(false)
+
+Warning: XSLTProcessor::getParameter() expects parameter 2 to be %binary_string_optional%, array given in %s on line %d
+bool(false)
+--CREDITS--
+Christian Weiske, cweiske@php.net
+PHP Testfest Berlin 2009-05-09
diff --git a/ext/xsl/tests/xsltprocessor_getParameter.phpt b/ext/xsl/tests/xsltprocessor_getParameter.phpt
new file mode 100644
index 0000000..2430bc8
--- /dev/null
+++ b/ext/xsl/tests/xsltprocessor_getParameter.phpt
@@ -0,0 +1,19 @@
+--TEST--
+Check xsltprocessor::getparameter functionality
+--SKIPIF--
+<?php
+ if (!extension_loaded('xsl')) {
+ die("skip\n");
+ }
+?>
+--FILE--
+<?php
+include dirname(__FILE__) .'/prepare.inc';
+$proc->importStylesheet($xsl);
+$proc->setParameter('', 'key', 'value');
+var_dump($proc->getParameter('', 'key'));
+--EXPECTF--
+%string|unicode%(5) "value"
+--CREDITS--
+Christian Weiske, cweiske@php.net
+PHP Testfest Berlin 2009-05-09
diff --git a/ext/xsl/tests/xsltprocessor_registerPHPFunctions-allfuncs.phpt b/ext/xsl/tests/xsltprocessor_registerPHPFunctions-allfuncs.phpt
new file mode 100644
index 0000000..1f0453e
--- /dev/null
+++ b/ext/xsl/tests/xsltprocessor_registerPHPFunctions-allfuncs.phpt
@@ -0,0 +1,30 @@
+--TEST--
+Check xsltprocessor::registerPHPFunctions
+--SKIPIF--
+<?php
+ if (!extension_loaded('xsl')) {
+ die("skip\n");
+ }
+?>
+--FILE--
+<?php
+include dirname(__FILE__) .'/prepare.inc';
+$phpfuncxsl = new domDocument();
+$phpfuncxsl->load(dirname(__FILE__)."/phpfunc.xsl");
+if(!$phpfuncxsl) {
+ echo "Error while parsing the xsl document\n";
+ exit;
+}
+$proc->importStylesheet($phpfuncxsl);
+var_dump($proc->registerPHPFunctions());
+var_dump($proc->transformToXml($dom));
+
+//var_dump($proc->registerPHPFunctions(array()));
+//var_dump($proc->transformToXml($dom));
+
+--EXPECTF--
+NULL
+string(18) "This Is An Example"
+--CREDITS--
+Christian Weiske, cweiske@php.net
+PHP Testfest Berlin 2009-05-09
diff --git a/ext/xsl/tests/xsltprocessor_registerPHPFunctions-array-multiple.phpt b/ext/xsl/tests/xsltprocessor_registerPHPFunctions-array-multiple.phpt
new file mode 100644
index 0000000..a5f2373
--- /dev/null
+++ b/ext/xsl/tests/xsltprocessor_registerPHPFunctions-array-multiple.phpt
@@ -0,0 +1,34 @@
+--TEST--
+Check xsltprocessor::registerPHPFunctions with array called multiple times
+--DESCRIPTION--
+When being called multiple times with an array,
+registerPHPFunctions adds the new functions to the allowed parameter
+list - it does not replace the previously allowed functions.
+--SKIPIF--
+<?php
+ if (!extension_loaded('xsl')) {
+ die("skip\n");
+ }
+?>
+--FILE--
+<?php
+include dirname(__FILE__) .'/prepare.inc';
+$phpfuncxsl = new domDocument();
+$phpfuncxsl->load(dirname(__FILE__)."/phpfunc.xsl");
+if(!$phpfuncxsl) {
+ echo "Error while parsing the xsl document\n";
+ exit;
+}
+$proc->importStylesheet($phpfuncxsl);
+var_dump($proc->registerPHPFunctions(array('strpos', 'ucwords')));
+var_dump($proc->registerPHPFunctions(array('strrev', 'array_key_exists')));
+var_dump($proc->registerPHPFunctions(array()));
+var_dump($proc->transformToXml($dom));
+--EXPECTF--
+NULL
+NULL
+NULL
+string(18) "This Is An Example"
+--CREDITS--
+Christian Weiske, cweiske@php.net
+PHP Testfest Berlin 2009-05-09
diff --git a/ext/xsl/tests/xsltprocessor_registerPHPFunctions-array-notallowed.phpt b/ext/xsl/tests/xsltprocessor_registerPHPFunctions-array-notallowed.phpt
new file mode 100644
index 0000000..9492fc6
--- /dev/null
+++ b/ext/xsl/tests/xsltprocessor_registerPHPFunctions-array-notallowed.phpt
@@ -0,0 +1,28 @@
+--TEST--
+Check xsltprocessor::registerPHPFunctions with array and a not allowed function
+--SKIPIF--
+<?php
+ if (!extension_loaded('xsl')) {
+ die("skip\n");
+ }
+?>
+--FILE--
+<?php
+include dirname(__FILE__) .'/prepare.inc';
+$phpfuncxsl = new domDocument();
+$phpfuncxsl->load(dirname(__FILE__)."/phpfunc.xsl");
+if(!$phpfuncxsl) {
+ echo "Error while parsing the xsl document\n";
+ exit;
+}
+$proc->importStylesheet($phpfuncxsl);
+var_dump($proc->registerPHPFunctions(array()));
+var_dump($proc->transformToXml($dom));
+--EXPECTF--
+NULL
+
+Warning: XSLTProcessor::transformToXml(): Not allowed to call handler 'ucwords()' in %s on line %d
+NULL
+--CREDITS--
+Christian Weiske, cweiske@php.net
+PHP Testfest Berlin 2009-05-09
diff --git a/ext/xsl/tests/xsltprocessor_registerPHPFunctions-array.phpt b/ext/xsl/tests/xsltprocessor_registerPHPFunctions-array.phpt
new file mode 100644
index 0000000..0e467aa
--- /dev/null
+++ b/ext/xsl/tests/xsltprocessor_registerPHPFunctions-array.phpt
@@ -0,0 +1,26 @@
+--TEST--
+Check xsltprocessor::registerPHPFunctions with array
+--SKIPIF--
+<?php
+ if (!extension_loaded('xsl')) {
+ die("skip\n");
+ }
+?>
+--FILE--
+<?php
+include dirname(__FILE__) .'/prepare.inc';
+$phpfuncxsl = new domDocument();
+$phpfuncxsl->load(dirname(__FILE__)."/phpfunc.xsl");
+if(!$phpfuncxsl) {
+ echo "Error while parsing the xsl document\n";
+ exit;
+}
+$proc->importStylesheet($phpfuncxsl);
+var_dump($proc->registerPHPFunctions(array('ucwords')));
+var_dump($proc->transformToXml($dom));
+--EXPECTF--
+NULL
+string(18) "This Is An Example"
+--CREDITS--
+Christian Weiske, cweiske@php.net
+PHP Testfest Berlin 2009-05-09
diff --git a/ext/xsl/tests/xsltprocessor_registerPHPFunctions-funcnostring.phpt b/ext/xsl/tests/xsltprocessor_registerPHPFunctions-funcnostring.phpt
new file mode 100644
index 0000000..90d9c68
--- /dev/null
+++ b/ext/xsl/tests/xsltprocessor_registerPHPFunctions-funcnostring.phpt
@@ -0,0 +1,31 @@
+--TEST--
+Check xsltprocessor::registerPHPFunctions and a non-string function in xsl
+--DESCRIPTION--
+The XSL script tries to call a php function that is not a string which
+is expected to fail
+--SKIPIF--
+<?php
+ if (!extension_loaded('xsl')) {
+ die("skip\n");
+ }
+?>
+--FILE--
+<?php
+include dirname(__FILE__) .'/prepare.inc';
+$phpfuncxsl = new domDocument();
+$phpfuncxsl->load(dirname(__FILE__)."/phpfunc-nostring.xsl");
+if(!$phpfuncxsl) {
+ echo "Error while parsing the xsl document\n";
+ exit;
+}
+$proc->importStylesheet($phpfuncxsl);
+var_dump($proc->registerPHPFunctions());
+var_dump($proc->transformToXml($dom));
+--EXPECTF--
+NULL
+
+Warning: XSLTProcessor::transformToXml(): Handler name must be a string in %s on line %d
+NULL
+--CREDITS--
+Christian Weiske, cweiske@php.net
+PHP Testfest Berlin 2009-05-09
diff --git a/ext/xsl/tests/xsltprocessor_registerPHPFunctions-funcundef.phpt b/ext/xsl/tests/xsltprocessor_registerPHPFunctions-funcundef.phpt
new file mode 100644
index 0000000..a26c210
--- /dev/null
+++ b/ext/xsl/tests/xsltprocessor_registerPHPFunctions-funcundef.phpt
@@ -0,0 +1,30 @@
+--TEST--
+Check xsltprocessor::registerPHPFunctions and a undefined php function
+--DESCRIPTION--
+The XSL script tries to call a php function that is not defined
+--SKIPIF--
+<?php
+ if (!extension_loaded('xsl')) {
+ die("skip\n");
+ }
+?>
+--FILE--
+<?php
+include dirname(__FILE__) .'/prepare.inc';
+$phpfuncxsl = new domDocument();
+$phpfuncxsl->load(dirname(__FILE__)."/phpfunc-undef.xsl");
+if(!$phpfuncxsl) {
+ echo "Error while parsing the xsl document\n";
+ exit;
+}
+$proc->importStylesheet($phpfuncxsl);
+var_dump($proc->registerPHPFunctions());
+var_dump($proc->transformToXml($dom));
+--EXPECTF--
+NULL
+
+Warning: XSLTProcessor::transformToXml(): Unable to call handler undefinedfunc() in %s on line %d
+NULL
+--CREDITS--
+Christian Weiske, cweiske@php.net
+PHP Testfest Berlin 2009-05-09
diff --git a/ext/xsl/tests/xsltprocessor_registerPHPFunctions-null.phpt b/ext/xsl/tests/xsltprocessor_registerPHPFunctions-null.phpt
new file mode 100644
index 0000000..f74d785
--- /dev/null
+++ b/ext/xsl/tests/xsltprocessor_registerPHPFunctions-null.phpt
@@ -0,0 +1,32 @@
+--TEST--
+Check xsltprocessor::registerPHPFunctions called with null to reset
+--DESCRIPTION--
+When being called multiple times with an array,
+registerPHPFunctions adds the new functions to the allowed parameter
+list - it does not replace the previously allowed functions.
+--SKIPIF--
+<?php
+ if (!extension_loaded('xsl')) {
+ die("skip\n");
+ }
+?>
+--FILE--
+<?php
+include dirname(__FILE__) .'/prepare.inc';
+$phpfuncxsl = new domDocument();
+$phpfuncxsl->load(dirname(__FILE__)."/phpfunc.xsl");
+if(!$phpfuncxsl) {
+ echo "Error while parsing the xsl document\n";
+ exit;
+}
+$proc->importStylesheet($phpfuncxsl);
+var_dump($proc->registerPHPFunctions('ucwords'));
+var_dump($proc->registerPHPFunctions(null));
+var_dump($proc->transformToXml($dom));
+--EXPECTF--
+NULL
+NULL
+string(18) "This Is An Example"
+--CREDITS--
+Christian Weiske, cweiske@php.net
+PHP Testfest Berlin 2009-05-09
diff --git a/ext/xsl/tests/xsltprocessor_registerPHPFunctions-string-multiple.phpt b/ext/xsl/tests/xsltprocessor_registerPHPFunctions-string-multiple.phpt
new file mode 100644
index 0000000..f15c08d
--- /dev/null
+++ b/ext/xsl/tests/xsltprocessor_registerPHPFunctions-string-multiple.phpt
@@ -0,0 +1,32 @@
+--TEST--
+Check xsltprocessor::registerPHPFunctions with string called multiple times
+--DESCRIPTION--
+When being called multiple times with a stringular function name only,
+registerPHPFunctions adds the new function to the allowed parameter
+list - it does not replace the old function.
+--SKIPIF--
+<?php
+ if (!extension_loaded('xsl')) {
+ die("skip\n");
+ }
+?>
+--FILE--
+<?php
+include dirname(__FILE__) .'/prepare.inc';
+$phpfuncxsl = new domDocument();
+$phpfuncxsl->load(dirname(__FILE__)."/phpfunc.xsl");
+if(!$phpfuncxsl) {
+ echo "Error while parsing the xsl document\n";
+ exit;
+}
+$proc->importStylesheet($phpfuncxsl);
+var_dump($proc->registerPHPFunctions('ucwords'));
+var_dump($proc->registerPHPFunctions('strpos'));
+var_dump($proc->transformToXml($dom));
+--EXPECTF--
+NULL
+NULL
+string(18) "This Is An Example"
+--CREDITS--
+Christian Weiske, cweiske@php.net
+PHP Testfest Berlin 2009-05-09
diff --git a/ext/xsl/tests/xsltprocessor_registerPHPFunctions-string-notallowed.phpt b/ext/xsl/tests/xsltprocessor_registerPHPFunctions-string-notallowed.phpt
new file mode 100644
index 0000000..9257749
--- /dev/null
+++ b/ext/xsl/tests/xsltprocessor_registerPHPFunctions-string-notallowed.phpt
@@ -0,0 +1,28 @@
+--TEST--
+Check xsltprocessor::registerPHPFunctions with string and not allowed function
+--SKIPIF--
+<?php
+ if (!extension_loaded('xsl')) {
+ die("skip\n");
+ }
+?>
+--FILE--
+<?php
+include dirname(__FILE__) .'/prepare.inc';
+$phpfuncxsl = new domDocument();
+$phpfuncxsl->load(dirname(__FILE__)."/phpfunc.xsl");
+if(!$phpfuncxsl) {
+ echo "Error while parsing the xsl document\n";
+ exit;
+}
+$proc->importStylesheet($phpfuncxsl);
+var_dump($proc->registerPHPFunctions('strpos'));
+var_dump($proc->transformToXml($dom));
+--EXPECTF--
+NULL
+
+Warning: XSLTProcessor::transformToXml(): Not allowed to call handler 'ucwords()' in %s on line %d
+NULL
+--CREDITS--
+Christian Weiske, cweiske@php.net
+PHP Testfest Berlin 2009-05-09
diff --git a/ext/xsl/tests/xsltprocessor_registerPHPFunctions-string.phpt b/ext/xsl/tests/xsltprocessor_registerPHPFunctions-string.phpt
new file mode 100644
index 0000000..5fbba90
--- /dev/null
+++ b/ext/xsl/tests/xsltprocessor_registerPHPFunctions-string.phpt
@@ -0,0 +1,26 @@
+--TEST--
+Check xsltprocessor::registerPHPFunctions with string
+--SKIPIF--
+<?php
+ if (!extension_loaded('xsl')) {
+ die("skip\n");
+ }
+?>
+--FILE--
+<?php
+include dirname(__FILE__) .'/prepare.inc';
+$phpfuncxsl = new domDocument();
+$phpfuncxsl->load(dirname(__FILE__)."/phpfunc.xsl");
+if(!$phpfuncxsl) {
+ echo "Error while parsing the xsl document\n";
+ exit;
+}
+$proc->importStylesheet($phpfuncxsl);
+var_dump($proc->registerPHPFunctions('ucwords'));
+var_dump($proc->transformToXml($dom));
+--EXPECTF--
+NULL
+string(18) "This Is An Example"
+--CREDITS--
+Christian Weiske, cweiske@php.net
+PHP Testfest Berlin 2009-05-09
diff --git a/ext/xsl/tests/xsltprocessor_removeParameter-invalidparam.phpt b/ext/xsl/tests/xsltprocessor_removeParameter-invalidparam.phpt
new file mode 100644
index 0000000..f35b470
--- /dev/null
+++ b/ext/xsl/tests/xsltprocessor_removeParameter-invalidparam.phpt
@@ -0,0 +1,18 @@
+--TEST--
+Check xsltprocessor::removeParameter with invalid parameter
+--SKIPIF--
+<?php
+ if (!extension_loaded('xsl')) {
+ die("skip\n");
+ }
+?>
+--FILE--
+<?php
+include dirname(__FILE__) .'/prepare.inc';
+$proc->importStylesheet($xsl);
+var_dump($proc->removeParameter('', 'doesnotexist'));
+--EXPECT--
+bool(false)
+--CREDITS--
+Christian Weiske, cweiske@php.net
+PHP Testfest Berlin 2009-05-09
diff --git a/ext/xsl/tests/xsltprocessor_removeParameter-wrongparams.phpt b/ext/xsl/tests/xsltprocessor_removeParameter-wrongparams.phpt
new file mode 100644
index 0000000..c2b4f4c
--- /dev/null
+++ b/ext/xsl/tests/xsltprocessor_removeParameter-wrongparams.phpt
@@ -0,0 +1,23 @@
+--TEST--
+Check xsltprocessor::removeParameter wrong parameter handling
+--SKIPIF--
+<?php
+ if (!extension_loaded('xsl')) {
+ die("skip\n");
+ }
+?>
+--FILE--
+<?php
+include dirname(__FILE__) .'/prepare.inc';
+$proc->removeParameter();
+$proc->removeParameter(array(), array());
+$proc->removeParameter('', array());
+--EXPECTF--
+Warning: XSLTProcessor::removeParameter() expects exactly 2 parameters, 0 given in %s on line %d
+
+Warning: XSLTProcessor::removeParameter() expects parameter 1 to be %binary_string_optional%, array given in %s on line %d
+
+Warning: XSLTProcessor::removeParameter() expects parameter 2 to be %binary_string_optional%, array given in %s on line %d
+--CREDITS--
+Christian Weiske, cweiske@php.net
+PHP Testfest Berlin 2009-05-09
diff --git a/ext/xsl/tests/xsltprocessor_removeParameter.phpt b/ext/xsl/tests/xsltprocessor_removeParameter.phpt
new file mode 100644
index 0000000..92be056
--- /dev/null
+++ b/ext/xsl/tests/xsltprocessor_removeParameter.phpt
@@ -0,0 +1,20 @@
+--TEST--
+Check xsltprocessor::removeParameter functionality
+--SKIPIF--
+<?php
+ if (!extension_loaded('xsl')) {
+ die("skip\n");
+ }
+?>
+--FILE--
+<?php
+include dirname(__FILE__) .'/prepare.inc';
+$proc->importStylesheet($xsl);
+$proc->setParameter('', 'key', 'value');
+$proc->removeParameter('', 'key');
+var_dump($proc->getParameter('', 'key'));
+--EXPECT--
+bool(false)
+--CREDITS--
+Christian Weiske, cweiske@php.net
+PHP Testfest Berlin 2009-05-09
diff --git a/ext/xsl/tests/xsltprocessor_setparameter-errorquote.phpt b/ext/xsl/tests/xsltprocessor_setparameter-errorquote.phpt
new file mode 100644
index 0000000..44e49de
--- /dev/null
+++ b/ext/xsl/tests/xsltprocessor_setparameter-errorquote.phpt
@@ -0,0 +1,21 @@
+--TEST--
+Check xsltprocessor::setparameter error handling with both single and double quotes
+--DESCRIPTION--
+Memleak: http://bugs.php.net/bug.php?id=48221
+--SKIPIF--
+<?php
+ if (!extension_loaded('xsl')) {
+ die("skip\n");
+ }
+?>
+--FILE--
+<?php
+include dirname(__FILE__) .'/prepare.inc';
+$proc->importStylesheet($xsl);
+$proc->setParameter('', '', '"\'');
+$proc->transformToXml($dom);
+--EXPECTF--
+Warning: XSLTProcessor::transformToXml(): Cannot create XPath expression (string contains both quote and double-quotes) in %s on line %d
+--CREDITS--
+Christian Weiske, cweiske@php.net
+PHP Testfest Berlin 2009-05-09
diff --git a/ext/xsl/tests/xsltprocessor_setparameter-nostring.phpt b/ext/xsl/tests/xsltprocessor_setparameter-nostring.phpt
new file mode 100644
index 0000000..c4fcd70
--- /dev/null
+++ b/ext/xsl/tests/xsltprocessor_setparameter-nostring.phpt
@@ -0,0 +1,22 @@
+--TEST--
+Check xsltprocessor::setparameter error handling with no-string
+--DESCRIPTION--
+Memleak: http://bugs.php.net/bug.php?id=48221
+--SKIPIF--
+<?php
+ if (!extension_loaded('xsl')) {
+ die("skip\n");
+ }
+?>
+--FILE--
+<?php
+include dirname(__FILE__) .'/prepare.inc';
+$proc->importStylesheet($xsl);
+var_dump($proc->setParameter('', array(4, 'abc')));
+$proc->transformToXml($dom);
+--EXPECTF--
+Warning: XSLTProcessor::setParameter(): Invalid parameter array in %s on line %d
+bool(false)
+--CREDITS--
+Christian Weiske, cweiske@php.net
+PHP Testfest Berlin 2009-05-09
diff --git a/ext/xsl/xsl.dsp b/ext/xsl/xsl.dsp
new file mode 100644
index 0000000..ff7257d
--- /dev/null
+++ b/ext/xsl/xsl.dsp
@@ -0,0 +1,120 @@
+# Microsoft Developer Studio Project File - Name="xsl" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=xsl - Win32 Debug_TS
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "xsl.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "xsl.mak" CFG="xsl - Win32 Debug_TS"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "xsl - Win32 Release_TS" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "xsl - Win32 Debug_TS" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "xsl - Win32 Release_TS"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release_TS"
+# PROP BASE Intermediate_Dir "Release_TS"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release_TS"
+# PROP Intermediate_Dir "Release_TS"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XSL_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\.." /I "..\..\Zend" /I "..\..\TSRM" /I "..\..\main" /D ZEND_DEBUG=0 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "COMPILE_DL_XSL" /D ZTS=1 /D "ZEND_WIN32" /D "PHP_WIN32" /D "LIBXSLT_STATIC" /D "LIBEXSLT_STATIC" /D "LIBXML_THREAD_ENABLED" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 wsock32.lib php5ts.lib libxslt_a.lib libexslt_a.lib resolv.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /dll /machine:I386 /out:"..\..\Release_TS/php_xsl.dll" /implib:".Release_TS/php_xsl.lib" /libpath:"..\..\Release_TS" /libpath:"..\..\Release_TS_Inline" /libpath:"..\..\..\bindlib_w32\Release"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "xsl - Win32 Debug_TS"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug_TS"
+# PROP BASE Intermediate_Dir "Debug_TS"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug_TS"
+# PROP Intermediate_Dir "Debug_TS"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XSL_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /GX /ZI /Od /I "..\.." /I "..\..\Zend" /I "..\..\TSRM" /I "..\..\main" /D ZEND_DEBUG=1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XSL_EXPORTS" /D "COMPILE_DL_XSL" /D ZTS=1 /D "ZEND_WIN32" /D "PHP_WIN32" /D "LIBXSLT_STATIC" /D "LIBEXSLT_STATIC" /D "LIBXML_THREAD_ENABLED" /FR /YX /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x406 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 php5ts_debug.lib libxslt_a.lib libexslt_a.lib resolv.lib kernel32.lib user32.lib gdi32.lib winspool.lib /nologo /dll /debug /machine:I386 /nodefaultlib:"msvcrt" /out:"..\..\Debug_TS/php_xsl.dll" /libpath:"..\..\Debug_TS" /libpath:"..\..\..\bindlib_w32\Release" /libpath:"..\..\..\php_build\lib\libxslt"
+
+!ENDIF
+
+# Begin Target
+
+# Name "xsl - Win32 Release_TS"
+# Name "xsl - Win32 Debug_TS"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\php_xsl.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\xsltprocessor.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\php_xsl.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\xsl_fe.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/ext/xsl/xsl_fe.h b/ext/xsl/xsl_fe.h
new file mode 100644
index 0000000..ba9d49b
--- /dev/null
+++ b/ext/xsl/xsl_fe.h
@@ -0,0 +1,49 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Christian Stocker <chregu@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifndef XSL_FE_H
+#define XSL_FE_H
+
+extern const zend_function_entry php_xsl_xsltprocessor_class_functions[];
+extern zend_class_entry *xsl_xsltprocessor_class_entry;
+
+PHP_FUNCTION(xsl_xsltprocessor_import_stylesheet);
+PHP_FUNCTION(xsl_xsltprocessor_transform_to_doc);
+PHP_FUNCTION(xsl_xsltprocessor_transform_to_uri);
+PHP_FUNCTION(xsl_xsltprocessor_transform_to_xml);
+PHP_FUNCTION(xsl_xsltprocessor_set_parameter);
+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);
+PHP_FUNCTION(xsl_xsltprocessor_set_profiling);
+PHP_FUNCTION(xsl_xsltprocessor_set_security_prefs);
+PHP_FUNCTION(xsl_xsltprocessor_get_security_prefs);
+
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: sw=4 ts=4 fdm=marker
+ * vim<600: sw=4 ts=4
+ */
diff --git a/ext/xsl/xsltprocessor.c b/ext/xsl/xsltprocessor.c
new file mode 100644
index 0000000..1785519
--- /dev/null
+++ b/ext/xsl/xsltprocessor.c
@@ -0,0 +1,992 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Christian Stocker <chregu@php.net> |
+ | Rob Richards <rrichards@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#include "php_xsl.h"
+#include "ext/libxml/php_libxml.h"
+
+/* {{{ arginfo */
+ZEND_BEGIN_ARG_INFO_EX(arginfo_xsl_xsltprocessor_import_stylesheet, 0, 0, 1)
+ ZEND_ARG_INFO(0, doc)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_xsl_xsltprocessor_transform_to_doc, 0, 0, 1)
+ ZEND_ARG_INFO(0, doc)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_xsl_xsltprocessor_transform_to_uri, 0, 0, 2)
+ ZEND_ARG_INFO(0, doc)
+ ZEND_ARG_INFO(0, uri)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_xsl_xsltprocessor_transform_to_xml, 0, 0, 1)
+ ZEND_ARG_INFO(0, doc)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_xsl_xsltprocessor_set_parameter, 0, 0, 2)
+ ZEND_ARG_INFO(0, namespace)
+ ZEND_ARG_INFO(0, name)
+ ZEND_ARG_INFO(0, value)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_xsl_xsltprocessor_get_parameter, 0, 0, 2)
+ ZEND_ARG_INFO(0, namespace)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_xsl_xsltprocessor_remove_parameter, 0, 0, 2)
+ ZEND_ARG_INFO(0, namespace)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_xsl_xsltprocessor_has_exslt_support, 0, 0, 0)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_xsl_xsltprocessor_register_php_functions, 0, 0, 0)
+ ZEND_ARG_INFO(0, restrict)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_xsl_xsltprocessor_set_profiling, 0, 0, 1)
+ ZEND_ARG_INFO(0, filename)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_xsl_xsltprocessor_set_security_prefs, 0, 0, 1)
+ ZEND_ARG_INFO(0, securityPrefs)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_xsl_xsltprocessor_get_security_prefs, 0, 0, 0)
+ZEND_END_ARG_INFO();
+/* }}} */
+
+/*
+* class xsl_xsltprocessor
+*
+* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#
+* Since:
+*/
+
+const zend_function_entry php_xsl_xsltprocessor_class_functions[] = {
+ PHP_FALIAS(importStylesheet, xsl_xsltprocessor_import_stylesheet, arginfo_xsl_xsltprocessor_import_stylesheet)
+ PHP_FALIAS(transformToDoc, xsl_xsltprocessor_transform_to_doc, arginfo_xsl_xsltprocessor_transform_to_doc)
+ PHP_FALIAS(transformToUri, xsl_xsltprocessor_transform_to_uri, arginfo_xsl_xsltprocessor_transform_to_uri)
+ PHP_FALIAS(transformToXml, xsl_xsltprocessor_transform_to_xml, arginfo_xsl_xsltprocessor_transform_to_xml)
+ PHP_FALIAS(setParameter, xsl_xsltprocessor_set_parameter, arginfo_xsl_xsltprocessor_set_parameter)
+ PHP_FALIAS(getParameter, xsl_xsltprocessor_get_parameter, arginfo_xsl_xsltprocessor_get_parameter)
+ PHP_FALIAS(removeParameter, xsl_xsltprocessor_remove_parameter, arginfo_xsl_xsltprocessor_remove_parameter)
+ PHP_FALIAS(hasExsltSupport, xsl_xsltprocessor_has_exslt_support, arginfo_xsl_xsltprocessor_has_exslt_support)
+ PHP_FALIAS(registerPHPFunctions, xsl_xsltprocessor_register_php_functions, arginfo_xsl_xsltprocessor_register_php_functions)
+ PHP_FALIAS(setProfiling, xsl_xsltprocessor_set_profiling, arginfo_xsl_xsltprocessor_set_profiling)
+ PHP_FALIAS(setSecurityPrefs, xsl_xsltprocessor_set_security_prefs, arginfo_xsl_xsltprocessor_set_security_prefs)
+ PHP_FALIAS(getSecurityPrefs, xsl_xsltprocessor_get_security_prefs, arginfo_xsl_xsltprocessor_get_security_prefs)
+ {NULL, NULL, NULL}
+};
+
+/* {{{ php_xsl_xslt_string_to_xpathexpr()
+ Translates a string to a XPath Expression */
+static char *php_xsl_xslt_string_to_xpathexpr(const char *str TSRMLS_DC)
+{
+ const xmlChar *string = (const xmlChar *)str;
+
+ 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)");
+ return NULL;
+ }
+ value = (xmlChar*) safe_emalloc (str_len, sizeof(xmlChar), 0);
+ snprintf(value, str_len, "'%s'", string);
+ } else {
+ value = (xmlChar*) safe_emalloc (str_len, sizeof(xmlChar), 0);
+ snprintf(value, str_len, "\"%s\"", string);
+ }
+ return (char *) value;
+}
+/* }}} */
+
+/* {{{ 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)
+{
+
+ int parsize;
+ zval **value;
+ char *xpath_expr, *string_key = NULL;
+ ulong num_key;
+ char **params = NULL;
+ int i = 0;
+
+ parsize = (2 * zend_hash_num_elements(parht) + 1) * sizeof(char *);
+ params = (char **)safe_emalloc((2 * zend_hash_num_elements(parht) + 1), sizeof(char *), 0);
+ memset((char *)params, 0, parsize);
+
+ for (zend_hash_internal_pointer_reset(parht);
+ zend_hash_get_current_data(parht, (void **)&value) == SUCCESS;
+ zend_hash_move_forward(parht)) {
+
+ if (zend_hash_get_current_key(parht, &string_key, &num_key, 1) != HASH_KEY_IS_STRING) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid argument or parameter array");
+ efree(params);
+ return NULL;
+ } else {
+ if (Z_TYPE_PP(value) != IS_STRING) {
+ 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 {
+ xpath_expr = estrndup(Z_STRVAL_PP(value), Z_STRLEN_PP(value));
+ }
+ if (xpath_expr) {
+ params[i++] = string_key;
+ params[i++] = xpath_expr;
+ } else {
+ efree(string_key);
+ }
+ }
+ }
+
+ params[i++] = NULL;
+
+ return params;
+}
+/* }}} */
+
+static void xsl_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs, int type) /* {{{ */
+{
+ xsltTransformContextPtr tctxt;
+ zval **args;
+ zval *retval;
+ int result, i, ret;
+ int error = 0;
+ zend_fcall_info fci;
+ zval handler;
+ xmlXPathObjectPtr obj;
+ char *str;
+ char *callable = NULL;
+ xsl_object *intern;
+
+ TSRMLS_FETCH();
+
+ if (! zend_is_executing(TSRMLS_C)) {
+ xsltGenericError(xsltGenericErrorContext,
+ "xsltExtFunctionTest: Function called from outside of PHP\n");
+ error = 1;
+ } else {
+ tctxt = xsltXPathGetTransformContext(ctxt);
+ if (tctxt == NULL) {
+ xsltGenericError(xsltGenericErrorContext,
+ "xsltExtFunctionTest: failed to get the transformation context\n");
+ error = 1;
+ } else {
+ intern = (xsl_object *) tctxt->_private;
+ if (intern == NULL) {
+ xsltGenericError(xsltGenericErrorContext,
+ "xsltExtFunctionTest: failed to get the internal object\n");
+ error = 1;
+ }
+ else if (intern->registerPhpFunctions == 0) {
+ xsltGenericError(xsltGenericErrorContext,
+ "xsltExtFunctionTest: PHP Object did not register PHP functions\n");
+ error = 1;
+ }
+ }
+ }
+
+ if (error == 1) {
+ for (i = nargs - 1; i >= 0; i--) {
+ obj = valuePop(ctxt);
+ xmlXPathFreeObject(obj);
+ }
+ return;
+ }
+
+ fci.param_count = nargs - 1;
+ if (fci.param_count > 0) {
+ fci.params = safe_emalloc(fci.param_count, sizeof(zval**), 0);
+ args = safe_emalloc(fci.param_count, 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 *domintern = (dom_object *)intern->doc;
+ array_init(args[i]);
+ if (obj->nodesetval && obj->nodesetval->nodeNr > 0) {
+ 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, child, domintern TSRMLS_CC);
+ add_next_index_zval(args[i], child);
+ }
+ }
+ }
+ break;
+ default:
+ str = xmlXPathCastToString(obj);
+ ZVAL_STRING(args[i], str, 1);
+ xmlFree(str);
+ }
+ 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);
+ valuePush(ctxt, xmlXPathNewString(""));
+ if (fci.param_count > 0) {
+ 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_ptr = NULL;
+ fci.retval_ptr_ptr = &retval;
+ fci.no_separation = 0;
+ /*fci.function_handler_cache = &function_ptr;*/
+ 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) {
+ 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(""));
+ } else {
+ 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));
+ valuePush(ctxt, xmlXPathNewString(""));
+ }
+ /* retval is == NULL, when an exception occurred, don't report anything, because PHP itself will handle that */
+ } else if (retval == NULL) {
+ } else {
+ if (retval->type == IS_OBJECT && instanceof_function( Z_OBJCE_P(retval), dom_node_class_entry TSRMLS_CC)) {
+ xmlNode *nodep;
+ dom_object *obj;
+ if (intern->node_list == NULL) {
+ ALLOC_HASHTABLE(intern->node_list);
+ zend_hash_init(intern->node_list, 0, NULL, ZVAL_PTR_DTOR, 0);
+ }
+ zval_add_ref(&retval);
+ zend_hash_next_index_insert(intern->node_list, &retval, sizeof(zval *), NULL);
+ 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 cannot 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);
+ }
+ }
+ efree(callable);
+ zval_dtor(&handler);
+ if (fci.param_count > 0) {
+ for (i = 0; i < nargs - 1; i++) {
+ zval_ptr_dtor(&args[i]);
+ }
+ efree(args);
+ efree(fci.params);
+ }
+}
+/* }}} */
+
+void xsl_ext_function_string_php(xmlXPathParserContextPtr ctxt, int nargs) /* {{{ */
+{
+ xsl_ext_function_php(ctxt, nargs, 1);
+}
+/* }}} */
+
+void xsl_ext_function_object_php(xmlXPathParserContextPtr ctxt, int nargs) /* {{{ */
+{
+ xsl_ext_function_php(ctxt, nargs, 2);
+}
+/* }}} */
+
+/* {{{ 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:
+*/
+PHP_FUNCTION(xsl_xsltprocessor_import_stylesheet)
+{
+ zval *id, *docp = NULL;
+ xmlDoc *doc = NULL, *newdoc = NULL;
+ xsltStylesheetPtr sheetp, oldsheetp;
+ xsl_object *intern;
+ int prevSubstValue, prevExtDtdValue, clone_docu = 0;
+ 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;
+ }
+ if (doc == NULL) {
+ php_error(E_WARNING, "Invalid Document");
+ RETURN_FALSE;
+ }
+
+ /* 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);
+ prevSubstValue = xmlSubstituteEntitiesDefault(1);
+ prevExtDtdValue = xmlLoadExtDtdDefaultValue;
+ xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
+
+ sheetp = xsltParseStylesheetDoc(newdoc);
+ xmlSubstituteEntitiesDefault(prevSubstValue);
+ xmlLoadExtDtdDefaultValue = prevExtDtdValue;
+
+ if (!sheetp) {
+ xmlFreeDoc(newdoc);
+ RETURN_FALSE;
+ }
+
+ intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
+
+ std_hnd = zend_get_std_object_handlers();
+ MAKE_STD_ZVAL(member);
+ ZVAL_STRING(member, "cloneDocument", 0);
+ cloneDocu = std_hnd->read_property(id, member, BP_VAR_IS, NULL TSRMLS_CC);
+ if (Z_TYPE_P(cloneDocu) != IS_NULL) {
+ convert_to_long(cloneDocu);
+ clone_docu = Z_LVAL_P(cloneDocu);
+ }
+ efree(member);
+ if (clone_docu == 0) {
+ /* check if the stylesheet is using xsl:key, if yes, we have to clone the document _always_ before a transformation */
+ nodep = xmlDocGetRootElement(sheetp->doc);
+ if (nodep && (nodep = nodep->children)) {
+ while (nodep) {
+ if (nodep->type == XML_ELEMENT_NODE && xmlStrEqual(nodep->name, "key") && xmlStrEqual(nodep->ns->href, XSLT_NAMESPACE)) {
+ intern->hasKeys = 1;
+ break;
+ }
+ nodep = nodep->next;
+ }
+ }
+ } else {
+ intern->hasKeys = clone_docu;
+ }
+
+ if ((oldsheetp = (xsltStylesheetPtr)intern->ptr)) {
+ /* free wrapper */
+ if (((xsltStylesheetPtr) intern->ptr)->_private != NULL) {
+ ((xsltStylesheetPtr) intern->ptr)->_private = NULL;
+ }
+ xsltFreeStylesheet((xsltStylesheetPtr) intern->ptr);
+ intern->ptr = NULL;
+ }
+
+ php_xsl_set_object(id, sheetp TSRMLS_CC);
+ RETVAL_TRUE;
+}
+/* }}} end xsl_xsltprocessor_import_stylesheet */
+
+static xmlDocPtr php_xsl_apply_stylesheet(zval *id, xsl_object *intern, xsltStylesheetPtr style, zval *docp TSRMLS_DC) /* {{{ */
+{
+ xmlDocPtr newdocp;
+ xmlDocPtr doc = NULL;
+ xmlNodePtr node = NULL;
+ xsltTransformContextPtr ctxt;
+ php_libxml_node_object *object;
+ char **params = NULL;
+ int clone;
+ zval *doXInclude, *member;
+ zend_object_handlers *std_hnd;
+ FILE *f;
+ int secPrefsError = 0;
+ int secPrefsValue, secPrefsIni;
+ xsltSecurityPrefsPtr secPrefs = NULL;
+
+ node = php_libxml_import_node(docp TSRMLS_CC);
+
+ if (node) {
+ doc = node->doc;
+ }
+ if (doc == NULL) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Document");
+ return NULL;
+ }
+
+ if (style == NULL) {
+ 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;
+ } else {
+ f = VCWD_FOPEN(intern->profiling, "w");
+ }
+ } else {
+ f = NULL;
+ }
+
+ if (intern->parameter) {
+ params = php_xsl_xslt_make_params(intern->parameter, 0 TSRMLS_CC);
+ }
+
+ intern->doc = emalloc(sizeof(php_libxml_node_object));
+ memset(intern->doc, 0, sizeof(php_libxml_node_object));
+
+ if (intern->hasKeys == 1) {
+ doc = xmlCopyDoc(doc, 1);
+ } else {
+ object = (php_libxml_node_object *)zend_object_store_get_object(docp TSRMLS_CC);
+ intern->doc->document = object->document;
+ }
+
+ php_libxml_increment_doc_ref(intern->doc, doc TSRMLS_CC);
+
+ ctxt = xsltNewTransformContext(style, doc);
+ ctxt->_private = (void *) intern;
+
+ std_hnd = zend_get_std_object_handlers();
+
+ MAKE_STD_ZVAL(member);
+ ZVAL_STRING(member, "doXInclude", 0);
+ doXInclude = std_hnd->read_property(id, member, BP_VAR_IS, NULL TSRMLS_CC);
+ if (Z_TYPE_P(doXInclude) != IS_NULL) {
+ convert_to_long(doXInclude);
+ ctxt->xinclude = Z_LVAL_P(doXInclude);
+ }
+ 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 */
+ if (secPrefsIni != secPrefsValue) {
+ if (secPrefsIni != XSL_SECPREF_DEFAULT) {
+ /* if the ini value is not set to the default, throw an E_DEPRECATED warning */
+ php_error_docref(NULL TSRMLS_CC, E_DEPRECATED, "The xsl.security_prefs php.ini option is deprecated; use XsltProcessor->setSecurityPrefs() instead");
+ if (intern->securityPrefsSet == 0) {
+ /* if securityPrefs were not set through the setSecurityPrefs method, take the ini setting */
+ secPrefsValue = secPrefsIni;
+ } else {
+ /* else throw a notice, that the ini setting was not used */
+ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "The xsl.security_prefs php.ini was not used, since the XsltProcessor->setSecurityPrefs() method was used");
+ }
+ }
+ }
+
+ /* 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)) {
+ secPrefsError = 1;
+ }
+ }
+ 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)) {
+ secPrefsError = 1;
+ }
+ }
+ 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)) {
+ secPrefsError = 1;
+ }
+ }
+
+ 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 {
+ newdocp = xsltApplyStylesheetUser(style, doc, (const char**) params, NULL, f, ctxt);
+ }
+ if (f) {
+ fclose(f);
+ }
+
+ xsltFreeTransformContext(ctxt);
+ if (secPrefs) {
+ xsltFreeSecurityPrefs(secPrefs);
+ }
+
+ if (intern->node_list != NULL) {
+ zend_hash_destroy(intern->node_list);
+ FREE_HASHTABLE(intern->node_list);
+ intern->node_list = NULL;
+ }
+
+ php_libxml_decrement_doc_ref(intern->doc TSRMLS_CC);
+ efree(intern->doc);
+ intern->doc = NULL;
+
+ if (params) {
+ clone = 0;
+ while(params[clone]) {
+ efree(params[clone++]);
+ }
+ efree(params);
+ }
+
+ return newdocp;
+
+}
+/* }}} */
+
+/* {{{ 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:
+*/
+PHP_FUNCTION(xsl_xsltprocessor_transform_to_doc)
+{
+ zval *id, *docp = NULL;
+ xmlDoc *newdocp;
+ xsltStylesheetPtr sheetp;
+ int ret, ret_class_len=0;
+ char *ret_class = NULL;
+ xsl_object *intern;
+
+ id = getThis();
+ intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
+ sheetp = (xsltStylesheetPtr) intern->ptr;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o|s!", &docp, &ret_class, &ret_class_len) == FAILURE) {
+ RETURN_FALSE;
+ }
+
+ newdocp = php_xsl_apply_stylesheet(id, intern, sheetp, docp TSRMLS_CC);
+
+ if (newdocp) {
+ if (ret_class) {
+ int found;
+ char *curclass_name;
+ zend_class_entry *curce, **ce;
+ php_libxml_node_object *interndoc;
+
+ curce = Z_OBJCE_P(docp);
+ curclass_name = curce->name;
+ while (curce->parent != NULL) {
+ curce = curce->parent;
+ }
+
+ 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,
+ "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);
+ } else {
+ DOM_RET_OBJ((xmlNodePtr) newdocp, &ret, NULL);
+ }
+ } else {
+ RETURN_FALSE;
+ }
+
+}
+/* }}} end xsl_xsltprocessor_transform_to_doc */
+
+/* {{{ proto int xsl_xsltprocessor_transform_to_uri(domdocument doc, string uri);
+*/
+PHP_FUNCTION(xsl_xsltprocessor_transform_to_uri)
+{
+ zval *id, *docp = NULL;
+ xmlDoc *newdocp;
+ xsltStylesheetPtr sheetp;
+ 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;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "op", &docp, &uri, &uri_len) == FAILURE) {
+ RETURN_FALSE;
+ }
+
+ newdocp = php_xsl_apply_stylesheet(id, intern, sheetp, docp TSRMLS_CC);
+
+ ret = -1;
+ if (newdocp) {
+ ret = xsltSaveResultToFilename(uri, newdocp, sheetp, 0);
+ xmlFreeDoc(newdocp);
+ }
+
+ RETVAL_LONG(ret);
+}
+/* }}} end xsl_xsltprocessor_transform_to_uri */
+
+/* {{{ proto string xsl_xsltprocessor_transform_to_xml(domdocument doc);
+*/
+PHP_FUNCTION(xsl_xsltprocessor_transform_to_xml)
+{
+ zval *id, *docp = NULL;
+ xmlDoc *newdocp;
+ xsltStylesheetPtr sheetp;
+ int ret;
+ 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;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &docp) == FAILURE) {
+ RETURN_FALSE;
+ }
+
+ newdocp = php_xsl_apply_stylesheet(id, intern, sheetp, docp TSRMLS_CC);
+
+ ret = -1;
+ if (newdocp) {
+ ret = xsltSaveResultToString(&doc_txt_ptr, &doc_txt_len, newdocp, sheetp);
+ if (doc_txt_ptr && doc_txt_len) {
+ RETVAL_STRINGL(doc_txt_ptr, doc_txt_len, 1);
+ xmlFree(doc_txt_ptr);
+ }
+ xmlFreeDoc(newdocp);
+ }
+
+ if (ret < 0) {
+ RETURN_FALSE;
+ }
+}
+/* }}} end xsl_xsltprocessor_transform_to_xml */
+
+/* {{{ proto bool xsl_xsltprocessor_set_parameter(string namespace, mixed name [, string value]);
+*/
+PHP_FUNCTION(xsl_xsltprocessor_set_parameter)
+{
+
+ zval *id;
+ zval *array_value, **entry, *new_string;
+ xsl_object *intern;
+ char *string_key, *name, *value, *namespace;
+ ulong idx;
+ int string_key_len, namespace_len, name_len, value_len;
+ DOM_GET_THIS(id);
+
+ if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "sa", &namespace, &namespace_len, &array_value) == SUCCESS) {
+ intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
+ zend_hash_internal_pointer_reset(Z_ARRVAL_P(array_value));
+
+ 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 */
+
+/* {{{ proto string xsl_xsltprocessor_get_parameter(string namespace, string name);
+*/
+PHP_FUNCTION(xsl_xsltprocessor_get_parameter)
+{
+ zval *id;
+ int name_len = 0, namespace_len = 0;
+ char *name, *namespace;
+ zval **value;
+ 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;
+ }
+ intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
+ if ( zend_hash_find(intern->parameter, name, name_len + 1, (void**) &value) == SUCCESS) {
+ convert_to_string_ex(value);
+ RETVAL_STRING(Z_STRVAL_PP(value),1);
+ } else {
+ RETURN_FALSE;
+ }
+}
+/* }}} end xsl_xsltprocessor_get_parameter */
+
+/* {{{ proto bool xsl_xsltprocessor_remove_parameter(string namespace, string name);
+*/
+PHP_FUNCTION(xsl_xsltprocessor_remove_parameter)
+{
+ zval *id;
+ int name_len = 0, namespace_len = 0;
+ char *name, *namespace;
+ 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;
+ }
+ intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
+ if ( zend_hash_del(intern->parameter, name, name_len + 1) == SUCCESS) {
+ RETURN_TRUE;
+ } else {
+ RETURN_FALSE;
+ }
+}
+/* }}} end xsl_xsltprocessor_remove_parameter */
+
+/* {{{ proto void xsl_xsltprocessor_register_php_functions([mixed $restrict]);
+*/
+PHP_FUNCTION(xsl_xsltprocessor_register_php_functions)
+{
+ zval *id;
+ xsl_object *intern;
+ zval *array_value, **entry, *new_string;
+ int name_len = 0;
+ 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));
+
+ 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));
+ }
+ intern->registerPhpFunctions = 2;
+
+ } 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(); */
+
+/* {{{ proto bool xsl_xsltprocessor_set_profiling(string filename) */
+PHP_FUNCTION(xsl_xsltprocessor_set_profiling)
+{
+ zval *id;
+ xsl_object *intern;
+ char *filename = NULL;
+ int filename_len;
+ DOM_GET_THIS(id);
+
+ if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "p!", &filename, &filename_len) == SUCCESS) {
+ intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
+ if (intern->profiling) {
+ efree(intern->profiling);
+ }
+ if (filename != NULL) {
+ intern->profiling = estrndup(filename,filename_len);
+ } else {
+ intern->profiling = NULL;
+ }
+ RETURN_TRUE;
+ } else {
+ WRONG_PARAM_COUNT;
+ }
+}
+/* }}} end xsl_xsltprocessor_set_profiling */
+
+/* {{{ proto long xsl_xsltprocessor_set_security_prefs(long securityPrefs) */
+PHP_FUNCTION(xsl_xsltprocessor_set_security_prefs)
+{
+ zval *id;
+ xsl_object *intern;
+ long securityPrefs, oldSecurityPrefs;
+
+ DOM_GET_THIS(id);
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &securityPrefs) == FAILURE) {
+ return;
+ }
+ intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
+ 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;
+ RETURN_LONG(oldSecurityPrefs);
+}
+/* }}} end xsl_xsltprocessor_set_security_prefs */
+
+/* {{{ proto long xsl_xsltprocessor_get_security_prefs() */
+PHP_FUNCTION(xsl_xsltprocessor_get_security_prefs)
+{
+ zval *id;
+ xsl_object *intern;
+
+ DOM_GET_THIS(id);
+ if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "") == SUCCESS) {
+ intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
+ RETURN_LONG(intern->securityPrefs);
+ } else {
+ WRONG_PARAM_COUNT;
+ }
+}
+/* }}} end xsl_xsltprocessor_get_security_prefs */
+
+
+
+/* {{{ proto bool xsl_xsltprocessor_has_exslt_support();
+*/
+PHP_FUNCTION(xsl_xsltprocessor_has_exslt_support)
+{
+#if HAVE_XSL_EXSLT
+ RETURN_TRUE;
+#else
+ RETURN_FALSE;
+#endif
+}
+/* }}} end xsl_xsltprocessor_has_exslt_support(); */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: sw=4 ts=4 fdm=marker
+ * vim<600: sw=4 ts=4
+ */