xref: /PHP-5.5/ext/xsl/php_xsl.c (revision 73c1be26)
1 /*
2   +----------------------------------------------------------------------+
3   | PHP Version 5                                                        |
4   +----------------------------------------------------------------------+
5   | Copyright (c) 1997-2015 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 
119 	intern = emalloc(sizeof(xsl_object));
120 	intern->ptr = NULL;
121 	intern->prop_handler = NULL;
122 	intern->parameter = NULL;
123 	intern->hasKeys = 0;
124 	intern->registerPhpFunctions = 0;
125 	intern->registered_phpfunctions = NULL;
126 	intern->node_list = NULL;
127 	intern->doc = NULL;
128 	intern->profiling = NULL;
129 	intern->securityPrefs = XSL_SECPREF_DEFAULT;
130 	intern->securityPrefsSet = 0;
131 
132 	zend_object_std_init(&intern->std, class_type TSRMLS_CC);
133 	object_properties_init(&intern->std, class_type);
134 	ALLOC_HASHTABLE(intern->parameter);
135 	zend_hash_init(intern->parameter, 0, NULL, ZVAL_PTR_DTOR, 0);
136 	ALLOC_HASHTABLE(intern->registered_phpfunctions);
137 	zend_hash_init(intern->registered_phpfunctions, 0, NULL, ZVAL_PTR_DTOR, 0);
138 	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);
139 	intern->handle = retval.handle;
140 	retval.handlers = &xsl_object_handlers;
141 	return retval;
142 }
143 /* }}} */
144 
145 PHP_INI_BEGIN()
146 /* Default is not allowing any write operations.
147    XSL_SECPREF_CREATE_DIRECTORY | XSL_SECPREF_WRITE_NETWORK | XSL_SECPREF_WRITE_FILE == 44
148 */
149 PHP_INI_ENTRY("xsl.security_prefs", "44", PHP_INI_ALL, NULL)
PHP_INI_END()150 PHP_INI_END()
151 
152 /* {{{ PHP_MINIT_FUNCTION
153  */
154 PHP_MINIT_FUNCTION(xsl)
155 {
156 
157 	zend_class_entry ce;
158 
159 	memcpy(&xsl_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
160 	xsl_object_handlers.clone_obj = NULL;
161 
162 	REGISTER_XSL_CLASS(ce, "XSLTProcessor", NULL, php_xsl_xsltprocessor_class_functions, xsl_xsltprocessor_class_entry);
163 #if HAVE_XSL_EXSLT
164 	exsltRegisterAll();
165 #endif
166 
167 	xsltRegisterExtModuleFunction ((const xmlChar *) "functionString",
168 				   (const xmlChar *) "http://php.net/xsl",
169 				   xsl_ext_function_string_php);
170 	xsltRegisterExtModuleFunction ((const xmlChar *) "function",
171 				   (const xmlChar *) "http://php.net/xsl",
172 				   xsl_ext_function_object_php);
173 
174 	REGISTER_LONG_CONSTANT("XSL_CLONE_AUTO",      0,     CONST_CS | CONST_PERSISTENT);
175 	REGISTER_LONG_CONSTANT("XSL_CLONE_NEVER",    -1,     CONST_CS | CONST_PERSISTENT);
176 	REGISTER_LONG_CONSTANT("XSL_CLONE_ALWAYS",    1,     CONST_CS | CONST_PERSISTENT);
177 
178 	REGISTER_LONG_CONSTANT("XSL_SECPREF_NONE",             XSL_SECPREF_NONE,             CONST_CS | CONST_PERSISTENT);
179 	REGISTER_LONG_CONSTANT("XSL_SECPREF_READ_FILE",        XSL_SECPREF_READ_FILE,        CONST_CS | CONST_PERSISTENT);
180 	REGISTER_LONG_CONSTANT("XSL_SECPREF_WRITE_FILE",       XSL_SECPREF_WRITE_FILE,       CONST_CS | CONST_PERSISTENT);
181 	REGISTER_LONG_CONSTANT("XSL_SECPREF_CREATE_DIRECTORY", XSL_SECPREF_CREATE_DIRECTORY, CONST_CS | CONST_PERSISTENT);
182 	REGISTER_LONG_CONSTANT("XSL_SECPREF_READ_NETWORK",     XSL_SECPREF_READ_NETWORK,     CONST_CS | CONST_PERSISTENT);
183 	REGISTER_LONG_CONSTANT("XSL_SECPREF_WRITE_NETWORK",    XSL_SECPREF_WRITE_NETWORK,    CONST_CS | CONST_PERSISTENT);
184 	REGISTER_LONG_CONSTANT("XSL_SECPREF_DEFAULT",          XSL_SECPREF_DEFAULT,          CONST_CS | CONST_PERSISTENT);
185 
186 	REGISTER_LONG_CONSTANT("LIBXSLT_VERSION",           LIBXSLT_VERSION,            CONST_CS | CONST_PERSISTENT);
187 	REGISTER_STRING_CONSTANT("LIBXSLT_DOTTED_VERSION",  LIBXSLT_DOTTED_VERSION,     CONST_CS | CONST_PERSISTENT);
188 
189 #if HAVE_XSL_EXSLT
190 	REGISTER_LONG_CONSTANT("LIBEXSLT_VERSION",           LIBEXSLT_VERSION,            CONST_CS | CONST_PERSISTENT);
191 	REGISTER_STRING_CONSTANT("LIBEXSLT_DOTTED_VERSION",  LIBEXSLT_DOTTED_VERSION,     CONST_CS | CONST_PERSISTENT);
192 #endif
193 
194     REGISTER_INI_ENTRIES();
195 
196 	return SUCCESS;
197 }
198 /* }}} */
199 
200 /* {{{ xsl_object_get_data */
xsl_object_get_data(void * obj)201 zval *xsl_object_get_data(void *obj)
202 {
203 	zval *dom_wrapper;
204 	dom_wrapper = ((xsltStylesheetPtr) obj)->_private;
205 	return dom_wrapper;
206 }
207 /* }}} */
208 
209 /* {{{ xsl_object_set_data */
xsl_object_set_data(void * obj,zval * wrapper TSRMLS_DC)210 static void xsl_object_set_data(void *obj, zval *wrapper TSRMLS_DC)
211 {
212 	((xsltStylesheetPtr) obj)->_private = wrapper;
213 }
214 /* }}} */
215 
216 /* {{{ php_xsl_set_object */
php_xsl_set_object(zval * wrapper,void * obj TSRMLS_DC)217 void php_xsl_set_object(zval *wrapper, void *obj TSRMLS_DC)
218 {
219 	xsl_object *object;
220 
221 	object = (xsl_object *)zend_objects_get_address(wrapper TSRMLS_CC);
222 	object->ptr = obj;
223 	xsl_object_set_data(obj, wrapper TSRMLS_CC);
224 }
225 /* }}} */
226 
227 /* {{{ php_xsl_create_object */
php_xsl_create_object(xsltStylesheetPtr obj,int * found,zval * wrapper_in,zval * return_value TSRMLS_DC)228 zval *php_xsl_create_object(xsltStylesheetPtr obj, int *found, zval *wrapper_in, zval *return_value  TSRMLS_DC)
229 {
230 	zval *wrapper;
231 	zend_class_entry *ce;
232 
233 	*found = 0;
234 
235 	if (!obj) {
236 		if(!wrapper_in) {
237 			ALLOC_ZVAL(wrapper);
238 		} else {
239 			wrapper = wrapper_in;
240 		}
241 		ZVAL_NULL(wrapper);
242 		return wrapper;
243 	}
244 
245 	if ((wrapper = (zval *) xsl_object_get_data((void *) obj))) {
246 		zval_add_ref(&wrapper);
247 		*found = 1;
248 		return wrapper;
249 	}
250 
251 	if(!wrapper_in) {
252 		wrapper = return_value;
253 	} else {
254 		wrapper = wrapper_in;
255 	}
256 
257 
258 	ce = xsl_xsltprocessor_class_entry;
259 
260 	if(!wrapper_in) {
261 		object_init_ex(wrapper, ce);
262 	}
263 	php_xsl_set_object(wrapper, (void *) obj TSRMLS_CC);
264 	return (wrapper);
265 }
266 /* }}} */
267 
268 /* {{{ PHP_MSHUTDOWN_FUNCTION
269  */
PHP_MSHUTDOWN_FUNCTION(xsl)270 PHP_MSHUTDOWN_FUNCTION(xsl)
271 {
272 	xsltUnregisterExtModuleFunction ((const xmlChar *) "functionString",
273 				   (const xmlChar *) "http://php.net/xsl");
274 	xsltUnregisterExtModuleFunction ((const xmlChar *) "function",
275 				   (const xmlChar *) "http://php.net/xsl");
276 
277 	xsltCleanupGlobals();
278 
279 	UNREGISTER_INI_ENTRIES();
280 
281 	return SUCCESS;
282 }
283 /* }}} */
284 
285 /* {{{ PHP_RINIT_FUNCTION
286  */
PHP_RINIT_FUNCTION(xsl)287 PHP_RINIT_FUNCTION(xsl)
288 {
289 	xsltSetGenericErrorFunc(NULL, php_libxml_error_handler);
290 	return SUCCESS;
291 }
292 /* }}} */
293 
294 /* {{{ PHP_RSHUTDOWN_FUNCTION
295  */
PHP_RSHUTDOWN_FUNCTION(xsl)296 PHP_RSHUTDOWN_FUNCTION(xsl)
297 {
298 	xsltSetGenericErrorFunc(NULL, NULL);
299 	return SUCCESS;
300 }
301 /* }}} */
302 
303 /* {{{ PHP_MINFO_FUNCTION
304  */
PHP_MINFO_FUNCTION(xsl)305 PHP_MINFO_FUNCTION(xsl)
306 {
307 	php_info_print_table_start();
308 	{
309 		char buffer[128];
310 		int major, minor, subminor;
311 
312 		php_info_print_table_row(2, "XSL", "enabled");
313 		major = xsltLibxsltVersion/10000;
314 		minor = (xsltLibxsltVersion - major * 10000) / 100;
315 		subminor = (xsltLibxsltVersion - major * 10000 - minor * 100);
316 		snprintf(buffer, 128, "%d.%d.%d", major, minor, subminor);
317 		php_info_print_table_row(2, "libxslt Version", buffer);
318 		major = xsltLibxmlVersion/10000;
319 		minor = (xsltLibxmlVersion - major * 10000) / 100;
320 		subminor = (xsltLibxmlVersion - major * 10000 - minor * 100);
321 		snprintf(buffer, 128, "%d.%d.%d", major, minor, subminor);
322 		php_info_print_table_row(2, "libxslt compiled against libxml Version", buffer);
323 	}
324 #if HAVE_XSL_EXSLT
325 	php_info_print_table_row(2, "EXSLT", "enabled");
326 	php_info_print_table_row(2, "libexslt Version", LIBEXSLT_DOTTED_VERSION);
327 #endif
328 	php_info_print_table_end();
329 }
330 /* }}} */
331 
332 /*
333  * Local variables:
334  * tab-width: 4
335  * c-basic-offset: 4
336  * End:
337  * vim600: noet sw=4 ts=4 fdm=marker
338  * vim<600: noet sw=4 ts=4
339  */
340