Skip to content

Commit b5f92c2

Browse files
committed
fix Dom\Notation nodes missing tree connection
1 parent 0471420 commit b5f92c2

5 files changed

Lines changed: 74 additions & 10 deletions

File tree

ext/dom/dom_iterators.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,18 @@ static dom_nnodemap_object *php_dom_iterator_get_nnmap(const php_dom_iterator *i
5454
return nnmap->ptr;
5555
}
5656

57-
xmlNodePtr create_notation(const xmlChar *name, const xmlChar *ExternalID, const xmlChar *SystemID) /* {{{ */
57+
xmlNodePtr create_notation(xmlDtdPtr parent_dtd, const xmlChar *name, const xmlChar *ExternalID, const xmlChar *SystemID) /* {{{ */
5858
{
5959
xmlEntityPtr ret = xmlMalloc(sizeof(xmlEntity));
6060
memset(ret, 0, sizeof(xmlEntity));
6161
ret->type = XML_NOTATION_NODE;
6262
ret->name = xmlStrdup(name);
6363
ret->ExternalID = xmlStrdup(ExternalID);
6464
ret->SystemID = xmlStrdup(SystemID);
65+
if (parent_dtd != NULL) {
66+
ret->parent = (xmlNodePtr) parent_dtd;
67+
ret->doc = parent_dtd->doc;
68+
}
6569
return (xmlNodePtr) ret;
6670
}
6771
/* }}} */

ext/dom/obj_map.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,8 @@ static void dom_map_get_notation_item(dom_nnodemap_object *map, zend_long index,
176176
xmlNodePtr node = map->ht ? php_dom_libxml_hash_iter(map->ht, index) : NULL;
177177
if (node) {
178178
xmlNotation *notation = (xmlNotation *) node;
179-
node = create_notation(notation->name, notation->PublicID, notation->SystemID);
179+
xmlDtdPtr dtd = (xmlDtdPtr) dom_object_get_node(map->baseobj);
180+
node = create_notation(dtd, notation->name, notation->PublicID, notation->SystemID);
180181
}
181182
dom_ret_node_to_zobj(map, node, return_value);
182183
}
@@ -504,7 +505,8 @@ static xmlNodePtr dom_map_get_ns_named_item_notation(dom_nnodemap_object *map, c
504505
{
505506
xmlNotationPtr notation = xmlHashLookup(map->ht, BAD_CAST ZSTR_VAL(named));
506507
if (notation) {
507-
return create_notation(notation->name, notation->PublicID, notation->SystemID);
508+
xmlDtdPtr dtd = (xmlDtdPtr) dom_object_get_node(map->baseobj);
509+
return create_notation(dtd, notation->name, notation->PublicID, notation->SystemID);
508510
}
509511
return NULL;
510512
}

ext/dom/php_dom.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ int dom_hierarchy(xmlNodePtr parent, xmlNodePtr child);
125125
bool dom_has_feature(zend_string *feature, zend_string *version);
126126
bool dom_node_is_read_only(const xmlNode *node);
127127
bool dom_node_children_valid(const xmlNode *node);
128-
xmlNodePtr create_notation(const xmlChar *name, const xmlChar *ExternalID, const xmlChar *SystemID);
128+
xmlNodePtr create_notation(xmlDtdPtr parent_dtd, const xmlChar *name, const xmlChar *ExternalID, const xmlChar *SystemID);
129129
xmlNode *php_dom_libxml_hash_iter(xmlHashTable *ht, int index);
130130
zend_object_iterator *php_dom_get_iterator(zend_class_entry *ce, zval *object, int by_ref);
131131
void dom_set_doc_classmap(php_libxml_ref_obj *document, zend_class_entry *basece, zend_class_entry *ce);

ext/dom/tests/modern/xml/DTDNamedNodeMap.phpt

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ var_dump($doctype);
2121

2222
var_dump($doctype->entities["test"]);
2323
var_dump($doctype->entities["myimage"]);
24-
// TODO: isConnected returning false is a bug
2524
var_dump($doctype->notations["GIF"]);
2625

2726
?>
@@ -142,17 +141,19 @@ object(Dom\Entity)#3 (17) {
142141
["textContent"]=>
143142
NULL
144143
}
145-
object(Dom\Notation)#4 (13) {
144+
object(Dom\Notation)#4 (14) {
146145
["nodeType"]=>
147146
int(12)
148147
["nodeName"]=>
149148
string(3) "GIF"
150149
["baseURI"]=>
151-
string(11) "about:blank"
150+
string(%d) "%s"
152151
["isConnected"]=>
153-
bool(false)
152+
bool(true)
153+
["ownerDocument"]=>
154+
string(22) "(object value omitted)"
154155
["parentNode"]=>
155-
NULL
156+
string(22) "(object value omitted)"
156157
["parentElement"]=>
157158
NULL
158159
["childNodes"]=>
@@ -168,5 +169,5 @@ object(Dom\Notation)#4 (13) {
168169
["nodeValue"]=>
169170
NULL
170171
["textContent"]=>
171-
string(0) ""
172+
NULL
172173
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
--TEST--
2+
Dom\XMLDocument: Dom\Notation nodes are connected to their document and doctype
3+
--EXTENSIONS--
4+
dom
5+
--FILE--
6+
<?php
7+
$xml = <<<XML
8+
<!DOCTYPE root [
9+
<!NOTATION GIF SYSTEM "image/gif">
10+
<!NOTATION JPEG PUBLIC "-//W3C//NOTATION JPEG//EN" "image/jpeg">
11+
<!NOTATION HTML PUBLIC "-//W3C//NOTATION HTML//EN">
12+
]>
13+
<root/>
14+
XML;
15+
16+
$dom = Dom\XMLDocument::createFromString($xml);
17+
$doctype = $dom->doctype;
18+
$notations = $doctype->notations;
19+
20+
// Make notations deterministic by name, as the order of notations in the map is not guaranteed
21+
foreach (['GIF', 'JPEG', 'HTML'] as $name) {
22+
echo "=== $name ===\n";
23+
$notation = $notations->getNamedItem($name);
24+
var_dump($notation->nodeName);
25+
var_dump($notation->textContent);
26+
var_dump($notation->nodeValue);
27+
var_dump($notation->isConnected);
28+
var_dump($notation->ownerDocument === $dom);
29+
var_dump($notation->parentNode === $doctype);
30+
var_dump($notation->parentElement);
31+
}
32+
?>
33+
--EXPECT--
34+
=== GIF ===
35+
string(3) "GIF"
36+
NULL
37+
NULL
38+
bool(true)
39+
bool(true)
40+
bool(true)
41+
NULL
42+
=== JPEG ===
43+
string(4) "JPEG"
44+
NULL
45+
NULL
46+
bool(true)
47+
bool(true)
48+
bool(true)
49+
NULL
50+
=== HTML ===
51+
string(4) "HTML"
52+
NULL
53+
NULL
54+
bool(true)
55+
bool(true)
56+
bool(true)
57+
NULL

0 commit comments

Comments
 (0)