xref: /PHP-5.3/ext/xsl/php_xsl.c (revision a2045ff3)
1 /*
2   +----------------------------------------------------------------------+
3   | PHP Version 5                                                        |
4   +----------------------------------------------------------------------+
5   | Copyright (c) 1997-2013 The PHP Group                                |
6   +----------------------------------------------------------------------+
7   | This source file is subject to version 3.01 of the PHP license,      |
8   | that is bundled with this package in the file LICENSE, and is        |
9   | available through the world-wide-web at the following url:           |
10   | http://www.php.net/license/3_01.txt                                  |
11   | If you did not receive a copy of the PHP license and are unable to   |
12   | obtain it through the world-wide-web, please send a note to          |
13   | license@php.net so we can mail you a copy immediately.               |
14   +----------------------------------------------------------------------+
15   | Author: Christian Stocker <chregu@php.net>                           |
16   +----------------------------------------------------------------------+
17 */
18 
19 /* $Id$ */
20 
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24 
25 #include "php.h"
26 #include "php_ini.h"
27 #include "ext/standard/info.h"
28 #include "php_xsl.h"
29 
30 zend_class_entry *xsl_xsltprocessor_class_entry;
31 static zend_object_handlers xsl_object_handlers;
32 
33 /* {{{ xsl_functions[]
34  *
35  * Every user visible function must have an entry in xsl_functions[].
36  */
37 const zend_function_entry xsl_functions[] = {
38 	PHP_FE_END
39 };
40 /* }}} */
41 
42 static const zend_module_dep xsl_deps[] = {
43 	ZEND_MOD_REQUIRED("libxml")
44 	ZEND_MOD_END
45 };
46 
47 /* {{{ xsl_module_entry
48  */
49 zend_module_entry xsl_module_entry = {
50 #if ZEND_MODULE_API_NO >= 20050617
51 	STANDARD_MODULE_HEADER_EX, NULL,
52 	xsl_deps,
53 #elif ZEND_MODULE_API_NO >= 20010901
54 	STANDARD_MODULE_HEADER,
55 #endif
56 	"xsl",
57 	xsl_functions,
58 	PHP_MINIT(xsl),
59 	PHP_MSHUTDOWN(xsl),
60 	PHP_RINIT(xsl),		/* Replace with NULL if there's nothing to do at request start */
61 	PHP_RSHUTDOWN(xsl),	/* Replace with NULL if there's nothing to do at request end */
62 	PHP_MINFO(xsl),
63 #if ZEND_MODULE_API_NO >= 20010901
64 	"0.1", /* Replace with version number for your extension */
65 #endif
66 	STANDARD_MODULE_PROPERTIES
67 };
68 /* }}} */
69 
70 #ifdef COMPILE_DL_XSL
ZEND_GET_MODULE(xsl)71 ZEND_GET_MODULE(xsl)
72 #endif
73 
74 /* {{{ xsl_objects_free_storage */
75 void xsl_objects_free_storage(void *object TSRMLS_DC)
76 {
77 	xsl_object *intern = (xsl_object *)object;
78 
79 	zend_object_std_dtor(&intern->std TSRMLS_CC);
80 
81 	zend_hash_destroy(intern->parameter);
82 	FREE_HASHTABLE(intern->parameter);
83 
84 	zend_hash_destroy(intern->registered_phpfunctions);
85 	FREE_HASHTABLE(intern->registered_phpfunctions);
86 
87 	if (intern->node_list) {
88 		zend_hash_destroy(intern->node_list);
89 		FREE_HASHTABLE(intern->node_list);
90 	}
91 
92 	if (intern->doc) {
93 		php_libxml_decrement_doc_ref(intern->doc TSRMLS_CC);
94 		efree(intern->doc);
95 	}
96 
97 	if (intern->ptr) {
98 		/* free wrapper */
99 		if (((xsltStylesheetPtr) intern->ptr)->_private != NULL) {
100 			((xsltStylesheetPtr) intern->ptr)->_private = NULL;
101 		}
102 
103 		xsltFreeStylesheet((xsltStylesheetPtr) intern->ptr);
104 		intern->ptr = NULL;
105 	}
106 	if (intern->profiling) {
107 		efree(intern->profiling);
108 	}
109 	efree(object);
110 }
111 /* }}} */
112 
113 /* {{{ xsl_objects_new */
xsl_objects_new(zend_class_entry * class_type TSRMLS_DC)114 zend_object_value xsl_objects_new(zend_class_entry *class_type TSRMLS_DC)
115 {
116 	zend_object_value retval;
117 	xsl_object *intern;
118 	zval *tmp;
119 
120 	intern = emalloc(sizeof(xsl_object));
121 	intern->ptr = NULL;
122 	intern->prop_handler = NULL;
123 	intern->parameter = NULL;
124 	intern->hasKeys = 0;
125 	intern->registerPhpFunctions = 0;
126 	intern->registered_phpfunctions = NULL;
127 	intern->node_list = NULL;
128 	intern->doc = NULL;
129 	intern->profiling = NULL;
130 
131 	zend_object_std_init(&intern->std, class_type TSRMLS_CC);
132 	zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_property_ctor, (void *) &tmp, sizeof(zval *));
133 	ALLOC_HASHTABLE(intern->parameter);
134 	zend_hash_init(intern->parameter, 0, NULL, ZVAL_PTR_DTOR, 0);
135 	ALLOC_HASHTABLE(intern->registered_phpfunctions);
136 	zend_hash_init(intern->registered_phpfunctions, 0, NULL, ZVAL_PTR_DTOR, 0);
137 	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);
138 	intern->handle = retval.handle;
139 	retval.handlers = &xsl_object_handlers;
140 	return retval;
141 }
142 /* }}} */
143 
144 PHP_INI_BEGIN()
145 /* Default is not allowing any write operations.
146    XSL_SECPREF_CREATE_DIRECTORY | XSL_SECPREF_WRITE_NETWORK | XSL_SECPREF_WRITE_FILE == 44
147 */
148 PHP_INI_ENTRY("xsl.security_prefs", "44", PHP_INI_ALL, NULL)
PHP_INI_END()149 PHP_INI_END()
150 
151 /* {{{ PHP_MINIT_FUNCTION
152  */
153 PHP_MINIT_FUNCTION(xsl)
154 {
155 
156 	zend_class_entry ce;
157 
158 	memcpy(&xsl_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
159 	xsl_object_handlers.clone_obj = NULL;
160 
161 	REGISTER_XSL_CLASS(ce, "XSLTProcessor", NULL, php_xsl_xsltprocessor_class_functions, xsl_xsltprocessor_class_entry);
162 #if HAVE_XSL_EXSLT
163 	exsltRegisterAll();
164 #endif
165 
166 	xsltRegisterExtModuleFunction ((const xmlChar *) "functionString",
167 				   (const xmlChar *) "http://php.net/xsl",
168 				   xsl_ext_function_string_php);
169 	xsltRegisterExtModuleFunction ((const xmlChar *) "function",
170 				   (const xmlChar *) "http://php.net/xsl",
171 				   xsl_ext_function_object_php);
172 
173 	REGISTER_LONG_CONSTANT("XSL_CLONE_AUTO",      0,     CONST_CS | CONST_PERSISTENT);
174 	REGISTER_LONG_CONSTANT("XSL_CLONE_NEVER",    -1,     CONST_CS | CONST_PERSISTENT);
175 	REGISTER_LONG_CONSTANT("XSL_CLONE_ALWAYS",    1,     CONST_CS | CONST_PERSISTENT);
176 
177 	REGISTER_LONG_CONSTANT("XSL_SECPREF_NONE",             XSL_SECPREF_NONE,             CONST_CS | CONST_PERSISTENT);
178 	REGISTER_LONG_CONSTANT("XSL_SECPREF_READ_FILE",        XSL_SECPREF_READ_FILE,        CONST_CS | CONST_PERSISTENT);
179 	REGISTER_LONG_CONSTANT("XSL_SECPREF_WRITE_FILE",       XSL_SECPREF_WRITE_FILE,       CONST_CS | CONST_PERSISTENT);
180 	REGISTER_LONG_CONSTANT("XSL_SECPREF_CREATE_DIRECTORY", XSL_SECPREF_CREATE_DIRECTORY, CONST_CS | CONST_PERSISTENT);
181 	REGISTER_LONG_CONSTANT("XSL_SECPREF_READ_NETWORK",     XSL_SECPREF_READ_NETWORK,     CONST_CS | CONST_PERSISTENT);
182 	REGISTER_LONG_CONSTANT("XSL_SECPREF_WRITE_NETWORK",    XSL_SECPREF_WRITE_NETWORK,    CONST_CS | CONST_PERSISTENT);
183 	REGISTER_LONG_CONSTANT("XSL_SECPREF_DEFAULT",          XSL_SECPREF_DEFAULT,          CONST_CS | CONST_PERSISTENT);
184 
185 	REGISTER_LONG_CONSTANT("LIBXSLT_VERSION",           LIBXSLT_VERSION,            CONST_CS | CONST_PERSISTENT);
186 	REGISTER_STRING_CONSTANT("LIBXSLT_DOTTED_VERSION",  LIBXSLT_DOTTED_VERSION,     CONST_CS | CONST_PERSISTENT);
187 
188 #if HAVE_XSL_EXSLT
189 	REGISTER_LONG_CONSTANT("LIBEXSLT_VERSION",           LIBEXSLT_VERSION,            CONST_CS | CONST_PERSISTENT);
190 	REGISTER_STRING_CONSTANT("LIBEXSLT_DOTTED_VERSION",  LIBEXSLT_DOTTED_VERSION,     CONST_CS | CONST_PERSISTENT);
191 #endif
192 
193     REGISTER_INI_ENTRIES();
194 
195 	return SUCCESS;
196 }
197 /* }}} */
198 
199 /* {{{ xsl_object_get_data */
xsl_object_get_data(void * obj)200 zval *xsl_object_get_data(void *obj)
201 {
202 	zval *dom_wrapper;
203 	dom_wrapper = ((xsltStylesheetPtr) obj)->_private;
204 	return dom_wrapper;
205 }
206 /* }}} */
207 
208 /* {{{ xsl_object_set_data */
xsl_object_set_data(void * obj,zval * wrapper TSRMLS_DC)209 static void xsl_object_set_data(void *obj, zval *wrapper TSRMLS_DC)
210 {
211 	((xsltStylesheetPtr) obj)->_private = wrapper;
212 }
213 /* }}} */
214 
215 /* {{{ php_xsl_set_object */
php_xsl_set_object(zval * wrapper,void * obj TSRMLS_DC)216 void php_xsl_set_object(zval *wrapper, void *obj TSRMLS_DC)
217 {
218 	xsl_object *object;
219 
220 	object = (xsl_object *)zend_objects_get_address(wrapper TSRMLS_CC);
221 	object->ptr = obj;
222 	xsl_object_set_data(obj, wrapper TSRMLS_CC);
223 }
224 /* }}} */
225 
226 /* {{{ php_xsl_create_object */
php_xsl_create_object(xsltStylesheetPtr obj,int * found,zval * wrapper_in,zval * return_value TSRMLS_DC)227 zval *php_xsl_create_object(xsltStylesheetPtr obj, int *found, zval *wrapper_in, zval *return_value  TSRMLS_DC)
228 {
229 	zval *wrapper;
230 	zend_class_entry *ce;
231 
232 	*found = 0;
233 
234 	if (!obj) {
235 		if(!wrapper_in) {
236 			ALLOC_ZVAL(wrapper);
237 		} else {
238 			wrapper = wrapper_in;
239 		}
240 		ZVAL_NULL(wrapper);
241 		return wrapper;
242 	}
243 
244 	if ((wrapper = (zval *) xsl_object_get_data((void *) obj))) {
245 		zval_add_ref(&wrapper);
246 		*found = 1;
247 		return wrapper;
248 	}
249 
250 	if(!wrapper_in) {
251 		wrapper = return_value;
252 	} else {
253 		wrapper = wrapper_in;
254 	}
255 
256 
257 	ce = xsl_xsltprocessor_class_entry;
258 
259 	if(!wrapper_in) {
260 		object_init_ex(wrapper, ce);
261 	}
262 	php_xsl_set_object(wrapper, (void *) obj TSRMLS_CC);
263 	return (wrapper);
264 }
265 /* }}} */
266 
267 /* {{{ PHP_MSHUTDOWN_FUNCTION
268  */
PHP_MSHUTDOWN_FUNCTION(xsl)269 PHP_MSHUTDOWN_FUNCTION(xsl)
270 {
271 	xsltUnregisterExtModuleFunction ((const xmlChar *) "functionString",
272 				   (const xmlChar *) "http://php.net/xsl");
273 	xsltUnregisterExtModuleFunction ((const xmlChar *) "function",
274 				   (const xmlChar *) "http://php.net/xsl");
275 
276 	xsltCleanupGlobals();
277 
278 	UNREGISTER_INI_ENTRIES();
279 
280 	return SUCCESS;
281 }
282 /* }}} */
283 
284 /* {{{ PHP_RINIT_FUNCTION
285  */
PHP_RINIT_FUNCTION(xsl)286 PHP_RINIT_FUNCTION(xsl)
287 {
288 	xsltSetGenericErrorFunc(NULL, php_libxml_error_handler);
289 	return SUCCESS;
290 }
291 /* }}} */
292 
293 /* {{{ PHP_RSHUTDOWN_FUNCTION
294  */
PHP_RSHUTDOWN_FUNCTION(xsl)295 PHP_RSHUTDOWN_FUNCTION(xsl)
296 {
297 	xsltSetGenericErrorFunc(NULL, NULL);
298 	return SUCCESS;
299 }
300 /* }}} */
301 
302 /* {{{ PHP_MINFO_FUNCTION
303  */
PHP_MINFO_FUNCTION(xsl)304 PHP_MINFO_FUNCTION(xsl)
305 {
306 	php_info_print_table_start();
307 	{
308 		char buffer[128];
309 		int major, minor, subminor;
310 
311 		php_info_print_table_row(2, "XSL", "enabled");
312 		major = xsltLibxsltVersion/10000;
313 		minor = (xsltLibxsltVersion - major * 10000) / 100;
314 		subminor = (xsltLibxsltVersion - major * 10000 - minor * 100);
315 		snprintf(buffer, 128, "%d.%d.%d", major, minor, subminor);
316 		php_info_print_table_row(2, "libxslt Version", buffer);
317 		major = xsltLibxmlVersion/10000;
318 		minor = (xsltLibxmlVersion - major * 10000) / 100;
319 		subminor = (xsltLibxmlVersion - major * 10000 - minor * 100);
320 		snprintf(buffer, 128, "%d.%d.%d", major, minor, subminor);
321 		php_info_print_table_row(2, "libxslt compiled against libxml Version", buffer);
322 	}
323 #if HAVE_XSL_EXSLT
324 	php_info_print_table_row(2, "EXSLT", "enabled");
325 	php_info_print_table_row(2, "libexslt Version", LIBEXSLT_DOTTED_VERSION);
326 #endif
327 	php_info_print_table_end();
328 }
329 /* }}} */
330 
331 /*
332  * Local variables:
333  * tab-width: 4
334  * c-basic-offset: 4
335  * End:
336  * vim600: noet sw=4 ts=4 fdm=marker
337  * vim<600: noet sw=4 ts=4
338  */
339