diff options
Diffstat (limited to 'ext/xsl')
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, '"', ''), 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>"Автово" м.</AREA_NAME> + <AREA_NAME_ENG>m."Avtovo"</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 Binary files differnew file mode 100644 index 0000000..910bb63 --- /dev/null +++ b/ext/xsl/tests/xslt.xsl.gz 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 + */ |