Skip to content

Commit f54451c

Browse files
committed
Make DOMNode::textContent writeable
1 parent 8da58e3 commit f54451c

File tree

6 files changed

+75
-104
lines changed

6 files changed

+75
-104
lines changed

ext/dom/attr.c

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -183,14 +183,7 @@ int dom_attr_value_write(dom_object *obj, zval *newval TSRMLS_DC)
183183
node_list_unlink(attrp->children TSRMLS_CC);
184184
}
185185

186-
if (newval->type != IS_STRING) {
187-
if(Z_REFCOUNT_P(newval) > 1) {
188-
value_copy = *newval;
189-
zval_copy_ctor(&value_copy);
190-
newval = &value_copy;
191-
}
192-
convert_to_string(newval);
193-
}
186+
convert_to_string_copy(newval, value_copy);
194187

195188
xmlNodeSetContentLen((xmlNodePtr) attrp, Z_STRVAL_P(newval), Z_STRLEN_P(newval) + 1);
196189

ext/dom/characterdata.c

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -112,14 +112,7 @@ int dom_characterdata_data_write(dom_object *obj, zval *newval TSRMLS_DC)
112112
return FAILURE;
113113
}
114114

115-
if (newval->type != IS_STRING) {
116-
if(Z_REFCOUNT_P(newval) > 1) {
117-
value_copy = *newval;
118-
zval_copy_ctor(&value_copy);
119-
newval = &value_copy;
120-
}
121-
convert_to_string(newval);
122-
}
115+
convert_to_string_copy(newval, value_copy);
123116

124117
xmlNodeSetContentLen(nodep, Z_STRVAL_P(newval), Z_STRLEN_P(newval) + 1);
125118

ext/dom/document.c

Lines changed: 11 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -361,14 +361,7 @@ int dom_document_encoding_write(dom_object *obj, zval *newval TSRMLS_DC)
361361
return FAILURE;
362362
}
363363

364-
if (newval->type != IS_STRING) {
365-
if(Z_REFCOUNT_P(newval) > 1) {
366-
value_copy = *newval;
367-
zval_copy_ctor(&value_copy);
368-
newval = &value_copy;
369-
}
370-
convert_to_string(newval);
371-
}
364+
convert_to_string_copy(newval, value_copy);
372365

373366
handler = xmlFindCharEncodingHandler(Z_STRVAL_P(newval));
374367

@@ -428,12 +421,7 @@ int dom_document_standalone_write(dom_object *obj, zval *newval TSRMLS_DC)
428421
return FAILURE;
429422
}
430423

431-
if(Z_REFCOUNT_P(newval) > 1) {
432-
value_copy = *newval;
433-
zval_copy_ctor(&value_copy);
434-
newval = &value_copy;
435-
}
436-
convert_to_long(newval);
424+
convert_to_long_copy(newval, value_copy);
437425

438426
standalone = Z_LVAL_P(newval);
439427
if (standalone > 0) {
@@ -500,14 +488,7 @@ int dom_document_version_write(dom_object *obj, zval *newval TSRMLS_DC)
500488
xmlFree((xmlChar *) docp->version );
501489
}
502490

503-
if (newval->type != IS_STRING) {
504-
if(Z_REFCOUNT_P(newval) > 1) {
505-
value_copy = *newval;
506-
zval_copy_ctor(&value_copy);
507-
newval = &value_copy;
508-
}
509-
convert_to_string(newval);
510-
}
491+
convert_to_string_copy(newval, value_copy);
511492

512493
docp->version = xmlStrdup((const xmlChar *) Z_STRVAL_P(newval));
513494

