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