1 /*
2 +----------------------------------------------------------------------+
3 | PHP Version 7 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1997-2018 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
20 /* $Id$ */
21
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #include "php.h"
27 #if HAVE_LIBXML && HAVE_DOM
28 #include "php_dom.h"
29 #include <libxml/SAX.h>
30 #ifdef LIBXML_SCHEMAS_ENABLED
31 #include <libxml/relaxng.h>
32 #include <libxml/xmlschemas.h>
33 #endif
34
35 typedef struct _idsIterator idsIterator;
36 struct _idsIterator {
37 xmlChar *elementId;
38 xmlNode *element;
39 };
40
41 #define DOM_LOAD_STRING 0
42 #define DOM_LOAD_FILE 1
43
44 /* {{{ arginfo */
45 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_element, 0, 0, 1)
46 ZEND_ARG_INFO(0, tagName)
47 ZEND_ARG_INFO(0, value)
48 ZEND_END_ARG_INFO();
49
50 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_document_fragment, 0, 0, 0)
51 ZEND_END_ARG_INFO();
52
53 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_text_node, 0, 0, 1)
54 ZEND_ARG_INFO(0, data)
55 ZEND_END_ARG_INFO();
56
57 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_comment, 0, 0, 1)
58 ZEND_ARG_INFO(0, data)
59 ZEND_END_ARG_INFO();
60
61 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_cdatasection, 0, 0, 1)
62 ZEND_ARG_INFO(0, data)
63 ZEND_END_ARG_INFO();
64
65 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_processing_instruction, 0, 0, 2)
66 ZEND_ARG_INFO(0, target)
67 ZEND_ARG_INFO(0, data)
68 ZEND_END_ARG_INFO();
69
70 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_attribute, 0, 0, 1)
71 ZEND_ARG_INFO(0, name)
72 ZEND_END_ARG_INFO();
73
74 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_entity_reference, 0, 0, 1)
75 ZEND_ARG_INFO(0, name)
76 ZEND_END_ARG_INFO();
77
78 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_get_elements_by_tag_name, 0, 0, 1)
79 ZEND_ARG_INFO(0, tagName)
80 ZEND_END_ARG_INFO();
81
82 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_import_node, 0, 0, 2)
83 ZEND_ARG_OBJ_INFO(0, importedNode, DOMNode, 0)
84 ZEND_ARG_INFO(0, deep)
85 ZEND_END_ARG_INFO();
86
87 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_element_ns, 0, 0, 2)
88 ZEND_ARG_INFO(0, namespaceURI)
89 ZEND_ARG_INFO(0, qualifiedName)
90 ZEND_ARG_INFO(0, value)
91 ZEND_END_ARG_INFO();
92
93 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_attribute_ns, 0, 0, 2)
94 ZEND_ARG_INFO(0, namespaceURI)
95 ZEND_ARG_INFO(0, qualifiedName)
96 ZEND_END_ARG_INFO();
97
98 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_get_elements_by_tag_name_ns, 0, 0, 2)
99 ZEND_ARG_INFO(0, namespaceURI)
100 ZEND_ARG_INFO(0, localName)
101 ZEND_END_ARG_INFO();
102
103 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_get_element_by_id, 0, 0, 1)
104 ZEND_ARG_INFO(0, elementId)
105 ZEND_END_ARG_INFO();
106
107 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_adopt_node, 0, 0, 1)
108 ZEND_ARG_OBJ_INFO(0, source, DOMNode, 0)
109 ZEND_END_ARG_INFO();
110
111 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_normalize_document, 0, 0, 0)
112 ZEND_END_ARG_INFO();
113
114 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_rename_node, 0, 0, 3)
115 ZEND_ARG_OBJ_INFO(0, node, DOMNode, 0)
116 ZEND_ARG_INFO(0, namespaceURI)
117 ZEND_ARG_INFO(0, qualifiedName)
118 ZEND_END_ARG_INFO();
119
120 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_load, 0, 0, 1)
121 ZEND_ARG_INFO(0, source)
122 ZEND_ARG_INFO(0, options)
123 ZEND_END_ARG_INFO();
124
125 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_save, 0, 0, 1)
126 ZEND_ARG_INFO(0, file)
127 ZEND_END_ARG_INFO();
128
129 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_loadxml, 0, 0, 1)
130 ZEND_ARG_INFO(0, source)
131 ZEND_ARG_INFO(0, options)
132 ZEND_END_ARG_INFO();
133
134 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_savexml, 0, 0, 0)
135 ZEND_ARG_OBJ_INFO(0, node, DOMNode, 1)
136 ZEND_ARG_INFO(0, options)
137 ZEND_END_ARG_INFO();
138
139 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_construct, 0, 0, 0)
140 ZEND_ARG_INFO(0, version)
141 ZEND_ARG_INFO(0, encoding)
142 ZEND_END_ARG_INFO();
143
144 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_validate, 0, 0, 0)
145 ZEND_END_ARG_INFO();
146
147 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_xinclude, 0, 0, 0)
148 ZEND_ARG_INFO(0, options)
149 ZEND_END_ARG_INFO();
150
151 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_loadhtml, 0, 0, 1)
152 ZEND_ARG_INFO(0, source)
153 ZEND_ARG_INFO(0, options)
154 ZEND_END_ARG_INFO();
155
156 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_loadhtmlfile, 0, 0, 1)
157 ZEND_ARG_INFO(0, source)
158 ZEND_ARG_INFO(0, options)
159 ZEND_END_ARG_INFO();
160
161 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_savehtml, 0, 0, 0)
162 ZEND_END_ARG_INFO();
163
164 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_savehtmlfile, 0, 0, 1)
165 ZEND_ARG_INFO(0, file)
166 ZEND_END_ARG_INFO();
167
168 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_schema_validate_file, 0, 0, 1)
169 ZEND_ARG_INFO(0, filename)
170 ZEND_END_ARG_INFO();
171
172 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_schema_validate_xml, 0, 0, 1)
173 ZEND_ARG_INFO(0, source)
174 ZEND_END_ARG_INFO();
175
176 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_relaxNG_validate_file, 0, 0, 1)
177 ZEND_ARG_INFO(0, filename)
178 ZEND_END_ARG_INFO();
179
180 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_relaxNG_validate_xml, 0, 0, 1)
181 ZEND_ARG_INFO(0, source)
182 ZEND_END_ARG_INFO();
183
184 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_registernodeclass, 0, 0, 2)
185 ZEND_ARG_INFO(0, baseClass)
186 ZEND_ARG_INFO(0, extendedClass)
187 ZEND_END_ARG_INFO();
188 /* }}} */
189
190 /*
191 * class DOMDocument extends DOMNode
192 *
193 * URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-i-Document
194 * Since:
195 */
196
197 const zend_function_entry php_dom_document_class_functions[] = { /* {{{ */
198 PHP_FALIAS(createElement, dom_document_create_element, arginfo_dom_document_create_element)
199 PHP_FALIAS(createDocumentFragment, dom_document_create_document_fragment, arginfo_dom_document_create_document_fragment)
200 PHP_FALIAS(createTextNode, dom_document_create_text_node, arginfo_dom_document_create_text_node)
201 PHP_FALIAS(createComment, dom_document_create_comment, arginfo_dom_document_create_comment)
202 PHP_FALIAS(createCDATASection, dom_document_create_cdatasection, arginfo_dom_document_create_cdatasection)
203 PHP_FALIAS(createProcessingInstruction, dom_document_create_processing_instruction, arginfo_dom_document_create_processing_instruction)
204 PHP_FALIAS(createAttribute, dom_document_create_attribute, arginfo_dom_document_create_attribute)
205 PHP_FALIAS(createEntityReference, dom_document_create_entity_reference, arginfo_dom_document_create_entity_reference)
206 PHP_FALIAS(getElementsByTagName, dom_document_get_elements_by_tag_name, arginfo_dom_document_get_elements_by_tag_name)
207 PHP_FALIAS(importNode, dom_document_import_node, arginfo_dom_document_import_node)
208 PHP_FALIAS(createElementNS, dom_document_create_element_ns, arginfo_dom_document_create_element_ns)
209 PHP_FALIAS(createAttributeNS, dom_document_create_attribute_ns, arginfo_dom_document_create_attribute_ns)
210 PHP_FALIAS(getElementsByTagNameNS, dom_document_get_elements_by_tag_name_ns, arginfo_dom_document_get_elements_by_tag_name_ns)
211 PHP_FALIAS(getElementById, dom_document_get_element_by_id, arginfo_dom_document_get_element_by_id)
212 PHP_FALIAS(adoptNode, dom_document_adopt_node, arginfo_dom_document_adopt_node)
213 PHP_FALIAS(normalizeDocument, dom_document_normalize_document, arginfo_dom_document_normalize_document)
214 PHP_FALIAS(renameNode, dom_document_rename_node, arginfo_dom_document_rename_node)
215 PHP_ME(domdocument, load, arginfo_dom_document_load, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC)
216 PHP_FALIAS(save, dom_document_save, arginfo_dom_document_save)
217 PHP_ME(domdocument, loadXML, arginfo_dom_document_loadxml, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC)
218 PHP_FALIAS(saveXML, dom_document_savexml, arginfo_dom_document_savexml)
219 PHP_ME(domdocument, __construct, arginfo_dom_document_construct, ZEND_ACC_PUBLIC)
220 PHP_FALIAS(validate, dom_document_validate, arginfo_dom_document_validate)
221 PHP_FALIAS(xinclude, dom_document_xinclude, arginfo_dom_document_xinclude)
222 #if defined(LIBXML_HTML_ENABLED)
223 PHP_ME(domdocument, loadHTML, arginfo_dom_document_loadhtml, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC)
224 PHP_ME(domdocument, loadHTMLFile, arginfo_dom_document_loadhtmlfile, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC)
225 PHP_FALIAS(saveHTML, dom_document_save_html, arginfo_dom_document_savehtml)
226 PHP_FALIAS(saveHTMLFile, dom_document_save_html_file, arginfo_dom_document_savehtmlfile)
227 #endif /* defined(LIBXML_HTML_ENABLED) */
228 #if defined(LIBXML_SCHEMAS_ENABLED)
229 PHP_FALIAS(schemaValidate, dom_document_schema_validate_file, arginfo_dom_document_schema_validate_file)
230 PHP_FALIAS(schemaValidateSource, dom_document_schema_validate_xml, arginfo_dom_document_schema_validate_xml)
231 PHP_FALIAS(relaxNGValidate, dom_document_relaxNG_validate_file, arginfo_dom_document_relaxNG_validate_file)
232 PHP_FALIAS(relaxNGValidateSource, dom_document_relaxNG_validate_xml, arginfo_dom_document_relaxNG_validate_xml)
233 #endif
234 PHP_ME(domdocument, registerNodeClass, arginfo_dom_document_registernodeclass, ZEND_ACC_PUBLIC)
235 PHP_FE_END
236 };
237 /* }}} */
238
239 /* {{{ docType DOMDocumentType
240 readonly=yes
241 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-B63ED1A31
242 Since:
243 */
dom_document_doctype_read(dom_object * obj,zval * retval)244 int dom_document_doctype_read(dom_object *obj, zval *retval)
245 {
246 xmlDoc *docp = (xmlDocPtr) dom_object_get_node(obj);
247 xmlDtdPtr dtdptr;
248
249 if (docp == NULL) {
250 php_dom_throw_error(INVALID_STATE_ERR, 0);
251 return FAILURE;
252 }
253
254 dtdptr = xmlGetIntSubset(docp);
255 if (!dtdptr) {
256 ZVAL_NULL(retval);
257 return SUCCESS;
258 }
259
260 php_dom_create_object((xmlNodePtr) dtdptr, retval, obj);
261 return SUCCESS;
262 }
263
264 /* }}} */
265
266 /* {{{ implementation DOMImplementation
267 readonly=yes
268 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1B793EBA
269 Since:
270 */
dom_document_implementation_read(dom_object * obj,zval * retval)271 int dom_document_implementation_read(dom_object *obj, zval *retval)
272 {
273 php_dom_create_implementation(retval);
274 return SUCCESS;
275 }
276
277 /* }}} */
278
279 /* {{{ documentElement DOMElement
280 readonly=yes
281 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-87CD092
282 Since:
283 */
dom_document_document_element_read(dom_object * obj,zval * retval)284 int dom_document_document_element_read(dom_object *obj, zval *retval)
285 {
286 xmlDoc *docp = (xmlDocPtr) dom_object_get_node(obj);
287 xmlNode *root;
288
289 if (docp == NULL) {
290 php_dom_throw_error(INVALID_STATE_ERR, 0);
291 return FAILURE;
292 }
293
294 root = xmlDocGetRootElement(docp);
295 if (!root) {
296 ZVAL_NULL(retval);
297 return SUCCESS;
298 }
299
300 php_dom_create_object(root, retval, obj);
301 return SUCCESS;
302 }
303
304 /* }}} */
305
306 /* {{{ encoding string
307 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-encoding
308 Since: DOM Level 3
309 */
dom_document_encoding_read(dom_object * obj,zval * retval)310 int dom_document_encoding_read(dom_object *obj, zval *retval)
311 {
312 xmlDoc *docp = (xmlDocPtr) dom_object_get_node(obj);
313 char *encoding;
314
315 if (docp == NULL) {
316 php_dom_throw_error(INVALID_STATE_ERR, 0);
317 return FAILURE;
318 }
319
320 encoding = (char *) docp->encoding;
321
322 if (encoding != NULL) {
323 ZVAL_STRING(retval, encoding);
324 } else {
325 ZVAL_NULL(retval);
326 }
327
328 return SUCCESS;
329 }
330
dom_document_encoding_write(dom_object * obj,zval * newval)331 int dom_document_encoding_write(dom_object *obj, zval *newval)
332 {
333 xmlDoc *docp = (xmlDocPtr) dom_object_get_node(obj);
334 zend_string *str;
335 xmlCharEncodingHandlerPtr handler;
336
337 if (docp == NULL) {
338 php_dom_throw_error(INVALID_STATE_ERR, 0);
339 return FAILURE;
340 }
341
342 str = zval_get_string(newval);
343
344 handler = xmlFindCharEncodingHandler(ZSTR_VAL(str));
345
346 if (handler != NULL) {
347 xmlCharEncCloseFunc(handler);
348 if (docp->encoding != NULL) {
349 xmlFree((xmlChar *)docp->encoding);
350 }
351 docp->encoding = xmlStrdup((const xmlChar *) ZSTR_VAL(str));
352 } else {
353 php_error_docref(NULL, E_WARNING, "Invalid Document Encoding");
354 }
355
356 zend_string_release(str);
357 return SUCCESS;
358 }
359
360 /* }}} */
361
362 /* {{{ standalone boolean
363 readonly=no
364 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-standalone
365 Since: DOM Level 3
366 */
dom_document_standalone_read(dom_object * obj,zval * retval)367 int dom_document_standalone_read(dom_object *obj, zval *retval)
368 {
369 xmlDoc *docp;
370
371 docp = (xmlDocPtr) dom_object_get_node(obj);
372
373 if (docp == NULL) {
374 php_dom_throw_error(INVALID_STATE_ERR, 0);
375 return FAILURE;
376 }
377
378 ZVAL_BOOL(retval, docp->standalone);
379 return SUCCESS;
380 }
381
dom_document_standalone_write(dom_object * obj,zval * newval)382 int dom_document_standalone_write(dom_object *obj, zval *newval)
383 {
384 xmlDoc *docp = (xmlDocPtr) dom_object_get_node(obj);
385 zend_long standalone;
386
387 if (docp == NULL) {
388 php_dom_throw_error(INVALID_STATE_ERR, 0);
389 return FAILURE;
390 }
391
392 standalone = zval_get_long(newval);
393 docp->standalone = ZEND_NORMALIZE_BOOL(standalone);
394
395 return SUCCESS;
396 }
397
398 /* }}} */
399
400 /* {{{ version string
401 readonly=no
402 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-version
403 Since: DOM Level 3
404 */
dom_document_version_read(dom_object * obj,zval * retval)405 int dom_document_version_read(dom_object *obj, zval *retval)
406 {
407 xmlDoc *docp = (xmlDocPtr) dom_object_get_node(obj);
408 char *version;
409
410 if (docp == NULL) {
411 php_dom_throw_error(INVALID_STATE_ERR, 0);
412 return FAILURE;
413 }
414
415 version = (char *) docp->version;
416
417 if (version != NULL) {
418 ZVAL_STRING(retval, version);
419 } else {
420 ZVAL_NULL(retval);
421 }
422
423 return SUCCESS;
424 }
425
dom_document_version_write(dom_object * obj,zval * newval)426 int dom_document_version_write(dom_object *obj, zval *newval)
427 {
428 xmlDoc *docp = (xmlDocPtr) dom_object_get_node(obj);
429 zend_string *str;
430
431 if (docp == NULL) {
432 php_dom_throw_error(INVALID_STATE_ERR, 0);
433 return FAILURE;
434 }
435
436 if (docp->version != NULL) {
437 xmlFree((xmlChar *) docp->version );
438 }
439
440 str = zval_get_string(newval);
441
442 docp->version = xmlStrdup((const xmlChar *) ZSTR_VAL(str));
443
444 zend_string_release(str);
445 return SUCCESS;
446 }
447
448 /* }}} */
449
450 /* {{{ strictErrorChecking boolean
451 readonly=no
452 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-strictErrorChecking
453 Since: DOM Level 3
454 */
dom_document_strict_error_checking_read(dom_object * obj,zval * retval)455 int dom_document_strict_error_checking_read(dom_object *obj, zval *retval)
456 {
457 if (obj->document) {
458 dom_doc_propsptr doc_prop = dom_get_doc_props(obj->document);
459 ZVAL_BOOL(retval, doc_prop->stricterror);
460 } else {
461 ZVAL_FALSE(retval);
462 }
463 return SUCCESS;
464 }
465
dom_document_strict_error_checking_write(dom_object * obj,zval * newval)466 int dom_document_strict_error_checking_write(dom_object *obj, zval *newval)
467 {
468
469 if (obj->document) {
470 dom_doc_propsptr doc_prop = dom_get_doc_props(obj->document);
471 doc_prop->stricterror = zend_is_true(newval);
472 }
473
474 return SUCCESS;
475 }
476
477 /* }}} */
478
479 /* {{{ formatOutput boolean
480 readonly=no
481 */
dom_document_format_output_read(dom_object * obj,zval * retval)482 int dom_document_format_output_read(dom_object *obj, zval *retval)
483 {
484 if (obj->document) {
485 dom_doc_propsptr doc_prop = dom_get_doc_props(obj->document);
486 ZVAL_BOOL(retval, doc_prop->formatoutput);
487 } else {
488 ZVAL_FALSE(retval);
489 }
490 return SUCCESS;
491 }
492
dom_document_format_output_write(dom_object * obj,zval * newval)493 int dom_document_format_output_write(dom_object *obj, zval *newval)
494 {
495 if (obj->document) {
496 dom_doc_propsptr doc_prop = dom_get_doc_props(obj->document);
497 doc_prop->formatoutput = zend_is_true(newval);
498 }
499
500 return SUCCESS;
501 }
502 /* }}} */
503
504 /* {{{ validateOnParse boolean
505 readonly=no
506 */
dom_document_validate_on_parse_read(dom_object * obj,zval * retval)507 int dom_document_validate_on_parse_read(dom_object *obj, zval *retval)
508 {
509 if (obj->document) {
510 dom_doc_propsptr doc_prop = dom_get_doc_props(obj->document);
511 ZVAL_BOOL(retval, doc_prop->validateonparse);
512 } else {
513 ZVAL_FALSE(retval);
514 }
515 return SUCCESS;
516 }
517
dom_document_validate_on_parse_write(dom_object * obj,zval * newval)518 int dom_document_validate_on_parse_write(dom_object *obj, zval *newval)
519 {
520 if (obj->document) {
521 dom_doc_propsptr doc_prop = dom_get_doc_props(obj->document);
522 doc_prop->validateonparse = zend_is_true(newval);
523 }
524
525 return SUCCESS;
526 }
527 /* }}} */
528
529 /* {{{ resolveExternals boolean
530 readonly=no
531 */
dom_document_resolve_externals_read(dom_object * obj,zval * retval)532 int dom_document_resolve_externals_read(dom_object *obj, zval *retval)
533 {
534 if (obj->document) {
535 dom_doc_propsptr doc_prop = dom_get_doc_props(obj->document);
536 ZVAL_BOOL(retval, doc_prop->resolveexternals);
537 } else {
538 ZVAL_FALSE(retval);
539 }
540 return SUCCESS;
541 }
542
dom_document_resolve_externals_write(dom_object * obj,zval * newval)543 int dom_document_resolve_externals_write(dom_object *obj, zval *newval)
544 {
545 if (obj->document) {
546 dom_doc_propsptr doc_prop = dom_get_doc_props(obj->document);
547 doc_prop->resolveexternals = zend_is_true(newval);
548 }
549
550 return SUCCESS;
551 }
552 /* }}} */
553
554 /* {{{ preserveWhiteSpace boolean
555 readonly=no
556 */
dom_document_preserve_whitespace_read(dom_object * obj,zval * retval)557 int dom_document_preserve_whitespace_read(dom_object *obj, zval *retval)
558 {
559 if (obj->document) {
560 dom_doc_propsptr doc_prop = dom_get_doc_props(obj->document);
561 ZVAL_BOOL(retval, doc_prop->preservewhitespace);
562 } else {
563 ZVAL_FALSE(retval);
564 }
565 return SUCCESS;
566 }
567
dom_document_preserve_whitespace_write(dom_object * obj,zval * newval)568 int dom_document_preserve_whitespace_write(dom_object *obj, zval *newval)
569 {
570 if (obj->document) {
571 dom_doc_propsptr doc_prop = dom_get_doc_props(obj->document);
572 doc_prop->preservewhitespace = zend_is_true(newval);
573 }
574
575 return SUCCESS;
576 }
577 /* }}} */
578
579 /* {{{ recover boolean
580 readonly=no
581 */
dom_document_recover_read(dom_object * obj,zval * retval)582 int dom_document_recover_read(dom_object *obj, zval *retval)
583 {
584 if (obj->document) {
585 dom_doc_propsptr doc_prop = dom_get_doc_props(obj->document);
586 ZVAL_BOOL(retval, doc_prop->recover);
587 } else {
588 ZVAL_FALSE(retval);
589 }
590 return SUCCESS;
591 }
592
dom_document_recover_write(dom_object * obj,zval * newval)593 int dom_document_recover_write(dom_object *obj, zval *newval)
594 {
595 if (obj->document) {
596 dom_doc_propsptr doc_prop = dom_get_doc_props(obj->document);
597 doc_prop->recover = zend_is_true(newval);
598 }
599
600 return SUCCESS;
601 }
602 /* }}} */
603
604 /* {{{ substituteEntities boolean
605 readonly=no
606 */
dom_document_substitue_entities_read(dom_object * obj,zval * retval)607 int dom_document_substitue_entities_read(dom_object *obj, zval *retval)
608 {
609 if (obj->document) {
610 dom_doc_propsptr doc_prop = dom_get_doc_props(obj->document);
611 ZVAL_BOOL(retval, doc_prop->substituteentities);
612 } else {
613 ZVAL_FALSE(retval);
614 }
615 return SUCCESS;
616 }
617
dom_document_substitue_entities_write(dom_object * obj,zval * newval)618 int dom_document_substitue_entities_write(dom_object *obj, zval *newval)
619 {
620 if (obj->document) {
621 dom_doc_propsptr doc_prop = dom_get_doc_props(obj->document);
622 doc_prop->substituteentities = zend_is_true(newval);
623 }
624
625 return SUCCESS;
626 }
627 /* }}} */
628
629 /* {{{ documentURI string
630 readonly=no
631 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-documentURI
632 Since: DOM Level 3
633 */
dom_document_document_uri_read(dom_object * obj,zval * retval)634 int dom_document_document_uri_read(dom_object *obj, zval *retval)
635 {
636 xmlDoc *docp = (xmlDocPtr) dom_object_get_node(obj);
637 char *url;
638
639 if (docp == NULL) {
640 php_dom_throw_error(INVALID_STATE_ERR, 0);
641 return FAILURE;
642 }
643
644 url = (char *) docp->URL;
645 if (url != NULL) {
646 ZVAL_STRING(retval, url);
647 } else {
648 ZVAL_NULL(retval);
649 }
650
651 return SUCCESS;
652 }
653
dom_document_document_uri_write(dom_object * obj,zval * newval)654 int dom_document_document_uri_write(dom_object *obj, zval *newval)
655 {
656 xmlDoc *docp = (xmlDocPtr) dom_object_get_node(obj);
657 zend_string *str;
658
659 if (docp == NULL) {
660 php_dom_throw_error(INVALID_STATE_ERR, 0);
661 return FAILURE;
662 }
663
664 if (docp->URL != NULL) {
665 xmlFree((xmlChar *) docp->URL);
666 }
667
668 str = zval_get_string(newval);
669
670 docp->URL = xmlStrdup((const xmlChar *) ZSTR_VAL(str));
671
672 zend_string_release(str);
673 return SUCCESS;
674 }
675
676 /* }}} */
677
678 /* {{{ config DOMConfiguration
679 readonly=yes
680 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-config
681 Since: DOM Level 3
682 */
dom_document_config_read(dom_object * obj,zval * retval)683 int dom_document_config_read(dom_object *obj, zval *retval)
684 {
685 ZVAL_NULL(retval);
686 return SUCCESS;
687 }
688
689 /* }}} */
690
691 /* {{{ proto DOMElement dom_document_create_element(string tagName [, string value])
692 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-2141741547
693 Since:
694 */
PHP_FUNCTION(dom_document_create_element)695 PHP_FUNCTION(dom_document_create_element)
696 {
697 zval *id;
698 xmlNode *node;
699 xmlDocPtr docp;
700 dom_object *intern;
701 int ret;
702 size_t name_len, value_len;
703 char *name, *value = NULL;
704
705 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os|s", &id, dom_document_class_entry, &name, &name_len, &value, &value_len) == FAILURE) {
706 return;
707 }
708
709 DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
710
711 if (xmlValidateName((xmlChar *) name, 0) != 0) {
712 php_dom_throw_error(INVALID_CHARACTER_ERR, dom_get_strict_error(intern->document));
713 RETURN_FALSE;
714 }
715
716 node = xmlNewDocNode(docp, NULL, (xmlChar *) name, (xmlChar *) value);
717 if (!node) {
718 RETURN_FALSE;
719 }
720
721 DOM_RET_OBJ(node, &ret, intern);
722 }
723 /* }}} end dom_document_create_element */
724
725 /* {{{ proto DOMDocumentFragment dom_document_create_document_fragment()
726 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-35CB04B5
727 Since:
728 */
PHP_FUNCTION(dom_document_create_document_fragment)729 PHP_FUNCTION(dom_document_create_document_fragment)
730 {
731 zval *id;
732 xmlNode *node;
733 xmlDocPtr docp;
734 dom_object *intern;
735 int ret;
736
737 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &id, dom_document_class_entry) == FAILURE) {
738 return;
739 }
740
741 DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
742
743 node = xmlNewDocFragment(docp);
744 if (!node) {
745 RETURN_FALSE;
746 }
747
748 DOM_RET_OBJ(node, &ret, intern);
749 }
750 /* }}} end dom_document_create_document_fragment */
751
752 /* {{{ proto DOMText dom_document_create_text_node(string data)
753 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1975348127
754 Since:
755 */
PHP_FUNCTION(dom_document_create_text_node)756 PHP_FUNCTION(dom_document_create_text_node)
757 {
758 zval *id;
759 xmlNode *node;
760 xmlDocPtr docp;
761 int ret;
762 size_t value_len;
763 dom_object *intern;
764 char *value;
765
766 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os", &id, dom_document_class_entry, &value, &value_len) == FAILURE) {
767 return;
768 }
769
770 DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
771
772 node = xmlNewDocText(docp, (xmlChar *) value);
773 if (!node) {
774 RETURN_FALSE;
775 }
776
777 DOM_RET_OBJ(node, &ret, intern);
778 }
779 /* }}} end dom_document_create_text_node */
780
781 /* {{{ proto DOMComment dom_document_create_comment(string data)
782 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1334481328
783 Since:
784 */
PHP_FUNCTION(dom_document_create_comment)785 PHP_FUNCTION(dom_document_create_comment)
786 {
787 zval *id;
788 xmlNode *node;
789 xmlDocPtr docp;
790 int ret;
791 size_t value_len;
792 dom_object *intern;
793 char *value;
794
795 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os", &id, dom_document_class_entry, &value, &value_len) == FAILURE) {
796 return;
797 }
798
799 DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
800
801 node = xmlNewDocComment(docp, (xmlChar *) value);
802 if (!node) {
803 RETURN_FALSE;
804 }
805
806 DOM_RET_OBJ(node, &ret, intern);
807 }
808 /* }}} end dom_document_create_comment */
809
810 /* {{{ proto DOMCdataSection dom_document_create_cdatasection(string data)
811 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-D26C0AF8
812 Since:
813 */
PHP_FUNCTION(dom_document_create_cdatasection)814 PHP_FUNCTION(dom_document_create_cdatasection)
815 {
816 zval *id;
817 xmlNode *node;
818 xmlDocPtr docp;
819 int ret;
820 size_t value_len;
821 dom_object *intern;
822 char *value;
823
824 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os", &id, dom_document_class_entry, &value, &value_len) == FAILURE) {
825 return;
826 }
827
828 DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
829
830 node = xmlNewCDataBlock(docp, (xmlChar *) value, value_len);
831 if (!node) {
832 RETURN_FALSE;
833 }
834
835 DOM_RET_OBJ(node, &ret, intern);
836 }
837 /* }}} end dom_document_create_cdatasection */
838
839 /* {{{ proto DOMProcessingInstruction dom_document_create_processing_instruction(string target, string data)
840 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-135944439
841 Since:
842 */
PHP_FUNCTION(dom_document_create_processing_instruction)843 PHP_FUNCTION(dom_document_create_processing_instruction)
844 {
845 zval *id;
846 xmlNode *node;
847 xmlDocPtr docp;
848 int ret;
849 size_t value_len, name_len = 0;
850 dom_object *intern;
851 char *name, *value = NULL;
852
853 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os|s", &id, dom_document_class_entry, &name, &name_len, &value, &value_len) == FAILURE) {
854 return;
855 }
856
857 DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
858
859 if (xmlValidateName((xmlChar *) name, 0) != 0) {
860 php_dom_throw_error(INVALID_CHARACTER_ERR, dom_get_strict_error(intern->document));
861 RETURN_FALSE;
862 }
863
864 node = xmlNewPI((xmlChar *) name, (xmlChar *) value);
865 if (!node) {
866 RETURN_FALSE;
867 }
868
869 node->doc = docp;
870
871 DOM_RET_OBJ(node, &ret, intern);
872 }
873 /* }}} end dom_document_create_processing_instruction */
874
875 /* {{{ proto DOMAttr dom_document_create_attribute(string name)
876 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1084891198
877 Since:
878 */
PHP_FUNCTION(dom_document_create_attribute)879 PHP_FUNCTION(dom_document_create_attribute)
880 {
881 zval *id;
882 xmlAttrPtr node;
883 xmlDocPtr docp;
884 int ret;
885 size_t name_len;
886 dom_object *intern;
887 char *name;
888
889 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os", &id, dom_document_class_entry, &name, &name_len) == FAILURE) {
890 return;
891 }
892
893 DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
894
895 if (xmlValidateName((xmlChar *) name, 0) != 0) {
896 php_dom_throw_error(INVALID_CHARACTER_ERR, dom_get_strict_error(intern->document));
897 RETURN_FALSE;
898 }
899
900 node = xmlNewDocProp(docp, (xmlChar *) name, NULL);
901 if (!node) {
902 RETURN_FALSE;
903 }
904
905 DOM_RET_OBJ((xmlNodePtr) node, &ret, intern);
906
907 }
908 /* }}} end dom_document_create_attribute */
909
910 /* {{{ proto DOMEntityReference dom_document_create_entity_reference(string name)
911 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-392B75AE
912 Since:
913 */
PHP_FUNCTION(dom_document_create_entity_reference)914 PHP_FUNCTION(dom_document_create_entity_reference)
915 {
916 zval *id;
917 xmlNode *node;
918 xmlDocPtr docp = NULL;
919 dom_object *intern;
920 int ret;
921 size_t name_len;
922 char *name;
923
924 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os", &id, dom_document_class_entry, &name, &name_len) == FAILURE) {
925 return;
926 }
927
928 DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
929
930 if (xmlValidateName((xmlChar *) name, 0) != 0) {
931 php_dom_throw_error(INVALID_CHARACTER_ERR, dom_get_strict_error(intern->document));
932 RETURN_FALSE;
933 }
934
935 node = xmlNewReference(docp, (xmlChar *) name);
936 if (!node) {
937 RETURN_FALSE;
938 }
939
940 DOM_RET_OBJ((xmlNodePtr) node, &ret, intern);
941 }
942 /* }}} end dom_document_create_entity_reference */
943
944 /* {{{ proto DOMNodeList dom_document_get_elements_by_tag_name(string tagname)
945 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-A6C9094
946 Since:
947 */
PHP_FUNCTION(dom_document_get_elements_by_tag_name)948 PHP_FUNCTION(dom_document_get_elements_by_tag_name)
949 {
950 zval *id;
951 xmlDocPtr docp;
952 size_t name_len;
953 dom_object *intern, *namednode;
954 char *name;
955 xmlChar *local;
956
957 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os", &id, dom_document_class_entry, &name, &name_len) == FAILURE) {
958 return;
959 }
960
961 DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
962
963 php_dom_create_interator(return_value, DOM_NODELIST);
964 namednode = Z_DOMOBJ_P(return_value);
965 local = xmlCharStrndup(name, name_len);
966 dom_namednode_iter(intern, 0, namednode, NULL, local, NULL);
967 }
968 /* }}} end dom_document_get_elements_by_tag_name */
969
970 /* {{{ proto DOMNode dom_document_import_node(DOMNode importedNode, boolean deep)
971 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Core-Document-importNode
972 Since: DOM Level 2
973 */
PHP_FUNCTION(dom_document_import_node)974 PHP_FUNCTION(dom_document_import_node)
975 {
976 zval *id, *node;
977 xmlDocPtr docp;
978 xmlNodePtr nodep, retnodep;
979 dom_object *intern, *nodeobj;
980 int ret;
981 zend_bool recursive = 0;
982
983 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "OO|b", &id, dom_document_class_entry, &node, dom_node_class_entry, &recursive) == FAILURE) {
984 return;
985 }
986
987 DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
988
989 DOM_GET_OBJ(nodep, node, xmlNodePtr, nodeobj);
990
991 if (nodep->type == XML_HTML_DOCUMENT_NODE || nodep->type == XML_DOCUMENT_NODE
992 || nodep->type == XML_DOCUMENT_TYPE_NODE) {
993 php_error_docref(NULL, E_WARNING, "Cannot import: Node Type Not Supported");
994 RETURN_FALSE;
995 }
996
997 if (nodep->doc == docp) {
998 retnodep = nodep;
999 } else {
1000 if ((recursive == 0) && (nodep->type == XML_ELEMENT_NODE)) {
1001 recursive = 2;
1002 }
1003 retnodep = xmlDocCopyNode(nodep, docp, recursive);
1004 if (!retnodep) {
1005 RETURN_FALSE;
1006 }
1007
1008 if ((retnodep->type == XML_ATTRIBUTE_NODE) && (nodep->ns != NULL)) {
1009 xmlNsPtr nsptr = NULL;
1010 xmlNodePtr root = xmlDocGetRootElement(docp);
1011
1012 nsptr = xmlSearchNsByHref (nodep->doc, root, nodep->ns->href);
1013 if (nsptr == NULL) {
1014 int errorcode;
1015 nsptr = dom_get_ns(root, (char *) nodep->ns->href, &errorcode, (char *) nodep->ns->prefix);
1016 }
1017 xmlSetNs(retnodep, nsptr);
1018 }
1019 }
1020
1021 DOM_RET_OBJ((xmlNodePtr) retnodep, &ret, intern);
1022 }
1023 /* }}} end dom_document_import_node */
1024
1025 /* {{{ proto DOMElement dom_document_create_element_ns(string namespaceURI, string qualifiedName [,string value])
1026 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-DocCrElNS
1027 Since: DOM Level 2
1028 */
PHP_FUNCTION(dom_document_create_element_ns)1029 PHP_FUNCTION(dom_document_create_element_ns)
1030 {
1031 zval *id;
1032 xmlDocPtr docp;
1033 xmlNodePtr nodep = NULL;
1034 xmlNsPtr nsptr = NULL;
1035 int ret;
1036 size_t uri_len = 0, name_len = 0, value_len = 0;
1037 char *uri, *name, *value = NULL;
1038 char *localname = NULL, *prefix = NULL;
1039 int errorcode;
1040 dom_object *intern;
1041
1042 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os!s|s", &id, dom_document_class_entry, &uri, &uri_len, &name, &name_len, &value, &value_len) == FAILURE) {
1043 return;
1044 }
1045
1046 DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
1047
1048 errorcode = dom_check_qname(name, &localname, &prefix, uri_len, name_len);
1049
1050 if (errorcode == 0) {
1051 if (xmlValidateName((xmlChar *) localname, 0) == 0) {
1052 nodep = xmlNewDocNode(docp, NULL, (xmlChar *) localname, (xmlChar *) value);
1053 if (nodep != NULL && uri != NULL) {
1054 nsptr = xmlSearchNsByHref(nodep->doc, nodep, (xmlChar *) uri);
1055 if (nsptr == NULL) {
1056 nsptr = dom_get_ns(nodep, uri, &errorcode, prefix);
1057 }
1058 xmlSetNs(nodep, nsptr);
1059 }
1060 } else {
1061 errorcode = INVALID_CHARACTER_ERR;
1062 }
1063 }
1064
1065 xmlFree(localname);
1066 if (prefix != NULL) {
1067 xmlFree(prefix);
1068 }
1069
1070 if (errorcode != 0) {
1071 if (nodep != NULL) {
1072 xmlFreeNode(nodep);
1073 }
1074 php_dom_throw_error(errorcode, dom_get_strict_error(intern->document));
1075 RETURN_FALSE;
1076 }
1077
1078 if (nodep == NULL) {
1079 RETURN_FALSE;
1080 }
1081
1082
1083 nodep->ns = nsptr;
1084
1085 DOM_RET_OBJ(nodep, &ret, intern);
1086 }
1087 /* }}} end dom_document_create_element_ns */
1088
1089 /* {{{ proto DOMAttr dom_document_create_attribute_ns(string namespaceURI, string qualifiedName)
1090 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-DocCrAttrNS
1091 Since: DOM Level 2
1092 */
PHP_FUNCTION(dom_document_create_attribute_ns)1093 PHP_FUNCTION(dom_document_create_attribute_ns)
1094 {
1095 zval *id;
1096 xmlDocPtr docp;
1097 xmlNodePtr nodep = NULL, root;
1098 xmlNsPtr nsptr;
1099 int ret;
1100 size_t uri_len = 0, name_len = 0;
1101 char *uri, *name;
1102 char *localname = NULL, *prefix = NULL;
1103 dom_object *intern;
1104 int errorcode;
1105
1106 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os!s", &id, dom_document_class_entry, &uri, &uri_len, &name, &name_len) == FAILURE) {
1107 return;
1108 }
1109
1110 DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
1111
1112 root = xmlDocGetRootElement(docp);
1113 if (root != NULL) {
1114 errorcode = dom_check_qname(name, &localname, &prefix, uri_len, name_len);
1115 if (errorcode == 0) {
1116 if (xmlValidateName((xmlChar *) localname, 0) == 0) {
1117 nodep = (xmlNodePtr) xmlNewDocProp(docp, (xmlChar *) localname, NULL);
1118 if (nodep != NULL && uri_len > 0) {
1119 nsptr = xmlSearchNsByHref(nodep->doc, root, (xmlChar *) uri);
1120 if (nsptr == NULL) {
1121 nsptr = dom_get_ns(root, uri, &errorcode, prefix);
1122 }
1123 xmlSetNs(nodep, nsptr);
1124 }
1125 } else {
1126 errorcode = INVALID_CHARACTER_ERR;
1127 }
1128 }
1129 } else {
1130 php_error_docref(NULL, E_WARNING, "Document Missing Root Element");
1131 RETURN_FALSE;
1132 }
1133
1134 xmlFree(localname);
1135 if (prefix != NULL) {
1136 xmlFree(prefix);
1137 }
1138
1139 if (errorcode != 0) {
1140 if (nodep != NULL) {
1141 xmlFreeProp((xmlAttrPtr) nodep);
1142 }
1143 php_dom_throw_error(errorcode, dom_get_strict_error(intern->document));
1144 RETURN_FALSE;
1145 }
1146
1147 if (nodep == NULL) {
1148 RETURN_FALSE;
1149 }
1150
1151 DOM_RET_OBJ(nodep, &ret, intern);
1152 }
1153 /* }}} end dom_document_create_attribute_ns */
1154
1155 /* {{{ proto DOMNodeList dom_document_get_elements_by_tag_name_ns(string namespaceURI, string localName)
1156 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-getElBTNNS
1157 Since: DOM Level 2
1158 */
PHP_FUNCTION(dom_document_get_elements_by_tag_name_ns)1159 PHP_FUNCTION(dom_document_get_elements_by_tag_name_ns)
1160 {
1161 zval *id;
1162 xmlDocPtr docp;
1163 size_t uri_len, name_len;
1164 dom_object *intern, *namednode;
1165 char *uri, *name;
1166 xmlChar *local, *nsuri;
1167
1168 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Oss", &id, dom_document_class_entry, &uri, &uri_len, &name, &name_len) == FAILURE) {
1169 return;
1170 }
1171
1172 DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
1173
1174 php_dom_create_interator(return_value, DOM_NODELIST);
1175 namednode = Z_DOMOBJ_P(return_value);
1176 local = xmlCharStrndup(name, name_len);
1177 nsuri = xmlCharStrndup(uri, uri_len);
1178 dom_namednode_iter(intern, 0, namednode, NULL, local, nsuri);
1179 }
1180 /* }}} end dom_document_get_elements_by_tag_name_ns */
1181
1182 /* {{{ proto DOMElement dom_document_get_element_by_id(string elementId)
1183 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-getElBId
1184 Since: DOM Level 2
1185 */
PHP_FUNCTION(dom_document_get_element_by_id)1186 PHP_FUNCTION(dom_document_get_element_by_id)
1187 {
1188 zval *id;
1189 xmlDocPtr docp;
1190 xmlAttrPtr attrp;
1191 int ret;
1192 size_t idname_len;
1193 dom_object *intern;
1194 char *idname;
1195
1196 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os", &id, dom_document_class_entry, &idname, &idname_len) == FAILURE) {
1197 return;
1198 }
1199
1200 DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
1201
1202 attrp = xmlGetID(docp, (xmlChar *) idname);
1203
1204 if (attrp && attrp->parent) {
1205 DOM_RET_OBJ((xmlNodePtr) attrp->parent, &ret, intern);
1206 } else {
1207 RETVAL_NULL();
1208 }
1209
1210 }
1211 /* }}} end dom_document_get_element_by_id */
1212
1213 /* {{{ proto DOMNode dom_document_adopt_node(DOMNode source)
1214 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-adoptNode
1215 Since: DOM Level 3
1216 */
PHP_FUNCTION(dom_document_adopt_node)1217 PHP_FUNCTION(dom_document_adopt_node)
1218 {
1219 DOM_NOT_IMPLEMENTED();
1220 }
1221 /* }}} end dom_document_adopt_node */
1222
1223 /* {{{ proto void dom_document_normalize_document()
1224 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-normalizeDocument
1225 Since: DOM Level 3
1226 */
PHP_FUNCTION(dom_document_normalize_document)1227 PHP_FUNCTION(dom_document_normalize_document)
1228 {
1229 zval *id;
1230 xmlDocPtr docp;
1231 dom_object *intern;
1232
1233 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &id, dom_document_class_entry) == FAILURE) {
1234 return;
1235 }
1236
1237 DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
1238
1239 dom_normalize((xmlNodePtr) docp);
1240 }
1241 /* }}} end dom_document_normalize_document */
1242
1243 /* {{{ proto DOMNode dom_document_rename_node(node n, string namespaceURI, string qualifiedName)
1244 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-renameNode
1245 Since: DOM Level 3
1246 */
PHP_FUNCTION(dom_document_rename_node)1247 PHP_FUNCTION(dom_document_rename_node)
1248 {
1249 DOM_NOT_IMPLEMENTED();
1250 }
1251 /* }}} end dom_document_rename_node */
1252
1253 /* {{{ proto void DOMDocument::__construct([string version], [string encoding]); */
PHP_METHOD(domdocument,__construct)1254 PHP_METHOD(domdocument, __construct)
1255 {
1256
1257 zval *id = getThis();
1258 xmlDoc *docp = NULL, *olddoc;
1259 dom_object *intern;
1260 char *encoding, *version = NULL;
1261 size_t encoding_len = 0, version_len = 0;
1262 int refcount;
1263
1264 if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "|ss", &version, &version_len, &encoding, &encoding_len) == FAILURE) {
1265 return;
1266 }
1267
1268 docp = xmlNewDoc((xmlChar *) version);
1269
1270 if (!docp) {
1271 php_dom_throw_error(INVALID_STATE_ERR, 1);
1272 RETURN_FALSE;
1273 }
1274
1275 if (encoding_len > 0) {
1276 docp->encoding = (const xmlChar *) xmlStrdup((xmlChar *) encoding);
1277 }
1278
1279 intern = Z_DOMOBJ_P(id);
1280 if (intern != NULL) {
1281 olddoc = (xmlDocPtr) dom_object_get_node(intern);
1282 if (olddoc != NULL) {
1283 php_libxml_decrement_node_ptr((php_libxml_node_object *) intern);
1284 refcount = php_libxml_decrement_doc_ref((php_libxml_node_object *)intern);
1285 if (refcount != 0) {
1286 olddoc->_private = NULL;
1287 }
1288 }
1289 intern->document = NULL;
1290 if (php_libxml_increment_doc_ref((php_libxml_node_object *)intern, docp) == -1) {
1291 RETURN_FALSE;
1292 }
1293 php_libxml_increment_node_ptr((php_libxml_node_object *)intern, (xmlNodePtr)docp, (void *)intern);
1294 }
1295 }
1296 /* }}} end DOMDocument::__construct */
1297
_dom_get_valid_file_path(char * source,char * resolved_path,int resolved_path_len)1298 char *_dom_get_valid_file_path(char *source, char *resolved_path, int resolved_path_len ) /* {{{ */
1299 {
1300 xmlURI *uri;
1301 xmlChar *escsource;
1302 char *file_dest;
1303 int isFileUri = 0;
1304
1305 uri = xmlCreateURI();
1306 escsource = xmlURIEscapeStr((xmlChar *) source, (xmlChar *) ":");
1307 xmlParseURIReference(uri, (char *) escsource);
1308 xmlFree(escsource);
1309
1310 if (uri->scheme != NULL) {
1311 /* absolute file uris - libxml only supports localhost or empty host */
1312 #ifdef PHP_WIN32
1313 if (strncasecmp(source, "file://",7) == 0 && ':' == source[8]) {
1314 isFileUri = 1;
1315 source += 7;
1316 } else
1317 #endif
1318 if (strncasecmp(source, "file:///",8) == 0) {
1319 isFileUri = 1;
1320 #ifdef PHP_WIN32
1321 source += 8;
1322 #else
1323 source += 7;
1324 #endif
1325 } else if (strncasecmp(source, "file://localhost/",17) == 0) {
1326 isFileUri = 1;
1327 #ifdef PHP_WIN32
1328 source += 17;
1329 #else
1330 source += 16;
1331 #endif
1332 }
1333 }
1334
1335 file_dest = source;
1336
1337 if ((uri->scheme == NULL || isFileUri)) {
1338 /* XXX possible buffer overflow if VCWD_REALPATH does not know size of resolved_path */
1339 if (!VCWD_REALPATH(source, resolved_path) && !expand_filepath(source, resolved_path)) {
1340 xmlFreeURI(uri);
1341 return NULL;
1342 }
1343 file_dest = resolved_path;
1344 }
1345
1346 xmlFreeURI(uri);
1347
1348 return file_dest;
1349 }
1350 /* }}} */
1351
dom_document_parser(zval * id,int mode,char * source,size_t source_len,size_t options)1352 static xmlDocPtr dom_document_parser(zval *id, int mode, char *source, size_t source_len, size_t options) /* {{{ */
1353 {
1354 xmlDocPtr ret;
1355 xmlParserCtxtPtr ctxt = NULL;
1356 dom_doc_propsptr doc_props;
1357 dom_object *intern;
1358 php_libxml_ref_obj *document = NULL;
1359 int validate, recover, resolve_externals, keep_blanks, substitute_ent;
1360 int resolved_path_len;
1361 int old_error_reporting = 0;
1362 char *directory=NULL, resolved_path[MAXPATHLEN];
1363
1364 if (id != NULL) {
1365 intern = Z_DOMOBJ_P(id);
1366 document = intern->document;
1367 }
1368
1369 doc_props = dom_get_doc_props(document);
1370 validate = doc_props->validateonparse;
1371 resolve_externals = doc_props->resolveexternals;
1372 keep_blanks = doc_props->preservewhitespace;
1373 substitute_ent = doc_props->substituteentities;
1374 recover = doc_props->recover;
1375
1376 if (document == NULL) {
1377 efree(doc_props);
1378 }
1379
1380 xmlInitParser();
1381
1382 if (mode == DOM_LOAD_FILE) {
1383 char *file_dest;
1384 if (CHECK_NULL_PATH(source, source_len)) {
1385 return NULL;
1386 }
1387 file_dest = _dom_get_valid_file_path(source, resolved_path, MAXPATHLEN);
1388 if (file_dest) {
1389 ctxt = xmlCreateFileParserCtxt(file_dest);
1390 }
1391
1392 } else {
1393 ctxt = xmlCreateMemoryParserCtxt(source, source_len);
1394 }
1395
1396 if (ctxt == NULL) {
1397 return(NULL);
1398 }
1399
1400 /* If loading from memory, we need to set the base directory for the document */
1401 if (mode != DOM_LOAD_FILE) {
1402 #if HAVE_GETCWD
1403 directory = VCWD_GETCWD(resolved_path, MAXPATHLEN);
1404 #elif HAVE_GETWD
1405 directory = VCWD_GETWD(resolved_path);
1406 #endif
1407 if (directory) {
1408 if(ctxt->directory != NULL) {
1409 xmlFree((char *) ctxt->directory);
1410 }
1411 resolved_path_len = strlen(resolved_path);
1412 if (resolved_path[resolved_path_len - 1] != DEFAULT_SLASH) {
1413 resolved_path[resolved_path_len] = DEFAULT_SLASH;
1414 resolved_path[++resolved_path_len] = '\0';
1415 }
1416 ctxt->directory = (char *) xmlCanonicPath((const xmlChar *) resolved_path);
1417 }
1418 }
1419
1420 ctxt->vctxt.error = php_libxml_ctx_error;
1421 ctxt->vctxt.warning = php_libxml_ctx_warning;
1422
1423 if (ctxt->sax != NULL) {
1424 ctxt->sax->error = php_libxml_ctx_error;
1425 ctxt->sax->warning = php_libxml_ctx_warning;
1426 }
1427
1428 if (validate && ! (options & XML_PARSE_DTDVALID)) {
1429 options |= XML_PARSE_DTDVALID;
1430 }
1431 if (resolve_externals && ! (options & XML_PARSE_DTDATTR)) {
1432 options |= XML_PARSE_DTDATTR;
1433 }
1434 if (substitute_ent && ! (options & XML_PARSE_NOENT)) {
1435 options |= XML_PARSE_NOENT;
1436 }
1437 if (keep_blanks == 0 && ! (options & XML_PARSE_NOBLANKS)) {
1438 options |= XML_PARSE_NOBLANKS;
1439 }
1440
1441 xmlCtxtUseOptions(ctxt, options);
1442
1443 ctxt->recovery = recover;
1444 if (recover) {
1445 old_error_reporting = EG(error_reporting);
1446 EG(error_reporting) = old_error_reporting | E_WARNING;
1447 }
1448
1449 xmlParseDocument(ctxt);
1450
1451 if (ctxt->wellFormed || recover) {
1452 ret = ctxt->myDoc;
1453 if (ctxt->recovery) {
1454 EG(error_reporting) = old_error_reporting;
1455 }
1456 /* If loading from memory, set the base reference uri for the document */
1457 if (ret && ret->URL == NULL && ctxt->directory != NULL) {
1458 ret->URL = xmlStrdup((xmlChar *) ctxt->directory);
1459 }
1460 } else {
1461 ret = NULL;
1462 xmlFreeDoc(ctxt->myDoc);
1463 ctxt->myDoc = NULL;
1464 }
1465
1466 xmlFreeParserCtxt(ctxt);
1467
1468 return(ret);
1469 }
1470 /* }}} */
1471
1472 /* {{{ static void dom_parse_document(INTERNAL_FUNCTION_PARAMETERS, int mode) */
dom_parse_document(INTERNAL_FUNCTION_PARAMETERS,int mode)1473 static void dom_parse_document(INTERNAL_FUNCTION_PARAMETERS, int mode) {
1474 zval *id;
1475 xmlDoc *docp = NULL, *newdoc;
1476 dom_doc_propsptr doc_prop;
1477 dom_object *intern;
1478 char *source;
1479 size_t source_len;
1480 int refcount, ret;
1481 zend_long options = 0;
1482
1483 id = getThis();
1484 if (id != NULL && ! instanceof_function(Z_OBJCE_P(id), dom_document_class_entry)) {
1485 id = NULL;
1486 }
1487
1488 if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|l", &source, &source_len, &options) == FAILURE) {
1489 return;
1490 }
1491
1492 if (!source_len) {
1493 php_error_docref(NULL, E_WARNING, "Empty string supplied as input");
1494 RETURN_FALSE;
1495 }
1496 if (ZEND_SIZE_T_INT_OVFL(source_len)) {
1497 php_error_docref(NULL, E_WARNING, "Input string is too long");
1498 RETURN_FALSE;
1499 }
1500 if (ZEND_LONG_EXCEEDS_INT(options)) {
1501 php_error_docref(NULL, E_WARNING, "Invalid options");
1502 RETURN_FALSE;
1503 }
1504
1505 newdoc = dom_document_parser(id, mode, source, source_len, options);
1506
1507 if (!newdoc)
1508 RETURN_FALSE;
1509
1510 if (id != NULL) {
1511 intern = Z_DOMOBJ_P(id);
1512 if (intern != NULL) {
1513 docp = (xmlDocPtr) dom_object_get_node(intern);
1514 doc_prop = NULL;
1515 if (docp != NULL) {
1516 php_libxml_decrement_node_ptr((php_libxml_node_object *) intern);
1517 doc_prop = intern->document->doc_props;
1518 intern->document->doc_props = NULL;
1519 refcount = php_libxml_decrement_doc_ref((php_libxml_node_object *)intern);
1520 if (refcount != 0) {
1521 docp->_private = NULL;
1522 }
1523 }
1524 intern->document = NULL;
1525 if (php_libxml_increment_doc_ref((php_libxml_node_object *)intern, newdoc) == -1) {
1526 RETURN_FALSE;
1527 }
1528 intern->document->doc_props = doc_prop;
1529 }
1530
1531 php_libxml_increment_node_ptr((php_libxml_node_object *)intern, (xmlNodePtr)newdoc, (void *)intern);
1532
1533 RETURN_TRUE;
1534 } else {
1535 DOM_RET_OBJ((xmlNodePtr) newdoc, &ret, NULL);
1536 }
1537 }
1538 /* }}} end dom_parser_document */
1539
1540 /* {{{ proto DOMNode dom_document_load(string source [, int options])
1541 URL: http://www.w3.org/TR/DOM-Level-3-LS/load-save.html#LS-DocumentLS-load
1542 Since: DOM Level 3
1543 */
PHP_METHOD(domdocument,load)1544 PHP_METHOD(domdocument, load)
1545 {
1546 dom_parse_document(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_FILE);
1547 }
1548 /* }}} end dom_document_load */
1549
1550 /* {{{ proto DOMNode dom_document_loadxml(string source [, int options])
1551 URL: http://www.w3.org/TR/DOM-Level-3-LS/load-save.html#LS-DocumentLS-loadXML
1552 Since: DOM Level 3
1553 */
PHP_METHOD(domdocument,loadXML)1554 PHP_METHOD(domdocument, loadXML)
1555 {
1556 dom_parse_document(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_STRING);
1557 }
1558 /* }}} end dom_document_loadxml */
1559
1560 /* {{{ proto int dom_document_save(string file)
1561 Convenience method to save to file
1562 */
PHP_FUNCTION(dom_document_save)1563 PHP_FUNCTION(dom_document_save)
1564 {
1565 zval *id;
1566 xmlDoc *docp;
1567 size_t file_len = 0;
1568 int bytes, format, saveempty = 0;
1569 dom_object *intern;
1570 dom_doc_propsptr doc_props;
1571 char *file;
1572 zend_long options = 0;
1573
1574 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Op|l", &id, dom_document_class_entry, &file, &file_len, &options) == FAILURE) {
1575 return;
1576 }
1577
1578 if (file_len == 0) {
1579 php_error_docref(NULL, E_WARNING, "Invalid Filename");
1580 RETURN_FALSE;
1581 }
1582
1583 DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
1584
1585 /* encoding handled by property on doc */
1586
1587 doc_props = dom_get_doc_props(intern->document);
1588 format = doc_props->formatoutput;
1589 if (options & LIBXML_SAVE_NOEMPTYTAG) {
1590 saveempty = xmlSaveNoEmptyTags;
1591 xmlSaveNoEmptyTags = 1;
1592 }
1593 bytes = xmlSaveFormatFileEnc(file, docp, NULL, format);
1594 if (options & LIBXML_SAVE_NOEMPTYTAG) {
1595 xmlSaveNoEmptyTags = saveempty;
1596 }
1597 if (bytes == -1) {
1598 RETURN_FALSE;
1599 }
1600 RETURN_LONG(bytes);
1601 }
1602 /* }}} end dom_document_save */
1603
1604 /* {{{ proto string dom_document_savexml([node n])
1605 URL: http://www.w3.org/TR/DOM-Level-3-LS/load-save.html#LS-DocumentLS-saveXML
1606 Since: DOM Level 3
1607 */
PHP_FUNCTION(dom_document_savexml)1608 PHP_FUNCTION(dom_document_savexml)
1609 {
1610 zval *id, *nodep = NULL;
1611 xmlDoc *docp;
1612 xmlNode *node;
1613 xmlBufferPtr buf;
1614 xmlChar *mem;
1615 dom_object *intern, *nodeobj;
1616 dom_doc_propsptr doc_props;
1617 int size, format, saveempty = 0;
1618 zend_long options = 0;
1619
1620 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O|O!l", &id, dom_document_class_entry, &nodep, dom_node_class_entry, &options) == FAILURE) {
1621 return;
1622 }
1623
1624 DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
1625
1626 doc_props = dom_get_doc_props(intern->document);
1627 format = doc_props->formatoutput;
1628
1629 if (nodep != NULL) {
1630 /* Dump contents of Node */
1631 DOM_GET_OBJ(node, nodep, xmlNodePtr, nodeobj);
1632 if (node->doc != docp) {
1633 php_dom_throw_error(WRONG_DOCUMENT_ERR, dom_get_strict_error(intern->document));
1634 RETURN_FALSE;
1635 }
1636 buf = xmlBufferCreate();
1637 if (!buf) {
1638 php_error_docref(NULL, E_WARNING, "Could not fetch buffer");
1639 RETURN_FALSE;
1640 }
1641 if (options & LIBXML_SAVE_NOEMPTYTAG) {
1642 saveempty = xmlSaveNoEmptyTags;
1643 xmlSaveNoEmptyTags = 1;
1644 }
1645 xmlNodeDump(buf, docp, node, 0, format);
1646 if (options & LIBXML_SAVE_NOEMPTYTAG) {
1647 xmlSaveNoEmptyTags = saveempty;
1648 }
1649 mem = (xmlChar*) xmlBufferContent(buf);
1650 if (!mem) {
1651 xmlBufferFree(buf);
1652 RETURN_FALSE;
1653 }
1654 RETVAL_STRING((char *) mem);
1655 xmlBufferFree(buf);
1656 } else {
1657 if (options & LIBXML_SAVE_NOEMPTYTAG) {
1658 saveempty = xmlSaveNoEmptyTags;
1659 xmlSaveNoEmptyTags = 1;
1660 }
1661 /* Encoding is handled from the encoding property set on the document */
1662 xmlDocDumpFormatMemory(docp, &mem, &size, format);
1663 if (options & LIBXML_SAVE_NOEMPTYTAG) {
1664 xmlSaveNoEmptyTags = saveempty;
1665 }
1666 if (!size || !mem) {
1667 RETURN_FALSE;
1668 }
1669 RETVAL_STRINGL((char *) mem, size);
1670 xmlFree(mem);
1671 }
1672 }
1673 /* }}} end dom_document_savexml */
1674
php_dom_free_xinclude_node(xmlNodePtr cur)1675 static xmlNodePtr php_dom_free_xinclude_node(xmlNodePtr cur) /* {{{ */
1676 {
1677 xmlNodePtr xincnode;
1678
1679 xincnode = cur;
1680 cur = cur->next;
1681 xmlUnlinkNode(xincnode);
1682 php_libxml_node_free_resource(xincnode);
1683
1684 return cur;
1685 }
1686 /* }}} */
1687
php_dom_remove_xinclude_nodes(xmlNodePtr cur)1688 static void php_dom_remove_xinclude_nodes(xmlNodePtr cur) /* {{{ */
1689 {
1690 while(cur) {
1691 if (cur->type == XML_XINCLUDE_START) {
1692 cur = php_dom_free_xinclude_node(cur);
1693
1694 /* XML_XINCLUDE_END node will be a sibling of XML_XINCLUDE_START */
1695 while(cur && cur->type != XML_XINCLUDE_END) {
1696 /* remove xinclude processing nodes from recursive xincludes */
1697 if (cur->type == XML_ELEMENT_NODE) {
1698 php_dom_remove_xinclude_nodes(cur->children);
1699 }
1700 cur = cur->next;
1701 }
1702
1703 if (cur && cur->type == XML_XINCLUDE_END) {
1704 cur = php_dom_free_xinclude_node(cur);
1705 }
1706 } else {
1707 if (cur->type == XML_ELEMENT_NODE) {
1708 php_dom_remove_xinclude_nodes(cur->children);
1709 }
1710 cur = cur->next;
1711 }
1712 }
1713 }
1714 /* }}} */
1715
1716 /* {{{ proto int dom_document_xinclude([int options])
1717 Substitutues xincludes in a DomDocument */
PHP_FUNCTION(dom_document_xinclude)1718 PHP_FUNCTION(dom_document_xinclude)
1719 {
1720 zval *id;
1721 xmlDoc *docp;
1722 xmlNodePtr root;
1723 zend_long flags = 0;
1724 int err;
1725 dom_object *intern;
1726
1727 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O|l", &id, dom_document_class_entry, &flags) == FAILURE) {
1728 return;
1729 }
1730
1731 if (ZEND_LONG_EXCEEDS_INT(flags)) {
1732 php_error_docref(NULL, E_WARNING, "Invalid flags");
1733 RETURN_FALSE;
1734 }
1735
1736 DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
1737
1738 err = xmlXIncludeProcessFlags(docp, (int)flags);
1739
1740 /* XML_XINCLUDE_START and XML_XINCLUDE_END nodes need to be removed as these
1741 are added via xmlXIncludeProcess to mark beginning and ending of xincluded document
1742 but are not wanted in resulting document - must be done even if err as it could fail after
1743 having processed some xincludes */
1744 root = (xmlNodePtr) docp->children;
1745 while(root && root->type != XML_ELEMENT_NODE && root->type != XML_XINCLUDE_START) {
1746 root = root->next;
1747 }
1748 if (root) {
1749 php_dom_remove_xinclude_nodes(root);
1750 }
1751
1752 if (err) {
1753 RETVAL_LONG(err);
1754 } else {
1755 RETVAL_FALSE;
1756 }
1757
1758 }
1759 /* }}} */
1760
1761 /* {{{ proto boolean dom_document_validate()
1762 Since: DOM extended
1763 */
PHP_FUNCTION(dom_document_validate)1764 PHP_FUNCTION(dom_document_validate)
1765 {
1766 zval *id;
1767 xmlDoc *docp;
1768 dom_object *intern;
1769 xmlValidCtxt *cvp;
1770
1771 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &id, dom_document_class_entry) == FAILURE) {
1772 return;
1773 }
1774
1775 DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
1776
1777 cvp = xmlNewValidCtxt();
1778
1779 cvp->userData = NULL;
1780 cvp->error = (xmlValidityErrorFunc) php_libxml_error_handler;
1781 cvp->warning = (xmlValidityErrorFunc) php_libxml_error_handler;
1782
1783 if (xmlValidateDocument(cvp, docp)) {
1784 RETVAL_TRUE;
1785 } else {
1786 RETVAL_FALSE;
1787 }
1788
1789 xmlFreeValidCtxt(cvp);
1790
1791 }
1792 /* }}} */
1793
1794 #if defined(LIBXML_SCHEMAS_ENABLED)
_dom_document_schema_validate(INTERNAL_FUNCTION_PARAMETERS,int type)1795 static void _dom_document_schema_validate(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */
1796 {
1797 zval *id;
1798 xmlDoc *docp;
1799 dom_object *intern;
1800 char *source = NULL, *valid_file = NULL;
1801 size_t source_len = 0;
1802 int valid_opts = 0;
1803 zend_long flags = 0;
1804 xmlSchemaParserCtxtPtr parser;
1805 xmlSchemaPtr sptr;
1806 xmlSchemaValidCtxtPtr vptr;
1807 int is_valid;
1808 char resolved_path[MAXPATHLEN + 1];
1809
1810 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os|l", &id, dom_document_class_entry, &source, &source_len, &flags) == FAILURE) {
1811 return;
1812 }
1813
1814 if (source_len == 0) {
1815 php_error_docref(NULL, E_WARNING, "Invalid Schema source");
1816 RETURN_FALSE;
1817 }
1818
1819 DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
1820
1821 switch (type) {
1822 case DOM_LOAD_FILE:
1823 if (CHECK_NULL_PATH(source, source_len)) {
1824 php_error_docref(NULL, E_WARNING, "Invalid Schema file source");
1825 RETURN_FALSE;
1826 }
1827 valid_file = _dom_get_valid_file_path(source, resolved_path, MAXPATHLEN);
1828 if (!valid_file) {
1829 php_error_docref(NULL, E_WARNING, "Invalid Schema file source");
1830 RETURN_FALSE;
1831 }
1832 parser = xmlSchemaNewParserCtxt(valid_file);
1833 break;
1834 case DOM_LOAD_STRING:
1835 parser = xmlSchemaNewMemParserCtxt(source, source_len);
1836 /* If loading from memory, we need to set the base directory for the document
1837 but it is not apparent how to do that for schema's */
1838 break;
1839 default:
1840 return;
1841 }
1842
1843 xmlSchemaSetParserErrors(parser,
1844 (xmlSchemaValidityErrorFunc) php_libxml_error_handler,
1845 (xmlSchemaValidityWarningFunc) php_libxml_error_handler,
1846 parser);
1847 sptr = xmlSchemaParse(parser);
1848 xmlSchemaFreeParserCtxt(parser);
1849 if (!sptr) {
1850 php_error_docref(NULL, E_WARNING, "Invalid Schema");
1851 RETURN_FALSE;
1852 }
1853
1854 docp = (xmlDocPtr) dom_object_get_node(intern);
1855
1856 vptr = xmlSchemaNewValidCtxt(sptr);
1857 if (!vptr) {
1858 xmlSchemaFree(sptr);
1859 zend_throw_error(NULL, "Invalid Schema Validation Context");
1860 RETURN_FALSE;
1861 }
1862
1863 #if LIBXML_VERSION >= 20614
1864 if (flags & XML_SCHEMA_VAL_VC_I_CREATE) {
1865 valid_opts |= XML_SCHEMA_VAL_VC_I_CREATE;
1866 }
1867 #endif
1868
1869 xmlSchemaSetValidOptions(vptr, valid_opts);
1870 xmlSchemaSetValidErrors(vptr, php_libxml_error_handler, php_libxml_error_handler, vptr);
1871 is_valid = xmlSchemaValidateDoc(vptr, docp);
1872 xmlSchemaFree(sptr);
1873 xmlSchemaFreeValidCtxt(vptr);
1874
1875 if (is_valid == 0) {
1876 RETURN_TRUE;
1877 } else {
1878 RETURN_FALSE;
1879 }
1880 }
1881 /* }}} */
1882
1883 /* {{{ proto boolean dom_document_schema_validate_file(string filename, int flags); */
PHP_FUNCTION(dom_document_schema_validate_file)1884 PHP_FUNCTION(dom_document_schema_validate_file)
1885 {
1886 _dom_document_schema_validate(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_FILE);
1887 }
1888 /* }}} end dom_document_schema_validate_file */
1889
1890 /* {{{ proto boolean dom_document_schema_validate(string source, int flags); */
PHP_FUNCTION(dom_document_schema_validate_xml)1891 PHP_FUNCTION(dom_document_schema_validate_xml)
1892 {
1893 _dom_document_schema_validate(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_STRING);
1894 }
1895 /* }}} end dom_document_schema_validate */
1896
_dom_document_relaxNG_validate(INTERNAL_FUNCTION_PARAMETERS,int type)1897 static void _dom_document_relaxNG_validate(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */
1898 {
1899 zval *id;
1900 xmlDoc *docp;
1901 dom_object *intern;
1902 char *source = NULL, *valid_file = NULL;
1903 size_t source_len = 0;
1904 xmlRelaxNGParserCtxtPtr parser;
1905 xmlRelaxNGPtr sptr;
1906 xmlRelaxNGValidCtxtPtr vptr;
1907 int is_valid;
1908 char resolved_path[MAXPATHLEN + 1];
1909
1910 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os", &id, dom_document_class_entry, &source, &source_len) == FAILURE) {
1911 return;
1912 }
1913
1914 if (source_len == 0) {
1915 php_error_docref(NULL, E_WARNING, "Invalid Schema source");
1916 RETURN_FALSE;
1917 }
1918
1919 DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
1920
1921 switch (type) {
1922 case DOM_LOAD_FILE:
1923 if (CHECK_NULL_PATH(source, source_len)) {
1924 php_error_docref(NULL, E_WARNING, "Invalid RelaxNG file source");
1925 RETURN_FALSE;
1926 }
1927 valid_file = _dom_get_valid_file_path(source, resolved_path, MAXPATHLEN);
1928 if (!valid_file) {
1929 php_error_docref(NULL, E_WARNING, "Invalid RelaxNG file source");
1930 RETURN_FALSE;
1931 }
1932 parser = xmlRelaxNGNewParserCtxt(valid_file);
1933 break;
1934 case DOM_LOAD_STRING:
1935 parser = xmlRelaxNGNewMemParserCtxt(source, source_len);
1936 /* If loading from memory, we need to set the base directory for the document
1937 but it is not apparent how to do that for schema's */
1938 break;
1939 default:
1940 return;
1941 }
1942
1943 xmlRelaxNGSetParserErrors(parser,
1944 (xmlRelaxNGValidityErrorFunc) php_libxml_error_handler,
1945 (xmlRelaxNGValidityWarningFunc) php_libxml_error_handler,
1946 parser);
1947 sptr = xmlRelaxNGParse(parser);
1948 xmlRelaxNGFreeParserCtxt(parser);
1949 if (!sptr) {
1950 php_error_docref(NULL, E_WARNING, "Invalid RelaxNG");
1951 RETURN_FALSE;
1952 }
1953
1954 docp = (xmlDocPtr) dom_object_get_node(intern);
1955
1956 vptr = xmlRelaxNGNewValidCtxt(sptr);
1957 if (!vptr) {
1958 xmlRelaxNGFree(sptr);
1959 zend_throw_error(NULL, "Invalid RelaxNG Validation Context");
1960 RETURN_FALSE;
1961 }
1962
1963 xmlRelaxNGSetValidErrors(vptr, php_libxml_error_handler, php_libxml_error_handler, vptr);
1964 is_valid = xmlRelaxNGValidateDoc(vptr, docp);
1965 xmlRelaxNGFree(sptr);
1966 xmlRelaxNGFreeValidCtxt(vptr);
1967
1968 if (is_valid == 0) {
1969 RETURN_TRUE;
1970 } else {
1971 RETURN_FALSE;
1972 }
1973 }
1974 /* }}} */
1975
1976 /* {{{ proto boolean dom_document_relaxNG_validate_file(string filename); */
PHP_FUNCTION(dom_document_relaxNG_validate_file)1977 PHP_FUNCTION(dom_document_relaxNG_validate_file)
1978 {
1979 _dom_document_relaxNG_validate(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_FILE);
1980 }
1981 /* }}} end dom_document_relaxNG_validate_file */
1982
1983 /* {{{ proto boolean dom_document_relaxNG_validate_xml(string source); */
PHP_FUNCTION(dom_document_relaxNG_validate_xml)1984 PHP_FUNCTION(dom_document_relaxNG_validate_xml)
1985 {
1986 _dom_document_relaxNG_validate(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_STRING);
1987 }
1988 /* }}} end dom_document_relaxNG_validate_xml */
1989
1990 #endif
1991
1992 #if defined(LIBXML_HTML_ENABLED)
1993
dom_load_html(INTERNAL_FUNCTION_PARAMETERS,int mode)1994 static void dom_load_html(INTERNAL_FUNCTION_PARAMETERS, int mode) /* {{{ */
1995 {
1996 zval *id;
1997 xmlDoc *docp = NULL, *newdoc;
1998 dom_object *intern;
1999 dom_doc_propsptr doc_prop;
2000 char *source;
2001 size_t source_len;
2002 int refcount, ret;
2003 zend_long options = 0;
2004 htmlParserCtxtPtr ctxt;
2005
2006 id = getThis();
2007
2008 if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|l", &source, &source_len, &options) == FAILURE) {
2009 return;
2010 }
2011
2012 if (!source_len) {
2013 php_error_docref(NULL, E_WARNING, "Empty string supplied as input");
2014 RETURN_FALSE;
2015 }
2016
2017 if (ZEND_LONG_EXCEEDS_INT(options)) {
2018 php_error_docref(NULL, E_WARNING, "Invalid options");
2019 RETURN_FALSE;
2020 }
2021
2022 if (mode == DOM_LOAD_FILE) {
2023 if (CHECK_NULL_PATH(source, source_len)) {
2024 php_error_docref(NULL, E_WARNING, "Invalid file source");
2025 RETURN_FALSE;
2026 }
2027 ctxt = htmlCreateFileParserCtxt(source, NULL);
2028 } else {
2029 source_len = xmlStrlen((xmlChar *) source);
2030 if (ZEND_SIZE_T_INT_OVFL(source_len)) {
2031 php_error_docref(NULL, E_WARNING, "Input string is too long");
2032 RETURN_FALSE;
2033 }
2034 ctxt = htmlCreateMemoryParserCtxt(source, (int)source_len);
2035 }
2036
2037 if (!ctxt) {
2038 RETURN_FALSE;
2039 }
2040
2041
2042 ctxt->vctxt.error = php_libxml_ctx_error;
2043 ctxt->vctxt.warning = php_libxml_ctx_warning;
2044 if (ctxt->sax != NULL) {
2045 ctxt->sax->error = php_libxml_ctx_error;
2046 ctxt->sax->warning = php_libxml_ctx_warning;
2047 }
2048 if (options) {
2049 htmlCtxtUseOptions(ctxt, (int)options);
2050 }
2051 htmlParseDocument(ctxt);
2052 newdoc = ctxt->myDoc;
2053 htmlFreeParserCtxt(ctxt);
2054
2055 if (!newdoc)
2056 RETURN_FALSE;
2057
2058 if (id != NULL && instanceof_function(Z_OBJCE_P(id), dom_document_class_entry)) {
2059 intern = Z_DOMOBJ_P(id);
2060 if (intern != NULL) {
2061 docp = (xmlDocPtr) dom_object_get_node(intern);
2062 doc_prop = NULL;
2063 if (docp != NULL) {
2064 php_libxml_decrement_node_ptr((php_libxml_node_object *) intern);
2065 doc_prop = intern->document->doc_props;
2066 intern->document->doc_props = NULL;
2067 refcount = php_libxml_decrement_doc_ref((php_libxml_node_object *)intern);
2068 if (refcount != 0) {
2069 docp->_private = NULL;
2070 }
2071 }
2072 intern->document = NULL;
2073 if (php_libxml_increment_doc_ref((php_libxml_node_object *)intern, newdoc) == -1) {
2074 RETURN_FALSE;
2075 }
2076 intern->document->doc_props = doc_prop;
2077 }
2078
2079 php_libxml_increment_node_ptr((php_libxml_node_object *)intern, (xmlNodePtr)newdoc, (void *)intern);
2080
2081 RETURN_TRUE;
2082 } else {
2083 DOM_RET_OBJ((xmlNodePtr) newdoc, &ret, NULL);
2084 }
2085 }
2086 /* }}} */
2087
2088 /* {{{ proto DOMNode dom_document_load_html_file(string source)
2089 Since: DOM extended
2090 */
PHP_METHOD(domdocument,loadHTMLFile)2091 PHP_METHOD(domdocument, loadHTMLFile)
2092 {
2093 dom_load_html(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_FILE);
2094 }
2095 /* }}} end dom_document_load_html_file */
2096
2097 /* {{{ proto DOMNode dom_document_load_html(string source)
2098 Since: DOM extended
2099 */
PHP_METHOD(domdocument,loadHTML)2100 PHP_METHOD(domdocument, loadHTML)
2101 {
2102 dom_load_html(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_STRING);
2103 }
2104 /* }}} end dom_document_load_html */
2105
2106 /* {{{ proto int dom_document_save_html_file(string file)
2107 Convenience method to save to file as html
2108 */
PHP_FUNCTION(dom_document_save_html_file)2109 PHP_FUNCTION(dom_document_save_html_file)
2110 {
2111 zval *id;
2112 xmlDoc *docp;
2113 size_t file_len;
2114 int bytes, format;
2115 dom_object *intern;
2116 dom_doc_propsptr doc_props;
2117 char *file;
2118 const char *encoding;
2119
2120 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Op", &id, dom_document_class_entry, &file, &file_len) == FAILURE) {
2121 return;
2122 }
2123
2124 if (file_len == 0) {
2125 php_error_docref(NULL, E_WARNING, "Invalid Filename");
2126 RETURN_FALSE;
2127 }
2128
2129 DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
2130
2131
2132 encoding = (const char *) htmlGetMetaEncoding(docp);
2133
2134 doc_props = dom_get_doc_props(intern->document);
2135 format = doc_props->formatoutput;
2136 bytes = htmlSaveFileFormat(file, docp, encoding, format);
2137
2138 if (bytes == -1) {
2139 RETURN_FALSE;
2140 }
2141 RETURN_LONG(bytes);
2142 }
2143 /* }}} end dom_document_save_html_file */
2144
2145 /* {{{ proto string dom_document_save_html()
2146 Convenience method to output as html
2147 */
PHP_FUNCTION(dom_document_save_html)2148 PHP_FUNCTION(dom_document_save_html)
2149 {
2150 zval *id, *nodep = NULL;
2151 xmlDoc *docp;
2152 xmlNode *node;
2153 xmlBufferPtr buf;
2154 dom_object *intern, *nodeobj;
2155 xmlChar *mem = NULL;
2156 int size = 0, format;
2157 dom_doc_propsptr doc_props;
2158
2159 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(),
2160 "O|O!", &id, dom_document_class_entry, &nodep, dom_node_class_entry)
2161 == FAILURE) {
2162 return;
2163 }
2164
2165 DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
2166
2167 doc_props = dom_get_doc_props(intern->document);
2168 format = doc_props->formatoutput;
2169
2170 if (nodep != NULL) {
2171 /* Dump contents of Node */
2172 DOM_GET_OBJ(node, nodep, xmlNodePtr, nodeobj);
2173 if (node->doc != docp) {
2174 php_dom_throw_error(WRONG_DOCUMENT_ERR, dom_get_strict_error(intern->document));
2175 RETURN_FALSE;
2176 }
2177
2178 buf = xmlBufferCreate();
2179 if (!buf) {
2180 php_error_docref(NULL, E_WARNING, "Could not fetch buffer");
2181 RETURN_FALSE;
2182 }
2183
2184 if (node->type == XML_DOCUMENT_FRAG_NODE) {
2185 int one_size;
2186
2187 for (node = node->children; node; node = node->next) {
2188 one_size = htmlNodeDump(buf, docp, node);
2189
2190 if (one_size >= 0) {
2191 size += one_size;
2192 } else {
2193 size = -1;
2194 break;
2195 }
2196 }
2197 } else {
2198 size = htmlNodeDump(buf, docp, node);
2199 }
2200 if (size >= 0) {
2201 mem = (xmlChar*) xmlBufferContent(buf);
2202 if (!mem) {
2203 RETVAL_FALSE;
2204 } else {
2205 RETVAL_STRINGL((const char*) mem, size);
2206 }
2207 } else {
2208 php_error_docref(NULL, E_WARNING, "Error dumping HTML node");
2209 RETVAL_FALSE;
2210 }
2211 xmlBufferFree(buf);
2212 } else {
2213 #if LIBXML_VERSION >= 20623
2214 htmlDocDumpMemoryFormat(docp, &mem, &size, format);
2215 #else
2216 htmlDocDumpMemory(docp, &mem, &size);
2217 #endif
2218 if (!size || !mem) {
2219 RETVAL_FALSE;
2220 } else {
2221 RETVAL_STRINGL((const char*) mem, size);
2222 }
2223 if (mem)
2224 xmlFree(mem);
2225 }
2226
2227 }
2228 /* }}} end dom_document_save_html */
2229
2230 #endif /* defined(LIBXML_HTML_ENABLED) */
2231
2232 /* {{{ proto boolean DOMDocument::registerNodeClass(string baseclass, string extendedclass)
2233 Register extended class used to create base node type */
PHP_METHOD(domdocument,registerNodeClass)2234 PHP_METHOD(domdocument, registerNodeClass)
2235 {
2236 zval *id;
2237 xmlDoc *docp;
2238 zend_class_entry *basece = dom_node_class_entry, *ce = NULL;
2239 dom_object *intern;
2240
2241 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "OCC!", &id, dom_document_class_entry, &basece, &ce) == FAILURE) {
2242 return;
2243 }
2244
2245 if (ce == NULL || instanceof_function(ce, basece)) {
2246 DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
2247 dom_set_doc_classmap(intern->document, basece, ce);
2248 RETURN_TRUE;
2249 }
2250
2251 zend_throw_error(NULL, "Class %s is not derived from %s.", ZSTR_VAL(ce->name), ZSTR_VAL(basece->name));
2252 RETURN_FALSE;
2253 }
2254 /* }}} */
2255
2256 #endif /* HAVE_LIBXML && HAVE_DOM */
2257
2258 /*
2259 * Local variables:
2260 * tab-width: 4
2261 * c-basic-offset: 4
2262 * End:
2263 * vim600: noet sw=4 ts=4 fdm=marker
2264 * vim<600: noet sw=4 ts=4
2265 */
2266