From 206e50fc609bde8f77bd5ba7593094dfb4af1964 Mon Sep 17 00:00:00 2001
From: Rob Richards <rrichards@php.net>
Date: Fri, 3 Mar 2006 20:13:12 +0000
Subject: [PATCH] update dom iterator get key function for engine iterator
 changes fix crashes using notations and entity decls add test

---
 ext/dom/dom_iterators.c   | 20 +++++---
 ext/dom/namednodemap.c    | 54 +++++++++++++--------
 ext/dom/notation.c        | 14 +++---
 ext/dom/tests/dom007.phpt | 99 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 155 insertions(+), 32 deletions(-)
 create mode 100644 ext/dom/tests/dom007.phpt

diff --git a/ext/dom/dom_iterators.c b/ext/dom/dom_iterators.c
index eae3e9ca18..c06e612d87 100644
--- a/ext/dom/dom_iterators.c
+++ b/ext/dom/dom_iterators.c
@@ -162,7 +162,7 @@ static int php_dom_iterator_current_key(zend_object_iterator *iter, zstr *str_ke
 	object = (zval *)iterator->intern.data;
 
 	if (instanceof_function(Z_OBJCE_P(object), dom_nodelist_class_entry TSRMLS_CC)) {
-		*int_key = iter->index - 1;
+		*int_key = iter->index;
 		return HASH_KEY_IS_LONG;
 	} else {
 		curobj = iterator->curobj;
@@ -200,7 +200,8 @@ static void php_dom_iterator_move_forward(zend_object_iterator *iter TSRMLS_DC)
 	curobj = iterator->curobj;
 	intern = (dom_object *)zend_object_store_get_object(curobj TSRMLS_CC);
 	if (intern != NULL && intern->ptr != NULL) {
-		if (objmap->ht == NULL) {
+		if (objmap->nodetype != XML_ENTITY_NODE && 
+			objmap->nodetype != XML_NOTATION_NODE) {
 			if (objmap->nodetype == DOM_NODESET) {
 				nodeht = HASH_OF(objmap->baseobjptr);
 				zend_hash_move_forward(nodeht);
@@ -210,12 +211,14 @@ static void php_dom_iterator_move_forward(zend_object_iterator *iter TSRMLS_DC)
 				}
 			} else {
 				curnode = (xmlNodePtr)((php_libxml_node_ptr *)intern->ptr)->node;
-				if (objmap->nodetype == XML_ATTRIBUTE_NODE || objmap->nodetype == XML_ELEMENT_NODE) {
+				if (objmap->nodetype == XML_ATTRIBUTE_NODE || 
+					objmap->nodetype == XML_ELEMENT_NODE) {
 					curnode = curnode->next;
 				} else {
 					/* Nav the tree evey time as this is LIVE */
 					basenode = dom_object_get_node(objmap->baseobj);
-					if (basenode && (basenode->type == XML_DOCUMENT_NODE || basenode->type == XML_HTML_DOCUMENT_NODE)) {
+					if (basenode && (basenode->type == XML_DOCUMENT_NODE || 
+						basenode->type == XML_HTML_DOCUMENT_NODE)) {
 						basenode = xmlDocGetRootElement((xmlDoc *) basenode);
 					} else {
 						basenode = basenode->children;
@@ -274,7 +277,8 @@ zend_object_iterator *php_dom_get_iterator(zend_class_entry *ce, zval *object, i
 	intern = (dom_object *)zend_object_store_get_object(object TSRMLS_CC);
 	objmap = (dom_nnodemap_object *)intern->ptr;
 	if (objmap != NULL) {
-		if (objmap->ht == NULL) {
+		if (objmap->nodetype != XML_ENTITY_NODE && 
+			objmap->nodetype != XML_NOTATION_NODE) {
 			if (objmap->nodetype == DOM_NODESET) {
 				nodeht = HASH_OF(objmap->baseobjptr);
 				zend_hash_internal_pointer_reset(nodeht);
@@ -300,7 +304,11 @@ zend_object_iterator *php_dom_get_iterator(zend_class_entry *ce, zval *object, i
 				}
 			}
 		} else {
-			curnode = php_dom_libxml_hash_iter(objmap->ht, 0);
+			if (objmap->nodetype == XML_ENTITY_NODE) {
+				curnode = php_dom_libxml_hash_iter(objmap->ht, 0);
+			} else {
+				curnode = php_dom_libxml_notation_iter(objmap->ht, 0);
+			}
 		}
 	}
 
diff --git a/ext/dom/namednodemap.c b/ext/dom/namednodemap.c
index 53707d02fb..1f7b80204f 100644
--- a/ext/dom/namednodemap.c
+++ b/ext/dom/namednodemap.c
@@ -61,8 +61,11 @@ int dom_namednodemap_length_read(dom_object *obj, zval **retval TSRMLS_DC)
 	objmap = (dom_nnodemap_object *)obj->ptr;
 
 	if (objmap != NULL) {
-		if (objmap->ht) {
-			count = xmlHashSize(objmap->ht);
+		if ((objmap->nodetype == XML_NOTATION_NODE) || 
+			objmap->nodetype == XML_ENTITY_NODE) {
+			if (objmap->ht) {
+				count = xmlHashSize(objmap->ht);
+			}
 		} else {
 			nodep = dom_object_get_node(objmap->baseobj);
 			if (nodep) {
@@ -113,12 +116,17 @@ PHP_FUNCTION(dom_namednodemap_get_named_item)
 	objmap = (dom_nnodemap_object *)intern->ptr;
 
 	if (objmap != NULL) {
-		if (objmap->ht) {
-			if (objmap->nodetype == XML_ENTITY_NODE) {
-				itemnode = (xmlNodePtr)xmlHashLookup(objmap->ht, named);
-			} else {
-				notep = (xmlNotation *)xmlHashLookup(objmap->ht, named);
-				itemnode = create_notation(notep->name, notep->PublicID, notep->SystemID);
+		if ((objmap->nodetype == XML_NOTATION_NODE) || 
+			objmap->nodetype == XML_ENTITY_NODE) {
+			if (objmap->ht) {
+				if (objmap->nodetype == XML_ENTITY_NODE) {
+					itemnode = (xmlNodePtr)xmlHashLookup(objmap->ht, named);
+				} else {
+					notep = (xmlNotation *)xmlHashLookup(objmap->ht, named);
+					if (notep) {
+						itemnode = create_notation(notep->name, notep->PublicID, notep->SystemID);
+					}
+				}
 			}
 		} else {
 			nodep = dom_object_get_node(objmap->baseobj);
@@ -185,11 +193,14 @@ PHP_FUNCTION(dom_namednodemap_item)
 		objmap = (dom_nnodemap_object *)intern->ptr;
 
 		if (objmap != NULL) {
-			if (objmap->ht) {
-				if (objmap->nodetype == XML_ENTITY_NODE) {
-					itemnode = php_dom_libxml_hash_iter(objmap->ht, index);
-				} else {
-					itemnode = php_dom_libxml_notation_iter(objmap->ht, index);
+			if ((objmap->nodetype == XML_NOTATION_NODE) || 
+				objmap->nodetype == XML_ENTITY_NODE) {
+				if (objmap->ht) {
+					if (objmap->nodetype == XML_ENTITY_NODE) {
+						itemnode = php_dom_libxml_hash_iter(objmap->ht, index);
+					} else {
+						itemnode = php_dom_libxml_notation_iter(objmap->ht, index);
+					}
 				}
 			} else {
 				nodep = dom_object_get_node(objmap->baseobj);
@@ -241,12 +252,17 @@ PHP_FUNCTION(dom_namednodemap_get_named_item_ns)
 	objmap = (dom_nnodemap_object *)intern->ptr;
 
 	if (objmap != NULL) {
-		if (objmap->ht) {
-			if (objmap->nodetype == XML_ENTITY_NODE) {
-				itemnode = (xmlNodePtr)xmlHashLookup(objmap->ht, named);
-			} else {
-				notep = (xmlNotation *)xmlHashLookup(objmap->ht, named);
-				itemnode = create_notation(notep->name, notep->PublicID, notep->SystemID);
+		if ((objmap->nodetype == XML_NOTATION_NODE) || 
+			objmap->nodetype == XML_ENTITY_NODE) {
+			if (objmap->ht) {
+				if (objmap->nodetype == XML_ENTITY_NODE) {
+					itemnode = (xmlNodePtr)xmlHashLookup(objmap->ht, named);
+				} else {
+					notep = (xmlNotation *)xmlHashLookup(objmap->ht, named);
+					if (notep) {
+						itemnode = create_notation(notep->name, notep->PublicID, notep->SystemID);
+					}
+				}
 			}
 		} else {
 			nodep = dom_object_get_node(objmap->baseobj);
diff --git a/ext/dom/notation.c b/ext/dom/notation.c
index 2a085e7639..ed1e73c032 100644
--- a/ext/dom/notation.c
+++ b/ext/dom/notation.c
@@ -48,9 +48,9 @@ Since:
 */
 int dom_notation_public_id_read(dom_object *obj, zval **retval TSRMLS_DC)
 {
-	xmlNotationPtr nodep;
+	xmlEntityPtr nodep;
 
-	nodep = (xmlNotationPtr) dom_object_get_node(obj);
+	nodep = (xmlEntityPtr) dom_object_get_node(obj);
 
 	if (nodep == NULL) {
 		php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
@@ -58,8 +58,8 @@ int dom_notation_public_id_read(dom_object *obj, zval **retval TSRMLS_DC)
 	}
 
 	ALLOC_ZVAL(*retval);
-	if (nodep->PublicID) {
-		ZVAL_STRING(*retval, (char *) (nodep->PublicID), 1);
+	if (nodep->ExternalID) {
+		ZVAL_STRING(*retval, (char *) (nodep->ExternalID), 1);
 	} else {
 		ZVAL_EMPTY_STRING(*retval);
 	}
@@ -78,9 +78,9 @@ Since:
 */
 int dom_notation_system_id_read(dom_object *obj, zval **retval TSRMLS_DC)
 {
-	xmlNotationPtr nodep;
+	xmlEntityPtr nodep;
 
-	nodep = (xmlNotationPtr) dom_object_get_node(obj);
+	nodep = (xmlEntityPtr) dom_object_get_node(obj);
 
 	if (nodep == NULL) {
 		php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
@@ -89,7 +89,7 @@ int dom_notation_system_id_read(dom_object *obj, zval **retval TSRMLS_DC)
 
 	ALLOC_ZVAL(*retval);
 	if (nodep->SystemID) {
-		ZVAL_STRING(*retval, (char *) (nodep->PublicID), 1);
+		ZVAL_STRING(*retval, (char *) (nodep->SystemID), 1);
 	} else {
 		ZVAL_EMPTY_STRING(*retval);
 	}
diff --git a/ext/dom/tests/dom007.phpt b/ext/dom/tests/dom007.phpt
new file mode 100644
index 0000000000..649d630336
--- /dev/null
+++ b/ext/dom/tests/dom007.phpt
@@ -0,0 +1,99 @@
+--TEST--
+Test 7: DTD tests
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+?>
+--FILE--
+<?php
+$xml = <<< EOXML
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE courses [
+<!ELEMENT courses (course+)>
+<!ELEMENT course (title, description, temp*)>
+<!ATTLIST course cid ID #REQUIRED>
+<!ELEMENT title (#PCDATA)>
+<!ELEMENT description (#PCDATA)>
+<!ELEMENT temp (#PCDATA)>
+<!ATTLIST temp vid ID #REQUIRED>
+<!ENTITY test 'http://www.hpl.hp.com/semweb/2003/query_tester#'>
+<!ENTITY rdf  'http://www.w3.org/1999/02/22-rdf-syntax-ns#'>
+<!NOTATION GIF PUBLIC "-" "image/gif">
+<!ENTITY myimage PUBLIC "-" "mypicture.gif" NDATA GIF>
+]>
+<courses>
+   <course cid="c1">
+      <title>Basic Languages</title>
+      <description>Introduction to Languages</description>
+   </course>
+   <course cid="c6">
+      <title>French I</title>
+      <description>Introduction to French</description>
+      <temp vid="c7">
+      </temp>
+   </course>
+</courses>
+EOXML;
+
+$dom = new DOMDocument();
+$dom->loadXML($xml);
+
+$dtd = $dom->doctype;
+
+/* Notation Tests */
+$nots = $dtd->notations;
+
+$length = $nots->length;
+echo "Length: ".$length."\n";
+
+foreach ($nots AS $key=>$node) {
+	echo "Key $key: ".$node->nodeName." (".$node->systemId.") (".$node->publicId.")\n";
+}
+print "\n";
+for($x=0; $x < $length; $x++) {
+	echo "Index $x: ".$nots->item($x)->nodeName." (".$nots->item($x)->systemId.") (".$nots->item($x)->publicId.")\n";
+}
+
+echo "\n";
+$node = $nots->getNamedItem('xxx');
+var_dump($node);
+
+echo "\n";
+/* Entity Decl Tests */
+$ents = $dtd->entities;
+$length = $ents->length;
+echo "Length: ".$length."\n";
+foreach ($ents AS $key=>$node) {
+	echo "Key: $key Name: ".$node->nodeName."\n";
+}
+echo "\n";
+for($x=0; $x < $length; $x++) {
+	echo "Index $x: ".$ents->item($x)->nodeName."\n";
+}
+
+echo "\n";
+$node = $ents->item(3);
+var_dump($node);
+$node = $ents->getNamedItem('xxx');
+var_dump($node);
+
+
+--EXPECT--
+Length: 1
+Key GIF: GIF (image/gif) (-)
+
+Index 0: GIF (image/gif) (-)
+
+NULL
+
+Length: 3
+Key: test Name: test
+Key: rdf Name: rdf
+Key: myimage Name: myimage
+
+Index 0: test
+Index 1: rdf
+Index 2: myimage
+
+NULL
+NULL
-- 
2.40.0