root/ext/dom/document.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. dom_document_doctype_read
  2. dom_document_implementation_read
  3. dom_document_document_element_read
  4. dom_document_encoding_read
  5. dom_document_encoding_write
  6. dom_document_standalone_read
  7. dom_document_standalone_write
  8. dom_document_version_read
  9. dom_document_version_write
  10. dom_document_strict_error_checking_read
  11. dom_document_strict_error_checking_write
  12. dom_document_format_output_read
  13. dom_document_format_output_write
  14. dom_document_validate_on_parse_read
  15. dom_document_validate_on_parse_write
  16. dom_document_resolve_externals_read
  17. dom_document_resolve_externals_write
  18. dom_document_preserve_whitespace_read
  19. dom_document_preserve_whitespace_write
  20. dom_document_recover_read
  21. dom_document_recover_write
  22. dom_document_substitue_entities_read
  23. dom_document_substitue_entities_write
  24. dom_document_document_uri_read
  25. dom_document_document_uri_write
  26. dom_document_config_read
  27. PHP_FUNCTION
  28. PHP_FUNCTION
  29. PHP_FUNCTION
  30. PHP_FUNCTION
  31. PHP_FUNCTION
  32. PHP_FUNCTION
  33. PHP_FUNCTION
  34. PHP_FUNCTION
  35. PHP_FUNCTION
  36. PHP_FUNCTION
  37. PHP_FUNCTION
  38. PHP_FUNCTION
  39. PHP_FUNCTION
  40. PHP_FUNCTION
  41. PHP_FUNCTION
  42. PHP_FUNCTION
  43. PHP_FUNCTION
  44. PHP_METHOD
  45. _dom_get_valid_file_path
  46. dom_document_parser
  47. dom_parse_document
  48. PHP_METHOD
  49. PHP_METHOD
  50. PHP_FUNCTION
  51. PHP_FUNCTION
  52. php_dom_free_xinclude_node
  53. php_dom_remove_xinclude_nodes
  54. PHP_FUNCTION
  55. PHP_FUNCTION
  56. _dom_document_schema_validate
  57. PHP_FUNCTION
  58. PHP_FUNCTION
  59. _dom_document_relaxNG_validate
  60. PHP_FUNCTION
  61. PHP_FUNCTION
  62. dom_load_html
  63. PHP_METHOD
  64. PHP_METHOD
  65. PHP_FUNCTION
  66. PHP_FUNCTION
  67. PHP_METHOD

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

/* [<][>][^][v][top][bottom][index][help] */