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