Skip to content

Commit 18b63c9

Browse files
author
Rob Richards
committed
MFH: fix bug #44648 (Attribute names not checked for wellformedness)
add test fix some warnings
1 parent 8f2c31a commit 18b63c9

File tree

2 files changed

+91
-32
lines changed

2 files changed

+91
-32
lines changed

ext/dom/element.c

+46-32
Original file line numberDiff line numberDiff line change
@@ -187,8 +187,8 @@ PHP_METHOD(domelement, __construct)
187187
php_std_error_handling();
188188
return;
189189
}
190-
191190
php_std_error_handling();
191+
192192
name_valid = xmlValidateName((xmlChar *) name, 0);
193193
if (name_valid != 0) {
194194
php_dom_throw_error(INVALID_CHARACTER_ERR, 1 TSRMLS_CC);
@@ -270,7 +270,7 @@ int dom_element_tag_name_read(dom_object *obj, zval **retval TSRMLS_DC)
270270
ns = nodep->ns;
271271
if (ns != NULL && ns->prefix) {
272272
qname = xmlStrdup(ns->prefix);
273-
qname = xmlStrcat(qname, ":");
273+
qname = xmlStrcat(qname, (xmlChar *)":");
274274
qname = xmlStrcat(qname, nodep->name);
275275
ZVAL_STRING(*retval, (char *)qname, 1);
276276
xmlFree(qname);
@@ -307,7 +307,7 @@ static xmlNodePtr dom_get_dom1_attribute(xmlNodePtr elem, xmlChar *name) {
307307
if (nqname != NULL) {
308308
xmlNsPtr ns;
309309
xmlChar *prefix = xmlStrndup(name, len);
310-
if (prefix && xmlStrEqual(prefix, "xmlns")) {
310+
if (prefix && xmlStrEqual(prefix, (xmlChar *)"xmlns")) {
311311
ns = elem->nsDef;
312312
while (ns) {
313313
if (xmlStrEqual(ns->prefix, nqname)) {
@@ -326,7 +326,7 @@ static xmlNodePtr dom_get_dom1_attribute(xmlNodePtr elem, xmlChar *name) {
326326
return (xmlNodePtr)xmlHasNsProp(elem, nqname, ns->href);
327327
}
328328
} else {
329-
if (xmlStrEqual(name, "xmlns")) {
329+
if (xmlStrEqual(name, (xmlChar *)"xmlns")) {
330330
xmlNsPtr nsPtr = elem->nsDef;
331331
while (nsPtr) {
332332
if (nsPtr->prefix == NULL) {
@@ -348,7 +348,8 @@ PHP_FUNCTION(dom_element_get_attribute)
348348
{
349349
zval *id;
350350
xmlNode *nodep;
351-
char *name, *value = NULL;
351+
char *name;
352+
xmlChar *value = NULL;
352353
dom_object *intern;
353354
xmlNodePtr attr;
354355
int name_len;
@@ -363,20 +364,20 @@ PHP_FUNCTION(dom_element_get_attribute)
363364
if (attr) {
364365
switch (attr->type) {
365366
case XML_ATTRIBUTE_NODE:
366-
value = xmlNodeListGetString(attr->doc, attr->children, 1);
367+
value = xmlNodeListGetString(attr->doc, attr->children, 1);
367368
break;
368369
case XML_NAMESPACE_DECL:
369370
value = xmlStrdup(((xmlNsPtr)attr)->href);
370371
break;
371372
default:
372-
value = xmlStrdup(((xmlAttributePtr)attr)->defaultValue);
373+
value = xmlStrdup(((xmlAttributePtr)attr)->defaultValue);
373374
}
374375
}
375376

376377
if (value == NULL) {
377378
RETURN_EMPTY_STRING();
378379
} else {
379-
RETVAL_STRING(value, 1);
380+
RETVAL_STRING((char *)value, 1);
380381
xmlFree(value);
381382
}
382383
}
@@ -392,7 +393,7 @@ PHP_FUNCTION(dom_element_set_attribute)
392393
zval *id, *rv = NULL;
393394
xmlNode *nodep;
394395
xmlNodePtr attr = NULL;
395-
int ret, name_len, value_len;
396+
int ret, name_len, value_len, name_valid;
396397
dom_object *intern;
397398
char *name, *value;
398399

@@ -405,6 +406,12 @@ PHP_FUNCTION(dom_element_set_attribute)
405406
RETURN_FALSE;
406407
}
407408

409+
name_valid = xmlValidateName((xmlChar *) name, 0);
410+
if (name_valid != 0) {
411+
php_dom_throw_error(INVALID_CHARACTER_ERR, 1 TSRMLS_CC);
412+
RETURN_FALSE;
413+
}
414+
408415
DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
409416

410417
if (dom_node_is_read_only(nodep) == SUCCESS) {
@@ -416,7 +423,7 @@ PHP_FUNCTION(dom_element_set_attribute)
416423
if (attr != NULL) {
417424
switch (attr->type) {
418425
case XML_ATTRIBUTE_NODE:
419-
node_list_unlink(attr->children TSRMLS_CC);
426+
node_list_unlink(attr->children TSRMLS_CC);
420427
break;
421428
case XML_NAMESPACE_DECL:
422429
RETURN_FALSE;
@@ -426,12 +433,12 @@ PHP_FUNCTION(dom_element_set_attribute)
426433

427434
}
428435

429-
if (xmlStrEqual((xmlChar *)name, "xmlns")) {
436+
if (xmlStrEqual((xmlChar *)name, (xmlChar *)"xmlns")) {
430437
if (xmlNewNs(nodep, (xmlChar *)value, NULL)) {
431438
RETURN_TRUE;
432439
}
433440
} else {
434-
attr = (xmlNodePtr)xmlSetProp(nodep, (xmlChar *) name, value);
441+
attr = (xmlNodePtr)xmlSetProp(nodep, (xmlChar *) name, (xmlChar *)value);
435442
}
436443
if (!attr) {
437444
php_error_docref(NULL TSRMLS_CC, E_WARNING, "No such attribute '%s'", name);
@@ -528,7 +535,7 @@ PHP_FUNCTION(dom_element_get_attribute_node)
528535
if (attrp->children) {
529536
attrp = xmlNewDocNode(nodep->doc, NULL, (xmlChar *) attrp->children, attrp->name);
530537
} else {
531-
attrp = xmlNewDocNode(nodep->doc, NULL, "xmlns", attrp->name);
538+
attrp = xmlNewDocNode(nodep->doc, NULL, (xmlChar *)"xmlns", attrp->name);
532539
}
533540
attrp->type = XML_NAMESPACE_DECL;
534541
attrp->parent = nsparent;
@@ -679,7 +686,8 @@ PHP_FUNCTION(dom_element_get_attribute_ns)
679686
xmlNsPtr nsptr;
680687
dom_object *intern;
681688
int uri_len = 0, name_len = 0;
682-
char *uri, *name, *strattr;
689+
char *uri, *name;
690+
xmlChar *strattr;
683691

684692
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os!s", &id, dom_element_class_entry, &uri, &uri_len, &name, &name_len) == FAILURE) {
685693
return;
@@ -690,11 +698,11 @@ PHP_FUNCTION(dom_element_get_attribute_ns)
690698
strattr = xmlGetNsProp(elemp, (xmlChar *) name, (xmlChar *) uri);
691699

692700
if (strattr != NULL) {
693-
RETVAL_STRING(strattr, 1);
701+
RETVAL_STRING((char *)strattr, 1);
694702
xmlFree(strattr);
695703
} else {
696-
if (xmlStrEqual((xmlChar *) uri, DOM_XMLNS_NAMESPACE)) {
697-
nsptr = dom_get_nsdecl(elemp, name);
704+
if (xmlStrEqual((xmlChar *) uri, (xmlChar *)DOM_XMLNS_NAMESPACE)) {
705+
nsptr = dom_get_nsdecl(elemp, (xmlChar *)name);
698706
if (nsptr != NULL) {
699707
RETVAL_STRING((char *) nsptr->href, 1);
700708
} else {
@@ -759,7 +767,7 @@ PHP_FUNCTION(dom_element_set_attribute_ns)
759767
char *uri, *name, *value;
760768
char *localname = NULL, *prefix = NULL;
761769
dom_object *intern;
762-
int errorcode = 0, stricterror, is_xmlns = 0;
770+
int errorcode = 0, stricterror, is_xmlns = 0, name_valid;
763771

764772
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os!ss", &id, dom_element_class_entry, &uri, &uri_len, &name, &name_len, &value, &value_len) == FAILURE) {
765773
return;
@@ -788,11 +796,11 @@ PHP_FUNCTION(dom_element_set_attribute_ns)
788796
node_list_unlink(nodep->children TSRMLS_CC);
789797
}
790798

791-
if (xmlStrEqual((xmlChar *) prefix,"xmlns") && xmlStrEqual((xmlChar *) uri, DOM_XMLNS_NAMESPACE)) {
799+
if (xmlStrEqual((xmlChar *) prefix, (xmlChar *)"xmlns") && xmlStrEqual((xmlChar *) uri, (xmlChar *)DOM_XMLNS_NAMESPACE)) {
792800
is_xmlns = 1;
793-
nsptr = dom_get_nsdecl(elemp, localname);
801+
nsptr = dom_get_nsdecl(elemp, (xmlChar *)localname);
794802
} else {
795-
nsptr = xmlSearchNsByHref(elemp->doc, elemp, uri);
803+
nsptr = xmlSearchNsByHref(elemp->doc, elemp, (xmlChar *)uri);
796804
if (nsptr && nsptr->prefix == NULL) {
797805
xmlNsPtr tmpnsptr;
798806

@@ -816,7 +824,7 @@ PHP_FUNCTION(dom_element_set_attribute_ns)
816824
errorcode = NAMESPACE_ERR;
817825
} else {
818826
if (is_xmlns == 1) {
819-
xmlNewNs(elemp, value, localname);
827+
xmlNewNs(elemp, (xmlChar *)value, (xmlChar *)localname);
820828
} else {
821829
nsptr = dom_get_ns(elemp, uri, &errorcode, prefix);
822830
}
@@ -827,19 +835,25 @@ PHP_FUNCTION(dom_element_set_attribute_ns)
827835
if (nsptr->href) {
828836
xmlFree((xmlChar *) nsptr->href);
829837
}
830-
nsptr->href = xmlStrdup(value);
838+
nsptr->href = xmlStrdup((xmlChar *)value);
831839
}
832840
}
833841

834842
if (errorcode == 0 && is_xmlns == 0) {
835-
attr = xmlSetNsProp(elemp, nsptr, localname, value);
843+
attr = xmlSetNsProp(elemp, nsptr, (xmlChar *)localname, (xmlChar *)value);
836844
}
837845
} else {
838-
attr = xmlHasProp(elemp, localname);
839-
if (attr != NULL && attr->type != XML_ATTRIBUTE_DECL) {
840-
node_list_unlink(attr->children TSRMLS_CC);
846+
name_valid = xmlValidateName((xmlChar *) localname, 0);
847+
if (name_valid != 0) {
848+
errorcode = INVALID_CHARACTER_ERR;
849+
stricterror = 1;
850+
} else {
851+
attr = xmlHasProp(elemp, (xmlChar *)localname);
852+
if (attr != NULL && attr->type != XML_ATTRIBUTE_DECL) {
853+
node_list_unlink(attr->children TSRMLS_CC);
854+
}
855+
attr = xmlSetProp(elemp, (xmlChar *)localname, (xmlChar *)value);
841856
}
842-
attr = xmlSetProp(elemp, localname, value);
843857
}
844858
}
845859

@@ -934,7 +948,7 @@ PHP_FUNCTION(dom_element_get_attribute_node_ns)
934948

935949
DOM_GET_OBJ(elemp, id, xmlNodePtr, intern);
936950

937-
attrp = xmlHasNsProp(elemp, name, uri);
951+
attrp = xmlHasNsProp(elemp, (xmlChar *)name, (xmlChar *)uri);
938952

939953
if (attrp == NULL) {
940954
RETURN_NULL();
@@ -1101,8 +1115,8 @@ PHP_FUNCTION(dom_element_has_attribute_ns)
11011115
xmlFree(value);
11021116
RETURN_TRUE;
11031117
} else {
1104-
if (xmlStrEqual(uri, DOM_XMLNS_NAMESPACE)) {
1105-
nsp = dom_get_nsdecl(elemp, name);
1118+
if (xmlStrEqual((xmlChar *)uri, (xmlChar *)DOM_XMLNS_NAMESPACE)) {
1119+
nsp = dom_get_nsdecl(elemp, (xmlChar *)name);
11061120
if (nsp != NULL) {
11071121
RETURN_TRUE;
11081122
}
@@ -1157,7 +1171,7 @@ PHP_FUNCTION(dom_element_set_id_attribute)
11571171
RETURN_NULL();
11581172
}
11591173

1160-
attrp = xmlHasNsProp(nodep, name, NULL);
1174+
attrp = xmlHasNsProp(nodep, (xmlChar *)name, NULL);
11611175
if (attrp == NULL || attrp->type == XML_ATTRIBUTE_DECL) {
11621176
php_dom_throw_error(NOT_FOUND_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
11631177
} else {

ext/dom/tests/bug44648.phpt

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
--TEST--
2+
Bug #44648 (Attribute names not checked for wellformedness)
3+
--SKIPIF--
4+
<?php require_once('skipif.inc'); ?>
5+
--FILE--
6+
<?php
7+
8+
$doc = new DOMDocument();
9+
$doc->loadXML('<root/>');
10+
11+
$root = $doc->documentElement;
12+
13+
try {
14+
$attr = new DOMAttr('@acb', '123');
15+
$root->setAttributeNode($attr);
16+
} catch (DOMException $e) {
17+
echo $e->getMessage()."\n";
18+
}
19+
20+
try {
21+
$root->setAttribute('@def', '456');
22+
} catch (DOMException $e) {
23+
echo $e->getMessage()."\n";
24+
}
25+
26+
try {
27+
$root->setAttributeNS(NULL, '@ghi', '789');
28+
} catch (DOMException $e) {
29+
echo $e->getMessage()."\n";
30+
}
31+
32+
try {
33+
$root->setAttributeNS('urn::test', 'a:g@hi', '789');
34+
} catch (DOMException $e) {
35+
echo $e->getMessage()."\n";
36+
}
37+
38+
echo $doc->saveXML($root);
39+
?>
40+
--EXPECT--
41+
Invalid Character Error
42+
Invalid Character Error
43+
Invalid Character Error
44+
Namespace Error
45+
<root/>

0 commit comments

Comments
 (0)