Annotation of embedaddon/php/ext/xsl/xsltprocessor.c, revision 1.1.1.5
1.1 misho 1: /*
2: +----------------------------------------------------------------------+
3: | PHP Version 5 |
4: +----------------------------------------------------------------------+
1.1.1.5 ! misho 5: | Copyright (c) 1997-2014 The PHP Group |
1.1 misho 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;
1.1.1.5 ! misho 282: } else {
! 283: node = xmlDocCopyNodeList(domintern->document->ptr, node);
1.1 misho 284: }
1.1.1.5 ! misho 285:
1.1.1.2 misho 286: child = php_dom_create_object(node, &ret, child, domintern TSRMLS_CC);
1.1 misho 287: add_next_index_zval(args[i], child);
288: }
289: }
290: }
291: break;
292: default:
293: str = xmlXPathCastToString(obj);
294: ZVAL_STRING(args[i], str, 1);
295: xmlFree(str);
296: }
297: xmlXPathFreeObject(obj);
298: fci.params[i] = &args[i];
299: }
300:
301: fci.size = sizeof(fci);
302: fci.function_table = EG(function_table);
303:
304: obj = valuePop(ctxt);
305: if (obj->stringval == NULL) {
306: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Handler name must be a string");
307: xmlXPathFreeObject(obj);
1.1.1.2 misho 308: valuePush(ctxt, xmlXPathNewString(""));
1.1 misho 309: if (fci.param_count > 0) {
310: for (i = 0; i < nargs - 1; i++) {
311: zval_ptr_dtor(&args[i]);
312: }
313: efree(args);
314: efree(fci.params);
315: }
316: return;
317: }
318: INIT_PZVAL(&handler);
319: ZVAL_STRING(&handler, obj->stringval, 1);
320: xmlXPathFreeObject(obj);
321:
322: fci.function_name = &handler;
323: fci.symbol_table = NULL;
324: fci.object_ptr = NULL;
325: fci.retval_ptr_ptr = &retval;
326: fci.no_separation = 0;
327: /*fci.function_handler_cache = &function_ptr;*/
328: if (!zend_make_callable(&handler, &callable TSRMLS_CC)) {
329: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call handler %s()", callable);
1.1.1.2 misho 330: valuePush(ctxt, xmlXPathNewString(""));
1.1 misho 331: } else if ( intern->registerPhpFunctions == 2 && zend_hash_exists(intern->registered_phpfunctions, callable, strlen(callable) + 1) == 0) {
332: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Not allowed to call handler '%s()'", callable);
333: /* Push an empty string, so that we at least have an xslt result... */
334: valuePush(ctxt, xmlXPathNewString(""));
335: } else {
336: result = zend_call_function(&fci, NULL TSRMLS_CC);
337: if (result == FAILURE) {
338: if (Z_TYPE(handler) == IS_STRING) {
339: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call handler %s()", Z_STRVAL_P(&handler));
1.1.1.2 misho 340: valuePush(ctxt, xmlXPathNewString(""));
1.1 misho 341: }
1.1.1.3 misho 342: /* retval is == NULL, when an exception occurred, don't report anything, because PHP itself will handle that */
1.1 misho 343: } else if (retval == NULL) {
344: } else {
345: if (retval->type == IS_OBJECT && instanceof_function( Z_OBJCE_P(retval), dom_node_class_entry TSRMLS_CC)) {
346: xmlNode *nodep;
347: dom_object *obj;
348: if (intern->node_list == NULL) {
349: ALLOC_HASHTABLE(intern->node_list);
350: zend_hash_init(intern->node_list, 0, NULL, ZVAL_PTR_DTOR, 0);
351: }
352: zval_add_ref(&retval);
353: zend_hash_next_index_insert(intern->node_list, &retval, sizeof(zval *), NULL);
354: obj = (dom_object *)zend_object_store_get_object(retval TSRMLS_CC);
355: nodep = dom_object_get_node(obj);
356: valuePush(ctxt, xmlXPathNewNodeSet(nodep));
357: } else if (retval->type == IS_BOOL) {
358: valuePush(ctxt, xmlXPathNewBoolean(retval->value.lval));
359: } else if (retval->type == IS_OBJECT) {
360: php_error_docref(NULL TSRMLS_CC, E_WARNING, "A PHP Object cannot be converted to a XPath-string");
361: valuePush(ctxt, xmlXPathNewString(""));
362: } else {
363: convert_to_string_ex(&retval);
364: valuePush(ctxt, xmlXPathNewString( Z_STRVAL_P(retval)));
365: }
366: zval_ptr_dtor(&retval);
367: }
368: }
369: efree(callable);
370: zval_dtor(&handler);
371: if (fci.param_count > 0) {
372: for (i = 0; i < nargs - 1; i++) {
373: zval_ptr_dtor(&args[i]);
374: }
375: efree(args);
376: efree(fci.params);
377: }
378: }
379: /* }}} */
380:
381: void xsl_ext_function_string_php(xmlXPathParserContextPtr ctxt, int nargs) /* {{{ */
382: {
383: xsl_ext_function_php(ctxt, nargs, 1);
384: }
385: /* }}} */
386:
387: void xsl_ext_function_object_php(xmlXPathParserContextPtr ctxt, int nargs) /* {{{ */
388: {
389: xsl_ext_function_php(ctxt, nargs, 2);
390: }
391: /* }}} */
392:
393: /* {{{ proto void xsl_xsltprocessor_import_stylesheet(domdocument doc);
394: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#
395: Since:
396: */
397: PHP_FUNCTION(xsl_xsltprocessor_import_stylesheet)
398: {
399: zval *id, *docp = NULL;
400: xmlDoc *doc = NULL, *newdoc = NULL;
401: xsltStylesheetPtr sheetp, oldsheetp;
402: xsl_object *intern;
403: int prevSubstValue, prevExtDtdValue, clone_docu = 0;
404: xmlNode *nodep = NULL;
405: zend_object_handlers *std_hnd;
406: zval *cloneDocu, *member;
407:
408: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oo", &id, xsl_xsltprocessor_class_entry, &docp) == FAILURE) {
409: RETURN_FALSE;
410: }
411:
412: nodep = php_libxml_import_node(docp TSRMLS_CC);
413:
414: if (nodep) {
415: doc = nodep->doc;
416: }
417: if (doc == NULL) {
418: php_error(E_WARNING, "Invalid Document");
419: RETURN_FALSE;
420: }
421:
422: /* libxslt uses _private, so we must copy the imported
423: stylesheet document otherwise the node proxies will be a mess */
424: newdoc = xmlCopyDoc(doc, 1);
425: xmlNodeSetBase((xmlNodePtr) newdoc, (xmlChar *)doc->URL);
426: prevSubstValue = xmlSubstituteEntitiesDefault(1);
427: prevExtDtdValue = xmlLoadExtDtdDefaultValue;
428: xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
429:
430: sheetp = xsltParseStylesheetDoc(newdoc);
431: xmlSubstituteEntitiesDefault(prevSubstValue);
432: xmlLoadExtDtdDefaultValue = prevExtDtdValue;
433:
434: if (!sheetp) {
435: xmlFreeDoc(newdoc);
436: RETURN_FALSE;
437: }
438:
439: intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
440:
441: std_hnd = zend_get_std_object_handlers();
442: MAKE_STD_ZVAL(member);
443: ZVAL_STRING(member, "cloneDocument", 0);
1.1.1.2 misho 444: cloneDocu = std_hnd->read_property(id, member, BP_VAR_IS, NULL TSRMLS_CC);
1.1 misho 445: if (Z_TYPE_P(cloneDocu) != IS_NULL) {
446: convert_to_long(cloneDocu);
447: clone_docu = Z_LVAL_P(cloneDocu);
448: }
449: efree(member);
450: if (clone_docu == 0) {
451: /* check if the stylesheet is using xsl:key, if yes, we have to clone the document _always_ before a transformation */
452: nodep = xmlDocGetRootElement(sheetp->doc);
453: if (nodep && (nodep = nodep->children)) {
454: while (nodep) {
455: if (nodep->type == XML_ELEMENT_NODE && xmlStrEqual(nodep->name, "key") && xmlStrEqual(nodep->ns->href, XSLT_NAMESPACE)) {
456: intern->hasKeys = 1;
457: break;
458: }
459: nodep = nodep->next;
460: }
461: }
462: } else {
463: intern->hasKeys = clone_docu;
464: }
465:
466: if ((oldsheetp = (xsltStylesheetPtr)intern->ptr)) {
467: /* free wrapper */
468: if (((xsltStylesheetPtr) intern->ptr)->_private != NULL) {
469: ((xsltStylesheetPtr) intern->ptr)->_private = NULL;
470: }
471: xsltFreeStylesheet((xsltStylesheetPtr) intern->ptr);
472: intern->ptr = NULL;
473: }
474:
475: php_xsl_set_object(id, sheetp TSRMLS_CC);
476: RETVAL_TRUE;
477: }
478: /* }}} end xsl_xsltprocessor_import_stylesheet */
479:
480: static xmlDocPtr php_xsl_apply_stylesheet(zval *id, xsl_object *intern, xsltStylesheetPtr style, zval *docp TSRMLS_DC) /* {{{ */
481: {
1.1.1.4 misho 482: xmlDocPtr newdocp = NULL;
1.1 misho 483: xmlDocPtr doc = NULL;
484: xmlNodePtr node = NULL;
485: xsltTransformContextPtr ctxt;
486: php_libxml_node_object *object;
487: char **params = NULL;
488: int clone;
489: zval *doXInclude, *member;
490: zend_object_handlers *std_hnd;
491: FILE *f;
492: int secPrefsError = 0;
1.1.1.2 misho 493: int secPrefsValue, secPrefsIni;
1.1 misho 494: xsltSecurityPrefsPtr secPrefs = NULL;
495:
496: node = php_libxml_import_node(docp TSRMLS_CC);
497:
498: if (node) {
499: doc = node->doc;
500: }
501: if (doc == NULL) {
502: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Document");
503: return NULL;
504: }
505:
506: if (style == NULL) {
507: php_error_docref(NULL TSRMLS_CC, E_WARNING, "No stylesheet associated to this object");
508: return NULL;
509: }
510:
511: if (intern->profiling) {
512: if (php_check_open_basedir(intern->profiling TSRMLS_CC)) {
513: f = NULL;
514: } else {
515: f = VCWD_FOPEN(intern->profiling, "w");
516: }
517: } else {
518: f = NULL;
519: }
520:
521: if (intern->parameter) {
522: params = php_xsl_xslt_make_params(intern->parameter, 0 TSRMLS_CC);
523: }
524:
525: intern->doc = emalloc(sizeof(php_libxml_node_object));
526: memset(intern->doc, 0, sizeof(php_libxml_node_object));
527:
528: if (intern->hasKeys == 1) {
529: doc = xmlCopyDoc(doc, 1);
530: } else {
531: object = (php_libxml_node_object *)zend_object_store_get_object(docp TSRMLS_CC);
532: intern->doc->document = object->document;
533: }
534:
535: php_libxml_increment_doc_ref(intern->doc, doc TSRMLS_CC);
536:
537: ctxt = xsltNewTransformContext(style, doc);
538: ctxt->_private = (void *) intern;
539:
540: std_hnd = zend_get_std_object_handlers();
541:
542: MAKE_STD_ZVAL(member);
543: ZVAL_STRING(member, "doXInclude", 0);
1.1.1.2 misho 544: doXInclude = std_hnd->read_property(id, member, BP_VAR_IS, NULL TSRMLS_CC);
1.1 misho 545: if (Z_TYPE_P(doXInclude) != IS_NULL) {
546: convert_to_long(doXInclude);
547: ctxt->xinclude = Z_LVAL_P(doXInclude);
548: }
549: efree(member);
550:
1.1.1.2 misho 551: secPrefsValue = intern->securityPrefs;
1.1 misho 552:
1.1.1.2 misho 553: /* This whole if block can be removed, when we remove the xsl.security_prefs php.ini option in PHP 6+ */
554: secPrefsIni= INI_INT("xsl.security_prefs");
555: /* if secPrefsIni has the same value as secPrefsValue, all is fine */
556: if (secPrefsIni != secPrefsValue) {
557: if (secPrefsIni != XSL_SECPREF_DEFAULT) {
558: /* if the ini value is not set to the default, throw an E_DEPRECATED warning */
559: php_error_docref(NULL TSRMLS_CC, E_DEPRECATED, "The xsl.security_prefs php.ini option is deprecated; use XsltProcessor->setSecurityPrefs() instead");
560: if (intern->securityPrefsSet == 0) {
561: /* if securityPrefs were not set through the setSecurityPrefs method, take the ini setting */
562: secPrefsValue = secPrefsIni;
563: } else {
564: /* else throw a notice, that the ini setting was not used */
565: php_error_docref(NULL TSRMLS_CC, E_NOTICE, "The xsl.security_prefs php.ini was not used, since the XsltProcessor->setSecurityPrefs() method was used");
566: }
567: }
568: }
569:
1.1 misho 570: /* if securityPrefs is set to NONE, we don't have to do any checks, but otherwise... */
571: if (secPrefsValue != XSL_SECPREF_NONE) {
572: secPrefs = xsltNewSecurityPrefs();
573: if (secPrefsValue & XSL_SECPREF_READ_FILE ) {
574: if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_READ_FILE, xsltSecurityForbid)) {
575: secPrefsError = 1;
576: }
577: }
578: if (secPrefsValue & XSL_SECPREF_WRITE_FILE ) {
579: if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_WRITE_FILE, xsltSecurityForbid)) {
580: secPrefsError = 1;
581: }
582: }
583: if (secPrefsValue & XSL_SECPREF_CREATE_DIRECTORY ) {
584: if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_CREATE_DIRECTORY, xsltSecurityForbid)) {
585: secPrefsError = 1;
586: }
587: }
588: if (secPrefsValue & XSL_SECPREF_READ_NETWORK) {
589: if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_READ_NETWORK, xsltSecurityForbid)) {
590: secPrefsError = 1;
591: }
592: }
593: if (secPrefsValue & XSL_SECPREF_WRITE_NETWORK) {
594: if (0 != xsltSetSecurityPrefs(secPrefs, XSLT_SECPREF_WRITE_NETWORK, xsltSecurityForbid)) {
595: secPrefsError = 1;
596: }
597: }
598:
599: if (0 != xsltSetCtxtSecurityPrefs(secPrefs, ctxt)) {
600: secPrefsError = 1;
601: }
602: }
603:
604: if (secPrefsError == 1) {
605: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't set libxslt security properties, not doing transformation for security reasons");
606: } else {
607: newdocp = xsltApplyStylesheetUser(style, doc, (const char**) params, NULL, f, ctxt);
608: }
609: if (f) {
610: fclose(f);
611: }
612:
613: xsltFreeTransformContext(ctxt);
614: if (secPrefs) {
615: xsltFreeSecurityPrefs(secPrefs);
616: }
617:
618: if (intern->node_list != NULL) {
619: zend_hash_destroy(intern->node_list);
620: FREE_HASHTABLE(intern->node_list);
621: intern->node_list = NULL;
622: }
623:
624: php_libxml_decrement_doc_ref(intern->doc TSRMLS_CC);
625: efree(intern->doc);
626: intern->doc = NULL;
627:
628: if (params) {
629: clone = 0;
630: while(params[clone]) {
631: efree(params[clone++]);
632: }
633: efree(params);
634: }
635:
636: return newdocp;
637:
638: }
639: /* }}} */
640:
641: /* {{{ proto domdocument xsl_xsltprocessor_transform_to_doc(domnode doc);
642: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#
643: Since:
644: */
645: PHP_FUNCTION(xsl_xsltprocessor_transform_to_doc)
646: {
1.1.1.2 misho 647: zval *id, *docp = NULL;
1.1 misho 648: xmlDoc *newdocp;
649: xsltStylesheetPtr sheetp;
650: int ret, ret_class_len=0;
651: char *ret_class = NULL;
652: xsl_object *intern;
653:
654: id = getThis();
655: intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
656: sheetp = (xsltStylesheetPtr) intern->ptr;
657:
658: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o|s!", &docp, &ret_class, &ret_class_len) == FAILURE) {
659: RETURN_FALSE;
660: }
661:
662: newdocp = php_xsl_apply_stylesheet(id, intern, sheetp, docp TSRMLS_CC);
663:
664: if (newdocp) {
665: if (ret_class) {
666: int found;
667: char *curclass_name;
668: zend_class_entry *curce, **ce;
669: php_libxml_node_object *interndoc;
670:
671: curce = Z_OBJCE_P(docp);
672: curclass_name = curce->name;
673: while (curce->parent != NULL) {
674: curce = curce->parent;
675: }
676:
677: found = zend_lookup_class(ret_class, ret_class_len, &ce TSRMLS_CC);
678: if ((found != SUCCESS) || !instanceof_function(*ce, curce TSRMLS_CC)) {
679: xmlFreeDoc(newdocp);
680: php_error_docref(NULL TSRMLS_CC, E_WARNING,
681: "Expecting class compatible with %s, '%s' given", curclass_name, ret_class);
682: RETURN_FALSE;
683: }
684:
685: object_init_ex(return_value, *ce);
686:
687: interndoc = (php_libxml_node_object *)zend_objects_get_address(return_value TSRMLS_CC);
688: php_libxml_increment_doc_ref(interndoc, newdocp TSRMLS_CC);
689: php_libxml_increment_node_ptr(interndoc, (xmlNodePtr)newdocp, (void *)interndoc TSRMLS_CC);
690: } else {
1.1.1.2 misho 691: DOM_RET_OBJ((xmlNodePtr) newdocp, &ret, NULL);
1.1 misho 692: }
693: } else {
694: RETURN_FALSE;
695: }
696:
697: }
698: /* }}} end xsl_xsltprocessor_transform_to_doc */
699:
700: /* {{{ proto int xsl_xsltprocessor_transform_to_uri(domdocument doc, string uri);
701: */
702: PHP_FUNCTION(xsl_xsltprocessor_transform_to_uri)
703: {
704: zval *id, *docp = NULL;
705: xmlDoc *newdocp;
706: xsltStylesheetPtr sheetp;
707: int ret, uri_len;
708: char *uri;
709: xsl_object *intern;
710:
711: id = getThis();
712: intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
713: sheetp = (xsltStylesheetPtr) intern->ptr;
714:
1.1.1.2 misho 715: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "op", &docp, &uri, &uri_len) == FAILURE) {
1.1 misho 716: RETURN_FALSE;
717: }
718:
719: newdocp = php_xsl_apply_stylesheet(id, intern, sheetp, docp TSRMLS_CC);
720:
721: ret = -1;
722: if (newdocp) {
723: ret = xsltSaveResultToFilename(uri, newdocp, sheetp, 0);
724: xmlFreeDoc(newdocp);
725: }
726:
727: RETVAL_LONG(ret);
728: }
729: /* }}} end xsl_xsltprocessor_transform_to_uri */
730:
731: /* {{{ proto string xsl_xsltprocessor_transform_to_xml(domdocument doc);
732: */
733: PHP_FUNCTION(xsl_xsltprocessor_transform_to_xml)
734: {
735: zval *id, *docp = NULL;
736: xmlDoc *newdocp;
737: xsltStylesheetPtr sheetp;
738: int ret;
739: xmlChar *doc_txt_ptr;
740: int doc_txt_len;
741: xsl_object *intern;
742:
743: id = getThis();
744: intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
745: sheetp = (xsltStylesheetPtr) intern->ptr;
746:
747: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &docp) == FAILURE) {
748: RETURN_FALSE;
749: }
750:
751: newdocp = php_xsl_apply_stylesheet(id, intern, sheetp, docp TSRMLS_CC);
752:
753: ret = -1;
754: if (newdocp) {
755: ret = xsltSaveResultToString(&doc_txt_ptr, &doc_txt_len, newdocp, sheetp);
756: if (doc_txt_ptr && doc_txt_len) {
757: RETVAL_STRINGL(doc_txt_ptr, doc_txt_len, 1);
758: xmlFree(doc_txt_ptr);
759: }
760: xmlFreeDoc(newdocp);
761: }
762:
763: if (ret < 0) {
764: RETURN_FALSE;
765: }
766: }
767: /* }}} end xsl_xsltprocessor_transform_to_xml */
768:
769: /* {{{ proto bool xsl_xsltprocessor_set_parameter(string namespace, mixed name [, string value]);
770: */
771: PHP_FUNCTION(xsl_xsltprocessor_set_parameter)
772: {
773:
774: zval *id;
775: zval *array_value, **entry, *new_string;
776: xsl_object *intern;
777: char *string_key, *name, *value, *namespace;
778: ulong idx;
779: int string_key_len, namespace_len, name_len, value_len;
780: DOM_GET_THIS(id);
781:
782: if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "sa", &namespace, &namespace_len, &array_value) == SUCCESS) {
783: intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
784: zend_hash_internal_pointer_reset(Z_ARRVAL_P(array_value));
785:
786: while (zend_hash_get_current_data(Z_ARRVAL_P(array_value), (void **)&entry) == SUCCESS) {
787: SEPARATE_ZVAL(entry);
788: convert_to_string_ex(entry);
789:
790: if (zend_hash_get_current_key_ex(Z_ARRVAL_P(array_value), &string_key, &string_key_len, &idx, 0, NULL) != HASH_KEY_IS_STRING) {
791: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid parameter array");
792: RETURN_FALSE;
793: }
794:
795: ALLOC_ZVAL(new_string);
796: Z_ADDREF_PP(entry);
797: COPY_PZVAL_TO_ZVAL(*new_string, *entry);
798:
799: zend_hash_update(intern->parameter, string_key, string_key_len, &new_string, sizeof(zval*), NULL);
800: zend_hash_move_forward(Z_ARRVAL_P(array_value));
801: }
802: RETURN_TRUE;
803:
804: } 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) {
805:
806: intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
807:
808: MAKE_STD_ZVAL(new_string);
809: ZVAL_STRING(new_string, value, 1);
810:
811: zend_hash_update(intern->parameter, name, name_len + 1, &new_string, sizeof(zval*), NULL);
812: RETURN_TRUE;
813: } else {
814: WRONG_PARAM_COUNT;
815: }
816:
817: }
818: /* }}} end xsl_xsltprocessor_set_parameter */
819:
820: /* {{{ proto string xsl_xsltprocessor_get_parameter(string namespace, string name);
821: */
822: PHP_FUNCTION(xsl_xsltprocessor_get_parameter)
823: {
824: zval *id;
825: int name_len = 0, namespace_len = 0;
826: char *name, *namespace;
827: zval **value;
828: xsl_object *intern;
829:
830: DOM_GET_THIS(id);
831:
832: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &namespace, &namespace_len, &name, &name_len) == FAILURE) {
833: RETURN_FALSE;
834: }
835: intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
836: if ( zend_hash_find(intern->parameter, name, name_len + 1, (void**) &value) == SUCCESS) {
837: convert_to_string_ex(value);
838: RETVAL_STRING(Z_STRVAL_PP(value),1);
839: } else {
840: RETURN_FALSE;
841: }
842: }
843: /* }}} end xsl_xsltprocessor_get_parameter */
844:
845: /* {{{ proto bool xsl_xsltprocessor_remove_parameter(string namespace, string name);
846: */
847: PHP_FUNCTION(xsl_xsltprocessor_remove_parameter)
848: {
849: zval *id;
850: int name_len = 0, namespace_len = 0;
851: char *name, *namespace;
852: xsl_object *intern;
853:
854: DOM_GET_THIS(id);
855:
856: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &namespace, &namespace_len, &name, &name_len) == FAILURE) {
857: RETURN_FALSE;
858: }
859: intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
860: if ( zend_hash_del(intern->parameter, name, name_len + 1) == SUCCESS) {
861: RETURN_TRUE;
862: } else {
863: RETURN_FALSE;
864: }
865: }
866: /* }}} end xsl_xsltprocessor_remove_parameter */
867:
868: /* {{{ proto void xsl_xsltprocessor_register_php_functions([mixed $restrict]);
869: */
870: PHP_FUNCTION(xsl_xsltprocessor_register_php_functions)
871: {
872: zval *id;
873: xsl_object *intern;
874: zval *array_value, **entry, *new_string;
875: int name_len = 0;
876: char *name;
877:
878: DOM_GET_THIS(id);
879:
880: if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "a", &array_value) == SUCCESS) {
881: intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
882: zend_hash_internal_pointer_reset(Z_ARRVAL_P(array_value));
883:
884: while (zend_hash_get_current_data(Z_ARRVAL_P(array_value), (void **)&entry) == SUCCESS) {
885: SEPARATE_ZVAL(entry);
886: convert_to_string_ex(entry);
887:
888: MAKE_STD_ZVAL(new_string);
889: ZVAL_LONG(new_string,1);
890:
891: zend_hash_update(intern->registered_phpfunctions, Z_STRVAL_PP(entry), Z_STRLEN_PP(entry) + 1, &new_string, sizeof(zval*), NULL);
892: zend_hash_move_forward(Z_ARRVAL_P(array_value));
893: }
894: intern->registerPhpFunctions = 2;
895:
896: } else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == SUCCESS) {
897: intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
898:
899: MAKE_STD_ZVAL(new_string);
900: ZVAL_LONG(new_string,1);
901: zend_hash_update(intern->registered_phpfunctions, name, name_len + 1, &new_string, sizeof(zval*), NULL);
902: intern->registerPhpFunctions = 2;
903:
904: } else {
905: intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
906: intern->registerPhpFunctions = 1;
907: }
908:
909: }
910: /* }}} end xsl_xsltprocessor_register_php_functions(); */
911:
912: /* {{{ proto bool xsl_xsltprocessor_set_profiling(string filename) */
913: PHP_FUNCTION(xsl_xsltprocessor_set_profiling)
914: {
915: zval *id;
916: xsl_object *intern;
917: char *filename = NULL;
918: int filename_len;
919: DOM_GET_THIS(id);
920:
1.1.1.2 misho 921: if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "p!", &filename, &filename_len) == SUCCESS) {
1.1 misho 922: intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
923: if (intern->profiling) {
924: efree(intern->profiling);
925: }
1.1.1.2 misho 926: if (filename != NULL) {
1.1 misho 927: intern->profiling = estrndup(filename,filename_len);
928: } else {
929: intern->profiling = NULL;
930: }
931: RETURN_TRUE;
932: } else {
933: WRONG_PARAM_COUNT;
934: }
935: }
936: /* }}} end xsl_xsltprocessor_set_profiling */
937:
1.1.1.2 misho 938: /* {{{ proto long xsl_xsltprocessor_set_security_prefs(long securityPrefs) */
939: PHP_FUNCTION(xsl_xsltprocessor_set_security_prefs)
940: {
941: zval *id;
942: xsl_object *intern;
943: long securityPrefs, oldSecurityPrefs;
944:
945: DOM_GET_THIS(id);
946: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &securityPrefs) == FAILURE) {
947: return;
948: }
949: intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
950: oldSecurityPrefs = intern->securityPrefs;
951: intern->securityPrefs = securityPrefs;
952: /* set this to 1 so that we know, it was set through this method. Can be removed, when we remove the ini setting */
953: intern->securityPrefsSet = 1;
954: RETURN_LONG(oldSecurityPrefs);
955: }
956: /* }}} end xsl_xsltprocessor_set_security_prefs */
957:
958: /* {{{ proto long xsl_xsltprocessor_get_security_prefs() */
959: PHP_FUNCTION(xsl_xsltprocessor_get_security_prefs)
960: {
961: zval *id;
962: xsl_object *intern;
963:
964: DOM_GET_THIS(id);
965: if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "") == SUCCESS) {
966: intern = (xsl_object *)zend_object_store_get_object(id TSRMLS_CC);
967: RETURN_LONG(intern->securityPrefs);
968: } else {
969: WRONG_PARAM_COUNT;
970: }
971: }
972: /* }}} end xsl_xsltprocessor_get_security_prefs */
973:
974:
975:
1.1 misho 976: /* {{{ proto bool xsl_xsltprocessor_has_exslt_support();
977: */
978: PHP_FUNCTION(xsl_xsltprocessor_has_exslt_support)
979: {
980: #if HAVE_XSL_EXSLT
981: RETURN_TRUE;
982: #else
983: RETURN_FALSE;
984: #endif
985: }
986: /* }}} end xsl_xsltprocessor_has_exslt_support(); */
987:
988: /*
989: * Local variables:
990: * tab-width: 4
991: * c-basic-offset: 4
992: * End:
993: * vim600: sw=4 ts=4 fdm=marker
994: * vim<600: sw=4 ts=4
995: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>