Annotation of embedaddon/php/ext/xsl/xsltprocessor.c, revision 1.1.1.2
1.1 misho 1: /*
2: +----------------------------------------------------------------------+
3: | PHP Version 5 |
4: +----------------------------------------------------------------------+
5: | Copyright (c) 1997-2012 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: | Authors: Christian Stocker <chregu@php.net> |
16: | Rob Richards <rrichards@php.net> |
17: +----------------------------------------------------------------------+
18: */
19:
1.1.1.2 ! misho 20: /* $Id$ */
1.1 misho 21:
22: #ifdef HAVE_CONFIG_H
23: #include "config.h"
24: #endif
25:
26: #include "php.h"
27: #include "php_xsl.h"
28: #include "ext/libxml/php_libxml.h"
29:
30: /* {{{ arginfo */
31: ZEND_BEGIN_ARG_INFO_EX(arginfo_xsl_xsltprocessor_import_stylesheet, 0, 0, 1)
32: ZEND_ARG_INFO(0, doc)
33: ZEND_END_ARG_INFO();
34:
35: ZEND_BEGIN_ARG_INFO_EX(arginfo_xsl_xsltprocessor_transform_to_doc, 0, 0, 1)
36: ZEND_ARG_INFO(0, doc)
37: ZEND_END_ARG_INFO();
38:
39: ZEND_BEGIN_ARG_INFO_EX(arginfo_xsl_xsltprocessor_transform_to_uri, 0, 0, 2)
40: ZEND_ARG_INFO(0, doc)
41: ZEND_ARG_INFO(0, uri)
42: ZEND_END_ARG_INFO();
43:
44: ZEND_BEGIN_ARG_INFO_EX(arginfo_xsl_xsltprocessor_transform_to_xml, 0, 0, 1)
45: ZEND_ARG_INFO(0, doc)
46: ZEND_END_ARG_INFO();
47:
48: ZEND_BEGIN_ARG_INFO_EX(arginfo_xsl_xsltprocessor_set_parameter, 0, 0, 2)
49: ZEND_ARG_INFO(0, namespace)
50: ZEND_ARG_INFO(0, name)
51: ZEND_ARG_INFO(0, value)
52: ZEND_END_ARG_INFO();
53:
54: ZEND_BEGIN_ARG_INFO_EX(arginfo_xsl_xsltprocessor_get_parameter, 0, 0, 2)
55: ZEND_ARG_INFO(0, namespace)
56: ZEND_ARG_INFO(0, name)
57: ZEND_END_ARG_INFO();
58:
59: ZEND_BEGIN_ARG_INFO_EX(arginfo_xsl_xsltprocessor_remove_parameter, 0, 0, 2)
60: ZEND_ARG_INFO(0, namespace)
61: ZEND_ARG_INFO(0, name)
62: ZEND_END_ARG_INFO();
63:
64: ZEND_BEGIN_ARG_INFO_EX(arginfo_xsl_xsltprocessor_has_exslt_support, 0, 0, 0)
65: ZEND_END_ARG_INFO();
66:
67: ZEND_BEGIN_ARG_INFO_EX(arginfo_xsl_xsltprocessor_register_php_functions, 0, 0, 0)
68: ZEND_ARG_INFO(0, restrict)
69: ZEND_END_ARG_INFO();
70:
71: ZEND_BEGIN_ARG_INFO_EX(arginfo_xsl_xsltprocessor_set_profiling, 0, 0, 1)
72: ZEND_ARG_INFO(0, filename)
73: ZEND_END_ARG_INFO();
1.1.1.2 ! misho 74:
! 75: ZEND_BEGIN_ARG_INFO_EX(arginfo_xsl_xsltprocessor_set_security_prefs, 0, 0, 1)
! 76: ZEND_ARG_INFO(0, securityPrefs)
! 77: ZEND_END_ARG_INFO();
! 78:
! 79: ZEND_BEGIN_ARG_INFO_EX(arginfo_xsl_xsltprocessor_get_security_prefs, 0, 0, 0)
! 80: ZEND_END_ARG_INFO();
1.1 misho 81: /* }}} */
82:
83: /*
84: * class xsl_xsltprocessor
85: *
86: * URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#
87: * Since:
88: */
89:
90: const zend_function_entry php_xsl_xsltprocessor_class_functions[] = {
91: PHP_FALIAS(importStylesheet, xsl_xsltprocessor_import_stylesheet, arginfo_xsl_xsltprocessor_import_stylesheet)
92: PHP_FALIAS(transformToDoc, xsl_xsltprocessor_transform_to_doc, arginfo_xsl_xsltprocessor_transform_to_doc)
93: PHP_FALIAS(transformToUri, xsl_xsltprocessor_transform_to_uri, arginfo_xsl_xsltprocessor_transform_to_uri)
94: PHP_FALIAS(transformToXml, xsl_xsltprocessor_transform_to_xml, arginfo_xsl_xsltprocessor_transform_to_xml)
95: PHP_FALIAS(setParameter, xsl_xsltprocessor_set_parameter, arginfo_xsl_xsltprocessor_set_parameter)
96: PHP_FALIAS(getParameter, xsl_xsltprocessor_get_parameter, arginfo_xsl_xsltprocessor_get_parameter)
97: PHP_FALIAS(removeParameter, xsl_xsltprocessor_remove_parameter, arginfo_xsl_xsltprocessor_remove_parameter)
98: PHP_FALIAS(hasExsltSupport, xsl_xsltprocessor_has_exslt_support, arginfo_xsl_xsltprocessor_has_exslt_support)
99: PHP_FALIAS(registerPHPFunctions, xsl_xsltprocessor_register_php_functions, arginfo_xsl_xsltprocessor_register_php_functions)
100: PHP_FALIAS(setProfiling, xsl_xsltprocessor_set_profiling, arginfo_xsl_xsltprocessor_set_profiling)
1.1.1.2 ! misho 101: PHP_FALIAS(setSecurityPrefs, xsl_xsltprocessor_set_security_prefs, arginfo_xsl_xsltprocessor_set_security_prefs)
! 102: PHP_FALIAS(getSecurityPrefs, xsl_xsltprocessor_get_security_prefs, arginfo_xsl_xsltprocessor_get_security_prefs)
1.1 misho 103: {NULL, NULL, NULL}
104: };
105:
106: /* {{{ php_xsl_xslt_string_to_xpathexpr()
107: Translates a string to a XPath Expression */
108: static char *php_xsl_xslt_string_to_xpathexpr(const char *str TSRMLS_DC)
109: {
110: const xmlChar *string = (const xmlChar *)str;
111:
112: xmlChar *value;
113: int str_len;
114:
115: str_len = xmlStrlen(string) + 3;
116:
117: if (xmlStrchr(string, '"')) {
118: if (xmlStrchr(string, '\'')) {
119: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create XPath expression (string contains both quote and double-quotes)");
120: return NULL;
121: }
122: value = (xmlChar*) safe_emalloc (str_len, sizeof(xmlChar), 0);
123: snprintf(value, str_len, "'%s'", string);
124: } else {
125: value = (xmlChar*) safe_emalloc (str_len, sizeof(xmlChar), 0);
126: snprintf(value, str_len, "\"%s\"", string);
127: }
128: return (char *) value;
129: }
130: /* }}} */
131:
132: /* {{{ php_xsl_xslt_make_params()
133: Translates a PHP array to a libxslt parameters array */
134: static char **php_xsl_xslt_make_params(HashTable *parht, int xpath_params TSRMLS_DC)
135: {
136:
137: int parsize;
138: zval **value;
139: char *xpath_expr, *string_key = NULL;
140: ulong num_key;
141: char **params = NULL;
142: int i = 0;
143:
144: parsize = (2 * zend_hash_num_elements(parht) + 1) * sizeof(char *);
145: params = (char **)safe_emalloc((2 * zend_hash_num_elements(parht) + 1), sizeof(char *), 0);
146: memset((char *)params, 0, parsize);
147:
148: for (zend_hash_internal_pointer_reset(parht);
149: zend_hash_get_current_data(parht, (void **)&value) == SUCCESS;
150: zend_hash_move_forward(parht)) {
151:
152: if (zend_hash_get_current_key(parht, &string_key, &num_key, 1) != HASH_KEY_IS_STRING) {
153: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid argument or parameter array");
154: efree(params);
155: return NULL;
156: } else {
157: if (Z_TYPE_PP(value) != IS_STRING) {
158: SEPARATE_ZVAL(value);
159: convert_to_string(*value);
160: }
161:
162: if (!xpath_params) {
163: xpath_expr = php_xsl_xslt_string_to_xpathexpr(Z_STRVAL_PP(value) TSRMLS_CC);
164: } else {
165: xpath_expr = estrndup(Z_STRVAL_PP(value), Z_STRLEN_PP(value));
166: }
167: if (xpath_expr) {
168: params[i++] = string_key;
169: params[i++] = xpath_expr;
170: } else {
171: efree(string_key);
172: }
173: }
174: }
175:
176: params[i++] = NULL;
177:
178: return params;
179: }
180: /* }}} */
181:
182: static void xsl_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs, int type) /* {{{ */
183: {
184: xsltTransformContextPtr tctxt;
185: zval **args;
186: zval *retval;
187: int result, i, ret;
188: int error = 0;
189: zend_fcall_info fci;
190: zval handler;
191: xmlXPathObjectPtr obj;
192: char *str;
193: char *callable = NULL;
194: xsl_object *intern;
195:
196: TSRMLS_FETCH();
197:
198: if (! zend_is_executing(TSRMLS_C)) {
199: xsltGenericError(xsltGenericErrorContext,
200: "xsltExtFunctionTest: Function called from outside of PHP\n");
201: error = 1;
202: } else {
203: tctxt = xsltXPathGetTransformContext(ctxt);
204: if (tctxt == NULL) {
205: xsltGenericError(xsltGenericErrorContext,
206: "xsltExtFunctionTest: failed to get the transformation context\n");
207: error = 1;
208: } else {
209: intern = (xsl_object *) tctxt->_private;
210: if (intern == NULL) {
211: xsltGenericError(xsltGenericErrorContext,
212: "xsltExtFunctionTest: failed to get the internal object\n");
213: error = 1;
214: }
215: else if (intern->registerPhpFunctions == 0) {
216: xsltGenericError(xsltGenericErrorContext,
217: "xsltExtFunctionTest: PHP Object did not register PHP functions\n");
218: error = 1;
219: }
220: }
221: }
222:
223: if (error == 1) {
224: for (i = nargs - 1; i >= 0; i--) {
225: obj = valuePop(ctxt);
226: xmlXPathFreeObject(obj);
227: }
228: return;
229: }
230:
231: fci.param_count = nargs - 1;
232: if (fci.param_count > 0) {
233: fci.params = safe_emalloc(fci.param_count, sizeof(zval**), 0);
234: args = safe_emalloc(fci.param_count, sizeof(zval *), 0);
235: }
236: /* Reverse order to pop values off ctxt stack */
237: for (i = nargs - 2; i >= 0; i--) {
238: obj = valuePop(ctxt);
239: MAKE_STD_ZVAL(args[i]);
240: switch (obj->type) {
241: case XPATH_STRING:
242: ZVAL_STRING(args[i], obj->stringval, 1);
243: break;
244: case XPATH_BOOLEAN:
245: ZVAL_BOOL(args[i], obj->boolval);
246: break;
247: case XPATH_NUMBER:
248: ZVAL_DOUBLE(args[i], obj->floatval);
249: break;
250: case XPATH_NODESET:
251: if (type == 1) {
252: str = xmlXPathCastToString(obj);
253: ZVAL_STRING(args[i], str, 1);
254: xmlFree(str);
255: } else if (type == 2) {
256: int j;
257: dom_object *domintern = (dom_object *)intern->doc;
258: array_init(args[i]);
259: if (obj->nodesetval && obj->nodesetval->nodeNr > 0) {
260: for (j = 0; j < obj->nodesetval->nodeNr; j++) {
261: xmlNodePtr node = obj->nodesetval->nodeTab[j];
262: zval *child;
263: MAKE_STD_ZVAL(child);
264: /* not sure, if we need this... it's copied from xpath.c */
265: if (node->type == XML_NAMESPACE_DECL) {
266: xmlNsPtr curns;
267: xmlNodePtr nsparent;
268:
269: nsparent = node->_private;
270: curns = xmlNewNs(NULL, node->name, NULL);
271: if (node->children) {
272: curns->prefix = xmlStrdup((char *) node->children);
273: }
274: if (node->children) {
275: node = xmlNewDocNode(node->doc, NULL, (char *) node->children, node->name);
276: } else {
277: node = xmlNewDocNode(node->doc, NULL, "xmlns", node->name);
278: }
279: node->type = XML_NAMESPACE_DECL;
280: node->parent = nsparent;
281: node->ns = curns;
282: }
1.1.1.2 ! misho 283: child = php_dom_create_object(node, &ret, child, domintern TSRMLS_CC);
1.1 misho 284: add_next_index_zval(args[i], child);
285: }
286: }
287: }
288: break;
289: default:
290: str = xmlXPathCastToString(obj);
291: ZVAL_STRING(args[i], str, 1);
292: xmlFree(str);
293: }
294: xmlXPathFreeObject(obj);
295: fci.params[i] = &args[i];
296: }
297:
298: fci.size = sizeof(fci);
299: fci.function_table = EG(function_table);
300:
301: obj = valuePop(ctxt);
302: if (obj->stringval == NULL) {
303: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Handler name must be a string");
304: xmlXPathFreeObject(obj);
1.1.1.2 ! misho 305: valuePush(ctxt, xmlXPathNewString(""));
1.1 misho 306: if (fci.param_count > 0) {
307: for (i = 0; i < nargs - 1; i++) {
308: zval_ptr_dtor(&args[i]);
309: }
310: efree(args);
311: efree(fci.params);
312: }
313: return;
314: }
315: INIT_PZVAL(&handler);
316: ZVAL_STRING(&handler, obj->stringval, 1);
317: xmlXPathFreeObject(obj);
318:
319: fci.function_name = &handler;
320: fci.symbol_table = NULL;
321: fci.object_ptr = NULL;
322: fci.retval_ptr_ptr = &retval;
323: fci.no_separation = 0;
324: /*fci.function_handler_cache = &function_ptr;*/
325: if (!zend_make_callable(&handler, &callable TSRMLS_CC)) {
326: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call handler %s()", callable);
1.1.1.2 ! misho 327: valuePush(ctxt, xmlXPathNewString(""));
1.1 misho 328: } else if ( intern->registerPhpFunctions == 2 && zend_hash_exists(intern->registered_phpfunctions, callable, strlen(callable) + 1) == 0) {
329: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Not allowed to call handler '%s()'", callable);
330: /* Push an empty string, so that we at least have an xslt result... */
331: valuePush(ctxt, xmlXPathNewString(""));
332: } else {
333: result = zend_call_function(&fci, NULL TSRMLS_CC);
334: if (result == FAILURE) {
335: if (Z_TYPE(handler) == IS_STRING) {
336: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call handler %s()", Z_STRVAL_P(&handler));
1.1.1.2 ! misho 337: valuePush(ctxt, xmlXPathNewString(""));
1.1 misho 338: }
339: /* retval is == NULL, when an exception occured, don't report anything, because PHP itself will handle that */
340: } else if (retval == NULL) {
341: } else {
342: if (retval->type == IS_OBJECT && instanceof_function( Z_OBJCE_P(retval), dom_node_class_entry TSRMLS_CC)) {
343: xmlNode *nodep;
344: dom_object *obj;
345: if (intern->node_list == NULL) {
346: ALLOC_HASHTABLE(intern->node_list);
347: zend_hash_init(intern->node_list, 0, NULL, ZVAL_PTR_DTOR, 0);
348: }
349: zval_add_ref(&retval);
350: zend_hash_next_index_insert(intern->node_list, &retval, sizeof(zval *), NULL);
351: obj = (dom_object *)zend_object_store_get_object(retval TSRMLS_CC);
352: nodep = dom_object_get_node(obj);
353: valuePush(ctxt, xmlXPathNewNodeSet(nodep));
354: } else if (retval->type == IS_BOOL) {
355: valuePush(ctxt, xmlXPathNewBoolean(retval->value.lval));
356: } else if (retval->type == IS_OBJECT) {
357: php_error_docref(NULL TSRMLS_CC, E_WARNING, "A PHP Object cannot be converted to a XPath-string");
358: valuePush(ctxt, xmlXPathNewString(""));
359: } else {
360: convert_to_string_ex(&retval);
361: valuePush(ctxt, xmlXPathNewString( Z_STRVAL_P(retval)));
362: }
363: zval_ptr_dtor(&retval);
364: }
365: }
366: efree(callable);
367: zval_dtor(&handler);
368: if (fci.param_count > 0) {
369: for (i = 0; i < nargs - 1; i++) {
370: zval_ptr_dtor(&args[i]);
371: }
372: efree(args);
373: efree(fci.params);
374: }
375: }
376: /* }}} */
377:
378: void xsl_ext_function_string_php(xmlXPathParserContextPtr ctxt, int nargs) /* {{{ */
379: {
380: xsl_ext_function_php(ctxt, nargs, 1);
381: }
382: /* }}} */
383:
384: void xsl_ext_function_object_php(xmlXPathParserContextPtr ctxt, int nargs) /* {{{ */
385: {
386: xsl_ext_function_php(ctxt, nargs, 2);
387: }
388: /* }}} */
389:
390: /* {{{ proto void xsl_xsltprocessor_import_stylesheet(domdocument doc);
391: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#
392: Since:
393: */
394: PHP_FUNCTION(xsl_xsltprocessor_import_stylesheet)
395: {
396: zval *id, *docp = NULL;
397: xmlDoc *doc = NULL, *newdoc = NULL;
398: xsltStylesheetPtr sheetp, oldsheetp;
399: xsl_object *intern;
400: int prevSubstValue, prevExtDtdValue, clone_docu = 0;
401: xmlNode *nodep = NULL;
402: zend_object_handlers *std_hnd;
403: zval *cloneDocu, *member;
404:
405: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oo", &id, xsl_xsltprocessor_class_entry, &docp) == FAILURE) {
406: RETURN_FALSE;
407: }
408:
409: nodep = php_libxml_import_node(docp TSRMLS_CC);
410:
411: if (nodep) {
412: doc = nodep->doc;
413: }
414: if (doc == NULL) {
415: php_error(E_WARNING, "Invalid Document");
416: RETURN_FALSE;
417: }
418:
419: /* libxslt uses _private, so we must copy the imported
420: stylesheet document otherwise the node proxies will be a mess */
421: newdoc = xmlCopyDoc(doc, 1);
422: xmlNodeSetBase((xmlNodePtr) newdoc, (xmlChar *)doc->URL);
423: prevSubstValue = xmlSubstituteEntitiesDefault(1);
424: prevExtDtdValue = xmlLoadExtDtdDefaultValue;
425: xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
426:
427: sheetp = xsltParseStylesheetDoc(newdoc);
428: xmlSubstituteEntitiesDefault(prevSubstValue);
429: xmlLoadExtDtdDefaultValue = prevExtDtdValue;
430:
431: if (!sheetp) {
432: xmlFreeDoc(newdoc);
433: RETURN_FALSE;
434: }
435:
436: intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
437:
438: std_hnd = zend_get_std_object_handlers();
439: MAKE_STD_ZVAL(member);
440: ZVAL_STRING(member, "cloneDocument", 0);
1.1.1.2 ! misho 441: cloneDocu = std_hnd->read_property(id, member, BP_VAR_IS, NULL TSRMLS_CC);
1.1 misho 442: if (Z_TYPE_P(cloneDocu) != IS_NULL) {
443: convert_to_long(cloneDocu);
444: clone_docu = Z_LVAL_P(cloneDocu);
445: }
446: efree(member);
447: if (clone_docu == 0) {
448: /* check if the stylesheet is using xsl:key, if yes, we have to clone the document _always_ before a transformation */
449: nodep = xmlDocGetRootElement(sheetp->doc);
450: if (nodep && (nodep = nodep->children)) {
451: while (nodep) {
452: if (nodep->type == XML_ELEMENT_NODE && xmlStrEqual(nodep->name, "key") && xmlStrEqual(nodep->ns->href, XSLT_NAMESPACE)) {
453: intern->hasKeys = 1;
454: break;
455: }
456: nodep = nodep->next;
457: }
458: }
459: } else {
460: intern->hasKeys = clone_docu;
461: }
462:
463: if ((oldsheetp = (xsltStylesheetPtr)intern->ptr)) {
464: /* free wrapper */
465: if (((xsltStylesheetPtr) intern->ptr)->_private != NULL) {
466: ((xsltStylesheetPtr) intern->ptr)->_private = NULL;
467: }
468: xsltFreeStylesheet((xsltStylesheetPtr) intern->ptr);
469: intern->ptr = NULL;
470: }
471:
472: php_xsl_set_object(id, sheetp TSRMLS_CC);
473: RETVAL_TRUE;
474: }
475: /* }}} end xsl_xsltprocessor_import_stylesheet */
476:
477: static xmlDocPtr php_xsl_apply_stylesheet(zval *id, xsl_object *intern, xsltStylesheetPtr style, zval *docp TSRMLS_DC) /* {{{ */
478: {
479: xmlDocPtr newdocp;
480: xmlDocPtr doc = NULL;
481: xmlNodePtr node = NULL;
482: xsltTransformContextPtr ctxt;
483: php_libxml_node_object *object;
484: char **params = NULL;
485: int clone;
486: zval *doXInclude, *member;
487: zend_object_handlers *std_hnd;
488: FILE *f;
489: int secPrefsError = 0;
1.1.1.2 ! misho 490: int secPrefsValue, secPrefsIni;
1.1 misho 491: xsltSecurityPrefsPtr secPrefs = NULL;
492:
493: node = php_libxml_import_node(docp TSRMLS_CC);
494:
495: if (node) {
496: doc = node->doc;
497: }
498: if (doc == NULL) {
499: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Document");
500: return NULL;
501: }
502:
503: if (style == NULL) {
504: php_error_docref(NULL TSRMLS_CC, E_WARNING, "No stylesheet associated to this object");
505: return NULL;
506: }
507:
508: if (intern->profiling) {
509: if (php_check_open_basedir(intern->profiling TSRMLS_CC)) {
510: f = NULL;
511: } else {
512: f = VCWD_FOPEN(intern->profiling, "w");
513: }
514: } else {
515: f = NULL;
516: }
517:
518: if (intern->parameter) {
519: params = php_xsl_xslt_make_params(intern->parameter, 0 TSRMLS_CC);
520: }
521:
522: intern->doc = emalloc(sizeof(php_libxml_node_object));
523: memset(intern->doc, 0, sizeof(php_libxml_node_object));
524:
525: if (intern->hasKeys == 1) {
526: doc = xmlCopyDoc(doc, 1);
527: } else {
528: object = (php_libxml_node_object *)zend_object_store_get_object(docp TSRMLS_CC);
529: intern->doc->document = object->document;
530: }
531:
532: php_libxml_increment_doc_ref(intern->doc, doc TSRMLS_CC);
533:
534: ctxt = xsltNewTransformContext(style, doc);
535: ctxt->_private = (void *) intern;
536:
537: std_hnd = zend_get_std_object_handlers();
538:
539: MAKE_STD_ZVAL(member);
540: ZVAL_STRING(member, "doXInclude", 0);
1.1.1.2 ! misho 541: doXInclude = std_hnd->read_property(id, member, BP_VAR_IS, NULL TSRMLS_CC);
1.1 misho 542: if (Z_TYPE_P(doXInclude) != IS_NULL) {
543: convert_to_long(doXInclude);
544: ctxt->xinclude = Z_LVAL_P(doXInclude);
545: }
546: efree(member);
547:
1.1.1.2 ! misho 548: secPrefsValue = intern->securityPrefs;
1.1 misho 549:
1.1.1.2 ! misho 550: /* This whole if block can be removed, when we remove the xsl.security_prefs php.ini option in PHP 6+ */
! 551: secPrefsIni= INI_INT("xsl.security_prefs");
! 552: /* if secPrefsIni has the same value as secPrefsValue, all is fine */
! 553: if (secPrefsIni != secPrefsValue) {
! 554: if (secPrefsIni != XSL_SECPREF_DEFAULT) {
! 555: /* if the ini value is not set to the default, throw an E_DEPRECATED warning */
! 556: php_error_docref(NULL TSRMLS_CC, E_DEPRECATED, "The xsl.security_prefs php.ini option is deprecated; use XsltProcessor->setSecurityPrefs() instead");
! 557: if (intern->securityPrefsSet == 0) {
! 558: /* if securityPrefs were not set through the setSecurityPrefs method, take the ini setting */
! 559: secPrefsValue = secPrefsIni;
! 560: } else {
! 561: /* else throw a notice, that the ini setting was not used */
! 562: php_error_docref(NULL TSRMLS_CC, E_NOTICE, "The xsl.security_prefs php.ini was not used, since the XsltProcessor->setSecurityPrefs() method was used");
! 563: }
! 564: }
! 565: }
! 566:
1.1 misho 567: /* if securityPrefs is set to NONE, we don't have to do any checks, but otherwise... */
568: if (secPrefsValue != XSL_SECPREF_NONE) {
569: secPrefs = xsltNewSecurityPrefs();
570: if (secPrefsValue & XSL_SECPREF_READ_FILE ) {
571: if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_READ_FILE, xsltSecurityForbid)) {
572: secPrefsError = 1;
573: }
574: }
575: if (secPrefsValue & XSL_SECPREF_WRITE_FILE ) {
576: if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_WRITE_FILE, xsltSecurityForbid)) {
577: secPrefsError = 1;
578: }
579: }
580: if (secPrefsValue & XSL_SECPREF_CREATE_DIRECTORY ) {
581: if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_CREATE_DIRECTORY, xsltSecurityForbid)) {
582: secPrefsError = 1;
583: }
584: }
585: if (secPrefsValue & XSL_SECPREF_READ_NETWORK) {
586: if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_READ_NETWORK, xsltSecurityForbid)) {
587: secPrefsError = 1;
588: }
589: }
590: if (secPrefsValue & XSL_SECPREF_WRITE_NETWORK) {
591: if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_WRITE_NETWORK, xsltSecurityForbid)) {
592: secPrefsError = 1;
593: }
594: }
595:
596: if (0 != xsltSetCtxtSecurityPrefs(secPrefs, ctxt)) {
597: secPrefsError = 1;
598: }
599: }
600:
601: if (secPrefsError == 1) {
602: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't set libxslt security properties, not doing transformation for security reasons");
603: } else {
604: newdocp = xsltApplyStylesheetUser(style, doc, (const char**) params, NULL, f, ctxt);
605: }
606: if (f) {
607: fclose(f);
608: }
609:
610: xsltFreeTransformContext(ctxt);
611: if (secPrefs) {
612: xsltFreeSecurityPrefs(secPrefs);
613: }
614:
615: if (intern->node_list != NULL) {
616: zend_hash_destroy(intern->node_list);
617: FREE_HASHTABLE(intern->node_list);
618: intern->node_list = NULL;
619: }
620:
621: php_libxml_decrement_doc_ref(intern->doc TSRMLS_CC);
622: efree(intern->doc);
623: intern->doc = NULL;
624:
625: if (params) {
626: clone = 0;
627: while(params[clone]) {
628: efree(params[clone++]);
629: }
630: efree(params);
631: }
632:
633: return newdocp;
634:
635: }
636: /* }}} */
637:
638: /* {{{ proto domdocument xsl_xsltprocessor_transform_to_doc(domnode doc);
639: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#
640: Since:
641: */
642: PHP_FUNCTION(xsl_xsltprocessor_transform_to_doc)
643: {
1.1.1.2 ! misho 644: zval *id, *docp = NULL;
1.1 misho 645: xmlDoc *newdocp;
646: xsltStylesheetPtr sheetp;
647: int ret, ret_class_len=0;
648: char *ret_class = NULL;
649: xsl_object *intern;
650:
651: id = getThis();
652: intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
653: sheetp = (xsltStylesheetPtr) intern->ptr;
654:
655: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o|s!", &docp, &ret_class, &ret_class_len) == FAILURE) {
656: RETURN_FALSE;
657: }
658:
659: newdocp = php_xsl_apply_stylesheet(id, intern, sheetp, docp TSRMLS_CC);
660:
661: if (newdocp) {
662: if (ret_class) {
663: int found;
664: char *curclass_name;
665: zend_class_entry *curce, **ce;
666: php_libxml_node_object *interndoc;
667:
668: curce = Z_OBJCE_P(docp);
669: curclass_name = curce->name;
670: while (curce->parent != NULL) {
671: curce = curce->parent;
672: }
673:
674: found = zend_lookup_class(ret_class, ret_class_len, &ce TSRMLS_CC);
675: if ((found != SUCCESS) || !instanceof_function(*ce, curce TSRMLS_CC)) {
676: xmlFreeDoc(newdocp);
677: php_error_docref(NULL TSRMLS_CC, E_WARNING,
678: "Expecting class compatible with %s, '%s' given", curclass_name, ret_class);
679: RETURN_FALSE;
680: }
681:
682: object_init_ex(return_value, *ce);
683:
684: interndoc = (php_libxml_node_object *)zend_objects_get_address(return_value TSRMLS_CC);
685: php_libxml_increment_doc_ref(interndoc, newdocp TSRMLS_CC);
686: php_libxml_increment_node_ptr(interndoc, (xmlNodePtr)newdocp, (void *)interndoc TSRMLS_CC);
687: } else {
1.1.1.2 ! misho 688: DOM_RET_OBJ((xmlNodePtr) newdocp, &ret, NULL);
1.1 misho 689: }
690: } else {
691: RETURN_FALSE;
692: }
693:
694: }
695: /* }}} end xsl_xsltprocessor_transform_to_doc */
696:
697: /* {{{ proto int xsl_xsltprocessor_transform_to_uri(domdocument doc, string uri);
698: */
699: PHP_FUNCTION(xsl_xsltprocessor_transform_to_uri)
700: {
701: zval *id, *docp = NULL;
702: xmlDoc *newdocp;
703: xsltStylesheetPtr sheetp;
704: int ret, uri_len;
705: char *uri;
706: xsl_object *intern;
707:
708: id = getThis();
709: intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
710: sheetp = (xsltStylesheetPtr) intern->ptr;
711:
1.1.1.2 ! misho 712: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "op", &docp, &uri, &uri_len) == FAILURE) {
1.1 misho 713: RETURN_FALSE;
714: }
715:
716: newdocp = php_xsl_apply_stylesheet(id, intern, sheetp, docp TSRMLS_CC);
717:
718: ret = -1;
719: if (newdocp) {
720: ret = xsltSaveResultToFilename(uri, newdocp, sheetp, 0);
721: xmlFreeDoc(newdocp);
722: }
723:
724: RETVAL_LONG(ret);
725: }
726: /* }}} end xsl_xsltprocessor_transform_to_uri */
727:
728: /* {{{ proto string xsl_xsltprocessor_transform_to_xml(domdocument doc);
729: */
730: PHP_FUNCTION(xsl_xsltprocessor_transform_to_xml)
731: {
732: zval *id, *docp = NULL;
733: xmlDoc *newdocp;
734: xsltStylesheetPtr sheetp;
735: int ret;
736: xmlChar *doc_txt_ptr;
737: int doc_txt_len;
738: xsl_object *intern;
739:
740: id = getThis();
741: intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
742: sheetp = (xsltStylesheetPtr) intern->ptr;
743:
744: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &docp) == FAILURE) {
745: RETURN_FALSE;
746: }
747:
748: newdocp = php_xsl_apply_stylesheet(id, intern, sheetp, docp TSRMLS_CC);
749:
750: ret = -1;
751: if (newdocp) {
752: ret = xsltSaveResultToString(&doc_txt_ptr, &doc_txt_len, newdocp, sheetp);
753: if (doc_txt_ptr && doc_txt_len) {
754: RETVAL_STRINGL(doc_txt_ptr, doc_txt_len, 1);
755: xmlFree(doc_txt_ptr);
756: }
757: xmlFreeDoc(newdocp);
758: }
759:
760: if (ret < 0) {
761: RETURN_FALSE;
762: }
763: }
764: /* }}} end xsl_xsltprocessor_transform_to_xml */
765:
766: /* {{{ proto bool xsl_xsltprocessor_set_parameter(string namespace, mixed name [, string value]);
767: */
768: PHP_FUNCTION(xsl_xsltprocessor_set_parameter)
769: {
770:
771: zval *id;
772: zval *array_value, **entry, *new_string;
773: xsl_object *intern;
774: char *string_key, *name, *value, *namespace;
775: ulong idx;
776: int string_key_len, namespace_len, name_len, value_len;
777: DOM_GET_THIS(id);
778:
779: if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "sa", &namespace, &namespace_len, &array_value) == SUCCESS) {
780: intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
781: zend_hash_internal_pointer_reset(Z_ARRVAL_P(array_value));
782:
783: while (zend_hash_get_current_data(Z_ARRVAL_P(array_value), (void **)&entry) == SUCCESS) {
784: SEPARATE_ZVAL(entry);
785: convert_to_string_ex(entry);
786:
787: if (zend_hash_get_current_key_ex(Z_ARRVAL_P(array_value), &string_key, &string_key_len, &idx, 0, NULL) != HASH_KEY_IS_STRING) {
788: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid parameter array");
789: RETURN_FALSE;
790: }
791:
792: ALLOC_ZVAL(new_string);
793: Z_ADDREF_PP(entry);
794: COPY_PZVAL_TO_ZVAL(*new_string, *entry);
795:
796: zend_hash_update(intern->parameter, string_key, string_key_len, &new_string, sizeof(zval*), NULL);
797: zend_hash_move_forward(Z_ARRVAL_P(array_value));
798: }
799: RETURN_TRUE;
800:
801: } 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) {
802:
803: intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
804:
805: MAKE_STD_ZVAL(new_string);
806: ZVAL_STRING(new_string, value, 1);
807:
808: zend_hash_update(intern->parameter, name, name_len + 1, &new_string, sizeof(zval*), NULL);
809: RETURN_TRUE;
810: } else {
811: WRONG_PARAM_COUNT;
812: }
813:
814: }
815: /* }}} end xsl_xsltprocessor_set_parameter */
816:
817: /* {{{ proto string xsl_xsltprocessor_get_parameter(string namespace, string name);
818: */
819: PHP_FUNCTION(xsl_xsltprocessor_get_parameter)
820: {
821: zval *id;
822: int name_len = 0, namespace_len = 0;
823: char *name, *namespace;
824: zval **value;
825: xsl_object *intern;
826:
827: DOM_GET_THIS(id);
828:
829: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &namespace, &namespace_len, &name, &name_len) == FAILURE) {
830: RETURN_FALSE;
831: }
832: intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
833: if ( zend_hash_find(intern->parameter, name, name_len + 1, (void**) &value) == SUCCESS) {
834: convert_to_string_ex(value);
835: RETVAL_STRING(Z_STRVAL_PP(value),1);
836: } else {
837: RETURN_FALSE;
838: }
839: }
840: /* }}} end xsl_xsltprocessor_get_parameter */
841:
842: /* {{{ proto bool xsl_xsltprocessor_remove_parameter(string namespace, string name);
843: */
844: PHP_FUNCTION(xsl_xsltprocessor_remove_parameter)
845: {
846: zval *id;
847: int name_len = 0, namespace_len = 0;
848: char *name, *namespace;
849: xsl_object *intern;
850:
851: DOM_GET_THIS(id);
852:
853: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &namespace, &namespace_len, &name, &name_len) == FAILURE) {
854: RETURN_FALSE;
855: }
856: intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
857: if ( zend_hash_del(intern->parameter, name, name_len + 1) == SUCCESS) {
858: RETURN_TRUE;
859: } else {
860: RETURN_FALSE;
861: }
862: }
863: /* }}} end xsl_xsltprocessor_remove_parameter */
864:
865: /* {{{ proto void xsl_xsltprocessor_register_php_functions([mixed $restrict]);
866: */
867: PHP_FUNCTION(xsl_xsltprocessor_register_php_functions)
868: {
869: zval *id;
870: xsl_object *intern;
871: zval *array_value, **entry, *new_string;
872: int name_len = 0;
873: char *name;
874:
875: DOM_GET_THIS(id);
876:
877: if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "a", &array_value) == SUCCESS) {
878: intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
879: zend_hash_internal_pointer_reset(Z_ARRVAL_P(array_value));
880:
881: while (zend_hash_get_current_data(Z_ARRVAL_P(array_value), (void **)&entry) == SUCCESS) {
882: SEPARATE_ZVAL(entry);
883: convert_to_string_ex(entry);
884:
885: MAKE_STD_ZVAL(new_string);
886: ZVAL_LONG(new_string,1);
887:
888: zend_hash_update(intern->registered_phpfunctions, Z_STRVAL_PP(entry), Z_STRLEN_PP(entry) + 1, &new_string, sizeof(zval*), NULL);
889: zend_hash_move_forward(Z_ARRVAL_P(array_value));
890: }
891: intern->registerPhpFunctions = 2;
892:
893: } else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == SUCCESS) {
894: intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
895:
896: MAKE_STD_ZVAL(new_string);
897: ZVAL_LONG(new_string,1);
898: zend_hash_update(intern->registered_phpfunctions, name, name_len + 1, &new_string, sizeof(zval*), NULL);
899: intern->registerPhpFunctions = 2;
900:
901: } else {
902: intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
903: intern->registerPhpFunctions = 1;
904: }
905:
906: }
907: /* }}} end xsl_xsltprocessor_register_php_functions(); */
908:
909: /* {{{ proto bool xsl_xsltprocessor_set_profiling(string filename) */
910: PHP_FUNCTION(xsl_xsltprocessor_set_profiling)
911: {
912: zval *id;
913: xsl_object *intern;
914: char *filename = NULL;
915: int filename_len;
916: DOM_GET_THIS(id);
917:
1.1.1.2 ! misho 918: if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "p!", &filename, &filename_len) == SUCCESS) {
1.1 misho 919: intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
920: if (intern->profiling) {
921: efree(intern->profiling);
922: }
1.1.1.2 ! misho 923: if (filename != NULL) {
1.1 misho 924: intern->profiling = estrndup(filename,filename_len);
925: } else {
926: intern->profiling = NULL;
927: }
928: RETURN_TRUE;
929: } else {
930: WRONG_PARAM_COUNT;
931: }
932: }
933: /* }}} end xsl_xsltprocessor_set_profiling */
934:
1.1.1.2 ! misho 935: /* {{{ proto long xsl_xsltprocessor_set_security_prefs(long securityPrefs) */
! 936: PHP_FUNCTION(xsl_xsltprocessor_set_security_prefs)
! 937: {
! 938: zval *id;
! 939: xsl_object *intern;
! 940: long securityPrefs, oldSecurityPrefs;
! 941:
! 942: DOM_GET_THIS(id);
! 943: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &securityPrefs) == FAILURE) {
! 944: return;
! 945: }
! 946: intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
! 947: oldSecurityPrefs = intern->securityPrefs;
! 948: intern->securityPrefs = securityPrefs;
! 949: /* set this to 1 so that we know, it was set through this method. Can be removed, when we remove the ini setting */
! 950: intern->securityPrefsSet = 1;
! 951: RETURN_LONG(oldSecurityPrefs);
! 952: }
! 953: /* }}} end xsl_xsltprocessor_set_security_prefs */
! 954:
! 955: /* {{{ proto long xsl_xsltprocessor_get_security_prefs() */
! 956: PHP_FUNCTION(xsl_xsltprocessor_get_security_prefs)
! 957: {
! 958: zval *id;
! 959: xsl_object *intern;
! 960:
! 961: DOM_GET_THIS(id);
! 962: if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "") == SUCCESS) {
! 963: intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
! 964: RETURN_LONG(intern->securityPrefs);
! 965: } else {
! 966: WRONG_PARAM_COUNT;
! 967: }
! 968: }
! 969: /* }}} end xsl_xsltprocessor_get_security_prefs */
! 970:
! 971:
! 972:
1.1 misho 973: /* {{{ proto bool xsl_xsltprocessor_has_exslt_support();
974: */
975: PHP_FUNCTION(xsl_xsltprocessor_has_exslt_support)
976: {
977: #if HAVE_XSL_EXSLT
978: RETURN_TRUE;
979: #else
980: RETURN_FALSE;
981: #endif
982: }
983: /* }}} end xsl_xsltprocessor_has_exslt_support(); */
984:
985: /*
986: * Local variables:
987: * tab-width: 4
988: * c-basic-offset: 4
989: * End:
990: * vim600: sw=4 ts=4 fdm=marker
991: * vim<600: sw=4 ts=4
992: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>