Skip to content

Commit ec2ea13

Browse files
author
Rob Richards
committed
implement clone functionality to fix segfault
DomNode->clone() creates new doc proxy if document is cloned remove printf from xpath fix remaining invalid object state issues
1 parent 0ecd198 commit ec2ea13

File tree

6 files changed

+169
-128
lines changed

6 files changed

+169
-128
lines changed

ext/dom/dom_iterators.c

+23-21
Original file line numberDiff line numberDiff line change
@@ -268,33 +268,35 @@ zend_object_iterator *php_dom_get_iterator(zend_class_entry *ce, zval *object TS
268268

269269
intern = (dom_object *)zend_object_store_get_object(object TSRMLS_CC);
270270
objmap = (dom_nnodemap_object *)intern->ptr;
271-
if (objmap->ht == NULL) {
272-
if (objmap->nodetype == DOM_NODESET) {
273-
nodeht = HASH_OF(objmap->baseobjptr);
274-
zend_hash_internal_pointer_reset(nodeht);
275-
if (zend_hash_get_current_data(nodeht, (void **) &entry)==SUCCESS) {
276-
curattr = *entry;
277-
curattr->refcount++;
278-
}
279-
} else {
280-
nodep = (xmlNode *)dom_object_get_node(objmap->baseobj);
281-
if (objmap->nodetype == XML_ATTRIBUTE_NODE || objmap->nodetype == XML_ELEMENT_NODE) {
282-
if (objmap->nodetype == XML_ATTRIBUTE_NODE) {
283-
curnode = (xmlNodePtr) nodep->properties;
284-
} else {
285-
curnode = (xmlNodePtr) nodep->children;
271+
if (objmap != NULL) {
272+
if (objmap->ht == NULL) {
273+
if (objmap->nodetype == DOM_NODESET) {
274+
nodeht = HASH_OF(objmap->baseobjptr);
275+
zend_hash_internal_pointer_reset(nodeht);
276+
if (zend_hash_get_current_data(nodeht, (void **) &entry)==SUCCESS) {
277+
curattr = *entry;
278+
curattr->refcount++;
286279
}
287280
} else {
288-
if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) {
289-
nodep = xmlDocGetRootElement((xmlDoc *) nodep);
281+
nodep = (xmlNode *)dom_object_get_node(objmap->baseobj);
282+
if (objmap->nodetype == XML_ATTRIBUTE_NODE || objmap->nodetype == XML_ELEMENT_NODE) {
283+
if (objmap->nodetype == XML_ATTRIBUTE_NODE) {
284+
curnode = (xmlNodePtr) nodep->properties;
285+
} else {
286+
curnode = (xmlNodePtr) nodep->children;
287+
}
290288
} else {
291-
nodep = nodep->children;
289+
if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) {
290+
nodep = xmlDocGetRootElement((xmlDoc *) nodep);
291+
} else {
292+
nodep = nodep->children;
293+
}
294+
curnode = dom_get_elements_by_tag_name_ns_raw(nodep, objmap->ns, objmap->local, &curindex, 0);
292295
}
293-
curnode = dom_get_elements_by_tag_name_ns_raw(nodep, objmap->ns, objmap->local, &curindex, 0);
294296
}
297+
} else {
298+
curnode = php_dom_libxml_hash_iter(objmap->ht, 0);
295299
}
296-
} else {
297-
curnode = php_dom_libxml_hash_iter(objmap->ht, 0);
298300
}
299301

300302
if (curnode) {

ext/dom/namednodemap.c

+56-46
Original file line numberDiff line numberDiff line change
@@ -61,17 +61,20 @@ int dom_namednodemap_length_read(dom_object *obj, zval **retval TSRMLS_DC)
6161
int count = 0;
6262

6363
objmap = (dom_nnodemap_object *)obj->ptr;
64-
if (objmap->ht) {
65-
count = xmlHashSize(objmap->ht);
66-
} else {
67-
nodep = dom_object_get_node(objmap->baseobj);
68-
if (nodep) {
69-
curnode = nodep->properties;
70-
if (curnode) {
71-
count++;
72-
while (curnode->next != NULL) {
64+
65+
if (objmap != NULL) {
66+
if (objmap->ht) {
67+
count = xmlHashSize(objmap->ht);
68+
} else {
69+
nodep = dom_object_get_node(objmap->baseobj);
70+
if (nodep) {
71+
curnode = nodep->properties;
72+
if (curnode) {
7373
count++;
74-
curnode = curnode->next;
74+
while (curnode->next != NULL) {
75+
count++;
76+
curnode = curnode->next;
77+
}
7578
}
7679
}
7780
}
@@ -110,17 +113,20 @@ PHP_FUNCTION(dom_namednodemap_get_named_item)
110113
intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC);
111114

112115
objmap = (dom_nnodemap_object *)intern->ptr;
113-
if (objmap->ht) {
114-
if (objmap->nodetype == XML_ENTITY_NODE) {
115-
itemnode = (xmlNodePtr)xmlHashLookup(objmap->ht, named);
116+
117+
if (objmap != NULL) {
118+
if (objmap->ht) {
119+
if (objmap->nodetype == XML_ENTITY_NODE) {
120+
itemnode = (xmlNodePtr)xmlHashLookup(objmap->ht, named);
121+
} else {
122+
notep = (xmlNotation *)xmlHashLookup(objmap->ht, named);
123+
itemnode = create_notation(notep->name, notep->PublicID, notep->SystemID);
124+
}
116125
} else {
117-
notep = (xmlNotation *)xmlHashLookup(objmap->ht, named);
118-
itemnode = create_notation(notep->name, notep->PublicID, notep->SystemID);
119-
}
120-
} else {
121-
nodep = dom_object_get_node(objmap->baseobj);
122-
if (nodep) {
123-
itemnode = (xmlNodePtr)xmlHasProp(nodep, named);
126+
nodep = dom_object_get_node(objmap->baseobj);
127+
if (nodep) {
128+
itemnode = (xmlNodePtr)xmlHasProp(nodep, named);
129+
}
124130
}
125131
}
126132

@@ -178,26 +184,27 @@ PHP_FUNCTION(dom_namednodemap_item)
178184
intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC);
179185

180186
objmap = (dom_nnodemap_object *)intern->ptr;
181-
if (objmap->ht) {
182-
if (objmap->nodetype == XML_ENTITY_NODE) {
183-
itemnode = php_dom_libxml_hash_iter(objmap->ht, index);
187+
188+
if (objmap != NULL) {
189+
if (objmap->ht) {
190+
if (objmap->nodetype == XML_ENTITY_NODE) {
191+
itemnode = php_dom_libxml_hash_iter(objmap->ht, index);
192+
} else {
193+
itemnode = php_dom_libxml_notation_iter(objmap->ht, index);
194+
}
184195
} else {
185-
itemnode = php_dom_libxml_notation_iter(objmap->ht, index);
186-
}
187-
} else {
188-
nodep = dom_object_get_node(objmap->baseobj);
189-
if (nodep) {
190-
curnode = (xmlNodePtr)nodep->properties;
191-
count = 0;
192-
while (count < index && curnode != NULL) {
193-
count++;
194-
curnode = (xmlNodePtr)curnode->next;
196+
nodep = dom_object_get_node(objmap->baseobj);
197+
if (nodep) {
198+
curnode = (xmlNodePtr)nodep->properties;
199+
count = 0;
200+
while (count < index && curnode != NULL) {
201+
count++;
202+
curnode = (xmlNodePtr)curnode->next;
203+
}
204+
itemnode = curnode;
195205
}
196-
itemnode = curnode;
197206
}
198207
}
199-
} else {
200-
RETURN_NULL();
201208
}
202209

203210
if (itemnode) {
@@ -232,17 +239,20 @@ PHP_FUNCTION(dom_namednodemap_get_named_item_ns)
232239
intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC);
233240

234241
objmap = (dom_nnodemap_object *)intern->ptr;
235-
if (objmap->ht) {
236-
if (objmap->nodetype == XML_ENTITY_NODE) {
237-
itemnode = (xmlNodePtr)xmlHashLookup(objmap->ht, named);
242+
243+
if (objmap != NULL) {
244+
if (objmap->ht) {
245+
if (objmap->nodetype == XML_ENTITY_NODE) {
246+
itemnode = (xmlNodePtr)xmlHashLookup(objmap->ht, named);
247+
} else {
248+
notep = (xmlNotation *)xmlHashLookup(objmap->ht, named);
249+
itemnode = create_notation(notep->name, notep->PublicID, notep->SystemID);
250+
}
238251
} else {
239-
notep = (xmlNotation *)xmlHashLookup(objmap->ht, named);
240-
itemnode = create_notation(notep->name, notep->PublicID, notep->SystemID);
241-
}
242-
} else {
243-
nodep = dom_object_get_node(objmap->baseobj);
244-
if (nodep) {
245-
itemnode = (xmlNodePtr)xmlHasNsProp(nodep, named, uri);
252+
nodep = dom_object_get_node(objmap->baseobj);
253+
if (nodep) {
254+
itemnode = (xmlNodePtr)xmlHasNsProp(nodep, named, uri);
255+
}
246256
}
247257
}
248258

ext/dom/node.c

+8-3
Original file line numberDiff line numberDiff line change
@@ -1291,9 +1291,13 @@ PHP_FUNCTION(dom_node_clone_node)
12911291

12921292
node = xmlDocCopyNode(n, n->doc, recursive);
12931293

1294+
if (!node) {
1295+
RETURN_FALSE;
1296+
}
1297+
12941298
/* When deep is false Element nodes still require the attributes
12951299
Following taken from libxml as xmlDocCopyNode doesnt do this */
1296-
if (node && n->type == XML_ELEMENT_NODE && recursive == 0) {
1300+
if (n->type == XML_ELEMENT_NODE && recursive == 0) {
12971301
if (n->nsDef != NULL) {
12981302
node->nsDef = xmlCopyNamespaceList(n->nsDef);
12991303
}
@@ -1319,8 +1323,9 @@ PHP_FUNCTION(dom_node_clone_node)
13191323
}
13201324
}
13211325

1322-
if (!node) {
1323-
RETURN_FALSE;
1326+
/* If document cloned we want a new document proxy */
1327+
if (node->doc != n->doc) {
1328+
intern = NULL;
13241329
}
13251330

13261331
DOM_RET_OBJ(rv, node, &ret, intern);

ext/dom/nodelist.c

+51-49
Original file line numberDiff line numberDiff line change
@@ -55,31 +55,33 @@ int dom_nodelist_length_read(dom_object *obj, zval **retval TSRMLS_DC)
5555
HashTable *nodeht;
5656

5757
objmap = (dom_nnodemap_object *)obj->ptr;
58-
if (objmap->ht) {
59-
count = xmlHashSize(objmap->ht);
60-
} else {
61-
if (objmap->nodetype == DOM_NODESET) {
62-
nodeht = HASH_OF(objmap->baseobjptr);
63-
count = zend_hash_num_elements(nodeht);
58+
if (objmap != NULL) {
59+
if (objmap->ht) {
60+
count = xmlHashSize(objmap->ht);
6461
} else {
65-
nodep = dom_object_get_node(objmap->baseobj);
66-
if (nodep) {
67-
if (objmap->nodetype == XML_ATTRIBUTE_NODE || objmap->nodetype == XML_ELEMENT_NODE) {
68-
curnode = nodep->children;
69-
if (curnode) {
70-
count++;
71-
while (curnode->next != NULL) {
62+
if (objmap->nodetype == DOM_NODESET) {
63+
nodeht = HASH_OF(objmap->baseobjptr);
64+
count = zend_hash_num_elements(nodeht);
65+
} else {
66+
nodep = dom_object_get_node(objmap->baseobj);
67+
if (nodep) {
68+
if (objmap->nodetype == XML_ATTRIBUTE_NODE || objmap->nodetype == XML_ELEMENT_NODE) {
69+
curnode = nodep->children;
70+
if (curnode) {
7271
count++;
73-
curnode = curnode->next;
72+
while (curnode->next != NULL) {
73+
count++;
74+
curnode = curnode->next;
75+
}
7476
}
75-
}
76-
} else {
77-
if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) {
78-
nodep = xmlDocGetRootElement((xmlDoc *) nodep);
7977
} else {
80-
nodep = nodep->children;
78+
if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) {
79+
nodep = xmlDocGetRootElement((xmlDoc *) nodep);
80+
} else {
81+
nodep = nodep->children;
82+
}
83+
curnode = dom_get_elements_by_tag_name_ns_raw(nodep, objmap->ns, objmap->local, &count, -1);
8184
}
82-
curnode = dom_get_elements_by_tag_name_ns_raw(nodep, objmap->ns, objmap->local, &count, -1);
8385
}
8486
}
8587
}
@@ -118,43 +120,43 @@ PHP_FUNCTION(dom_nodelist_item)
118120
intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC);
119121

120122
objmap = (dom_nnodemap_object *)intern->ptr;
121-
if (objmap->ht) {
122-
if (objmap->nodetype == XML_ENTITY_NODE) {
123-
itemnode = php_dom_libxml_hash_iter(objmap->ht, index);
124-
} else {
125-
itemnode = php_dom_libxml_notation_iter(objmap->ht, index);
126-
}
127-
} else {
128-
if (objmap->nodetype == DOM_NODESET) {
129-
nodeht = HASH_OF(objmap->baseobjptr);
130-
if (zend_hash_index_find(nodeht, index, (void **) &entry)==SUCCESS) {
131-
*return_value = **entry;
132-
zval_copy_ctor(return_value);
133-
return;
123+
if (objmap != NULL) {
124+
if (objmap->ht) {
125+
if (objmap->nodetype == XML_ENTITY_NODE) {
126+
itemnode = php_dom_libxml_hash_iter(objmap->ht, index);
127+
} else {
128+
itemnode = php_dom_libxml_notation_iter(objmap->ht, index);
134129
}
135130
} else {
136-
nodep = dom_object_get_node(objmap->baseobj);
137-
if (nodep) {
138-
if (objmap->nodetype == XML_ATTRIBUTE_NODE || objmap->nodetype == XML_ELEMENT_NODE) {
139-
curnode = nodep->children;
140-
while (count < index && curnode != NULL) {
141-
count++;
142-
curnode = curnode->next;
143-
}
144-
itemnode = curnode;
145-
} else {
146-
if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) {
147-
nodep = xmlDocGetRootElement((xmlDoc *) nodep);
131+
if (objmap->nodetype == DOM_NODESET) {
132+
nodeht = HASH_OF(objmap->baseobjptr);
133+
if (zend_hash_index_find(nodeht, index, (void **) &entry)==SUCCESS) {
134+
*return_value = **entry;
135+
zval_copy_ctor(return_value);
136+
return;
137+
}
138+
} else {
139+
nodep = dom_object_get_node(objmap->baseobj);
140+
if (nodep) {
141+
if (objmap->nodetype == XML_ATTRIBUTE_NODE || objmap->nodetype == XML_ELEMENT_NODE) {
142+
curnode = nodep->children;
143+
while (count < index && curnode != NULL) {
144+
count++;
145+
curnode = curnode->next;
146+
}
147+
itemnode = curnode;
148148
} else {
149-
nodep = nodep->children;
149+
if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) {
150+
nodep = xmlDocGetRootElement((xmlDoc *) nodep);
151+
} else {
152+
nodep = nodep->children;
153+
}
154+
itemnode = dom_get_elements_by_tag_name_ns_raw(nodep, objmap->ns, objmap->local, &count, index);
150155
}
151-
itemnode = dom_get_elements_by_tag_name_ns_raw(nodep, objmap->ns, objmap->local, &count, index);
152156
}
153157
}
154158
}
155159
}
156-
} else {
157-
RETURN_NULL();
158160
}
159161

160162
if (itemnode) {

0 commit comments

Comments
 (0)