@@ -544,12 +525,7 @@ int dom_document_strict_error_checking_write(dom_object *obj, zval *newval TSRML
544525
zval value_copy;
545526
dom_doc_propsptr doc_prop;
546527

547-
if(Z_REFCOUNT_P(newval) > 1) {
548-
value_copy = *newval;
549-
zval_copy_ctor(&value_copy);
550-
newval = &value_copy;
551-
}
552-
convert_to_boolean(newval);
528+
convert_to_boolean_copy(newval, value_copy);
553529

554530
if (obj->document) {
555531
doc_prop = dom_get_doc_props(obj->document);
@@ -587,12 +563,7 @@ int dom_document_format_output_write(dom_object *obj, zval *newval TSRMLS_DC)
587563
zval value_copy;
588564
dom_doc_propsptr doc_prop;
589565

590-
if(Z_REFCOUNT_P(newval) > 1) {
591-
value_copy = *newval;
592-
zval_copy_ctor(&value_copy);
593-
newval = &value_copy;
594-
}
595-
convert_to_boolean(newval);
566+
convert_to_boolean_copy(newval, value_copy);
596567

597568
if (obj->document) {
598569
doc_prop = dom_get_doc_props(obj->document);
@@ -629,12 +600,7 @@ int dom_document_validate_on_parse_write(dom_object *obj, zval *newval TSRMLS_DC
629600
zval value_copy;
630601
dom_doc_propsptr doc_prop;
631602

632-
if(Z_REFCOUNT_P(newval) > 1) {
633-
value_copy = *newval;
634-
zval_copy_ctor(&value_copy);
635-
newval = &value_copy;
636-
}
637-
convert_to_boolean(newval);
603+
convert_to_boolean_copy(newval, value_copy);
638604

639605
if (obj->document) {
640606
doc_prop = dom_get_doc_props(obj->document);
@@ -671,12 +637,7 @@ int dom_document_resolve_externals_write(dom_object *obj, zval *newval TSRMLS_DC
671637
zval value_copy;
672638
dom_doc_propsptr doc_prop;
673639

674-
if(Z_REFCOUNT_P(newval) > 1) {
675-
value_copy = *newval;
676-
zval_copy_ctor(&value_copy);
677-
newval = &value_copy;
678-
}
679-
convert_to_boolean(newval);
640+
convert_to_boolean_copy(newval, value_copy);
680641

681642
if (obj->document) {
682643
doc_prop = dom_get_doc_props(obj->document);
@@ -713,12 +674,7 @@ int dom_document_preserve_whitespace_write(dom_object *obj, zval *newval TSRMLS_
713674
zval value_copy;
714675
dom_doc_propsptr doc_prop;
715676

716-
if(Z_REFCOUNT_P(newval) > 1) {
717-
value_copy = *newval;
718-
zval_copy_ctor(&value_copy);
719-
newval = &value_copy;
720-
}
721-
convert_to_boolean(newval);
677+
convert_to_boolean_copy(newval, value_copy);
722678

723679
if (obj->document) {
724680
doc_prop = dom_get_doc_props(obj->document);
@@ -755,12 +711,7 @@ int dom_document_recover_write(dom_object *obj, zval *newval TSRMLS_DC)
755711
zval value_copy;
756712
dom_doc_propsptr doc_prop;
757713

758-
if(Z_REFCOUNT_P(newval) > 1) {
759-
value_copy = *newval;
760-
zval_copy_ctor(&value_copy);
761-
newval = &value_copy;
762-
}
763-
convert_to_boolean(newval);
714+
convert_to_boolean_copy(newval, value_copy);
764715

765716
if (obj->document) {
766717
doc_prop = dom_get_doc_props(obj->document);
@@ -797,12 +748,7 @@ int dom_document_substitue_entities_write(dom_object *obj, zval *newval TSRMLS_D
797748
zval value_copy;
798749
dom_doc_propsptr doc_prop;
799750

800-
if(Z_REFCOUNT_P(newval) > 1) {
801-
value_copy = *newval;
802-
zval_copy_ctor(&value_copy);
803-
newval = &value_copy;
804-
}
805-
convert_to_boolean(newval);
751+
convert_to_boolean_copy(newval, value_copy);
806752

807753
if (obj->document) {
808754
doc_prop = dom_get_doc_props(obj->document);
@@ -861,14 +807,7 @@ int dom_document_document_uri_write(dom_object *obj, zval *newval TSRMLS_DC)
861807
xmlFree((xmlChar *) docp->URL);
862808
}
863809

864-
if (newval->type != IS_STRING) {
865-
if(Z_REFCOUNT_P(newval) > 1) {
866-
value_copy = *newval;
867-
zval_copy_ctor(&value_copy);
868-
newval = &value_copy;
869-
}
870-
convert_to_string(newval);
871-
}
810+
convert_to_string_copy(newval, value_copy);
872811

873812
docp->URL = xmlStrdup((const xmlChar *) Z_STRVAL_P(newval));
874813

ext/dom/node.c

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -352,14 +352,7 @@ int dom_node_node_value_write(dom_object *obj, zval *newval TSRMLS_DC)
352352
case XML_COMMENT_NODE:
353353
case XML_CDATA_SECTION_NODE:
354354
case XML_PI_NODE:
355-
if (newval->type != IS_STRING) {
356-
if(Z_REFCOUNT_P(newval) > 1) {
357-
value_copy = *newval;
358-
zval_copy_ctor(&value_copy);
359-
newval = &value_copy;
360-
}
361-
convert_to_string(newval);
362-
}
355+
convert_to_string_copy(newval, value_copy);
363356
xmlNodeSetContentLen(nodep, Z_STRVAL_P(newval), Z_STRLEN_P(newval) + 1);
364357
if (newval == &value_copy) {
365358
zval_dtor(newval);
@@ -794,14 +787,7 @@ int dom_node_prefix_write(dom_object *obj, zval *newval TSRMLS_DC)
794787
nsnode = xmlDocGetRootElement(nodep->doc);
795788
}
796789
}
797-
if (newval->type != IS_STRING) {
798-
if(Z_REFCOUNT_P(newval) > 1) {
799-
value_copy = *newval;
800-
zval_copy_ctor(&value_copy);
801-
newval = &value_copy;
802-
}
803-
convert_to_string(newval);
804-
}
790+
convert_to_string_copy(newval, value_copy);
805791
prefix = Z_STRVAL_P(newval);
806792
if (nsnode && nodep->ns != NULL && !xmlStrEqual(nodep->ns->prefix, (xmlChar *)prefix)) {
807793
strURI = (char *) nodep->ns->href;
@@ -942,6 +928,23 @@ int dom_node_text_content_read(dom_object *obj, zval **retval TSRMLS_DC)
942928

943929
int dom_node_text_content_write(dom_object *obj, zval *newval TSRMLS_DC)
944930
{
931+
xmlNode *nodep = dom_object_get_node(obj);
932+
zval value_copy;
933+
xmlChar *enc_str;
934+
935+
if (nodep == NULL) {
936+
php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
937+
return FAILURE;
938+
}
939+
940+
convert_to_string_copy(newval, value_copy);
941+
enc_str = xmlEncodeEntitiesReentrant(nodep->doc, Z_STRVAL_P(newval));
942+
xmlNodeSetContent(nodep, enc_str);
943+
xmlFree(enc_str);
944+
if (newval == &value_copy) {
945+
zval_dtor(newval);
946+
}
947+
945948
return SUCCESS;
946949
}
947950

ext/dom/php_dom.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,20 @@ entry = zend_register_internal_class_ex(&ce, parent_ce, NULL TSRMLS_CC);
146146
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Not yet implemented"); \
147147
return;
148148

149+
#define convert_to_copy_master(orig, copy, lower_type, upper_type) \
150+
if (Z_TYPE_P(orig) != IS_##upper_type) { \
151+
if (Z_REFCOUNT_P(orig) > 1) { \
152+
copy = *orig; \
153+
zval_copy_ctor(&copy); \
154+
orig = © \
155+
} \
156+
convert_to_##lower_type(orig); \
157+
}
158+
159+
#define convert_to_string_copy(orig, copy) convert_to_copy_master(orig, copy, string, STRING);
160+
#define convert_to_long_copy(orig, copy) convert_to_copy_master(orig, copy, long, LONG);
161+
#define convert_to_boolean_copy(orig, copy) convert_to_copy_master(orig, copy, boolean, BOOL);
162+
149163
#define DOM_NODELIST 0
150164
#define DOM_NAMEDNODEMAP 1
151165

ext/dom/tests/node_textcontent.phpt

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
--TEST--
2+
Testing reading and writing to DOMNode::textContent
3+
--SKIPIF--
4+
<?php require_once('skipif.inc'); ?>
5+
--FILE--
6+
<?php
7+
8+
$html = <<<HTML
9+
<div id="test"><span>hi there</span></div>
10+
HTML;
11+
12+
$text = '<p>hello world &trade;</p>';
13+
14+
$dom = new DOMDocument('1.0', 'UTF-8');
15+
$dom->loadHTML($html);
16+
17+
$node = $dom->getElementById('test');
18+
var_dump($node->textContent);
19+
$node->textContent = $text;
20+
var_dump($node->textContent == $text);
21+
22+
var_dump($dom->saveHTML($node));
23+
24+
?>
25+
--EXPECT--
26+
string(8) "hi there"
27+
bool(true)
28+
string(63) "<div id="test">&lt;p&gt;hello world &amp;trade;&lt;/p&gt;</div>"
29+

0 commit comments

Comments
 (0)