xref: /PHP-8.2/ext/dom/characterdata.c (revision f2fede56)
1 /*
2    +----------------------------------------------------------------------+
3    | Copyright (c) The PHP Group                                          |
4    +----------------------------------------------------------------------+
5    | This source file is subject to version 3.01 of the PHP license,      |
6    | that is bundled with this package in the file LICENSE, and is        |
7    | available through the world-wide-web at the following url:           |
8    | https://www.php.net/license/3_01.txt                                 |
9    | If you did not receive a copy of the PHP license and are unable to   |
10    | obtain it through the world-wide-web, please send a note to          |
11    | license@php.net so we can mail you a copy immediately.               |
12    +----------------------------------------------------------------------+
13    | Authors: Christian Stocker <chregu@php.net>                          |
14    |          Rob Richards <rrichards@php.net>                            |
15    +----------------------------------------------------------------------+
16 */
17 
18 #ifdef HAVE_CONFIG_H
19 #include "config.h"
20 #endif
21 
22 #include "php.h"
23 #if defined(HAVE_LIBXML) && defined(HAVE_DOM)
24 #include "php_dom.h"
25 
26 /*
27 * class DOMCharacterData extends DOMNode
28 *
29 * URL: https://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-FF21A306
30 * Since:
31 */
32 
33 /* {{{ data	string
34 readonly=no
35 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-72AB8359
36 Since:
37 */
dom_characterdata_data_read(dom_object * obj,zval * retval)38 zend_result dom_characterdata_data_read(dom_object *obj, zval *retval)
39 {
40 	xmlNodePtr nodep = dom_object_get_node(obj);
41 
42 	if (nodep == NULL) {
43 		php_dom_throw_error(INVALID_STATE_ERR, 1);
44 		return FAILURE;
45 	}
46 
47 	php_dom_get_content_into_zval(nodep, retval, false);
48 
49 	return SUCCESS;
50 }
51 
dom_characterdata_data_write(dom_object * obj,zval * newval)52 zend_result dom_characterdata_data_write(dom_object *obj, zval *newval)
53 {
54 	xmlNode *nodep = dom_object_get_node(obj);
55 
56 	if (nodep == NULL) {
57 		php_dom_throw_error(INVALID_STATE_ERR, 1);
58 		return FAILURE;
59 	}
60 
61 	/* Typed property, this is already a string */
62 	ZEND_ASSERT(Z_TYPE_P(newval) == IS_STRING);
63 	zend_string *str = Z_STR_P(newval);
64 
65 	xmlNodeSetContentLen(nodep, (xmlChar *) ZSTR_VAL(str), ZSTR_LEN(str));
66 
67 	return SUCCESS;
68 }
69 
70 /* }}} */
71 
72 /* {{{ length	long
73 readonly=yes
74 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-7D61178C
75 Since:
76 */
dom_characterdata_length_read(dom_object * obj,zval * retval)77 zend_result dom_characterdata_length_read(dom_object *obj, zval *retval)
78 {
79 	xmlNodePtr nodep = dom_object_get_node(obj);
80 	long length = 0;
81 
82 	if (nodep == NULL) {
83 		php_dom_throw_error(INVALID_STATE_ERR, 1);
84 		return FAILURE;
85 	}
86 
87 	if (nodep->content) {
88 		length = xmlUTF8Strlen(nodep->content);
89 	}
90 
91 	ZVAL_LONG(retval, length);
92 
93 	return SUCCESS;
94 }
95 
96 /* }}} */
97 
98 /* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-6531BCCF
99 Since:
100 */
PHP_METHOD(DOMCharacterData,substringData)101 PHP_METHOD(DOMCharacterData, substringData)
102 {
103 	zval       *id;
104 	xmlChar    *cur;
105 	xmlChar    *substring;
106 	xmlNodePtr  node;
107 	zend_long        offset, count;
108 	int         length;
109 	dom_object	*intern;
110 
111 	id = ZEND_THIS;
112 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "ll", &offset, &count) == FAILURE) {
113 		RETURN_THROWS();
114 	}
115 
116 	DOM_GET_OBJ(node, id, xmlNodePtr, intern);
117 
118 	cur = node->content;
119 	if (cur == NULL) {
120 		RETURN_FALSE;
121 	}
122 
123 	length = xmlUTF8Strlen(cur);
124 
125 	if (offset < 0 || count < 0 || ZEND_LONG_INT_OVFL(offset) || ZEND_LONG_INT_OVFL(count) || offset > length) {
126 		php_dom_throw_error(INDEX_SIZE_ERR, dom_get_strict_error(intern->document));
127 		RETURN_FALSE;
128 	}
129 
130 	if ((offset + count) > length) {
131 		count = length - offset;
132 	}
133 
134 	substring = xmlUTF8Strsub(cur, (int)offset, (int)count);
135 
136 	if (substring) {
137 		RETVAL_STRING((char *) substring);
138 		xmlFree(substring);
139 	} else {
140 		RETVAL_EMPTY_STRING();
141 	}
142 }
143 /* }}} end dom_characterdata_substring_data */
144 
145 /* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-32791A2F
146 Since:
147 */
PHP_METHOD(DOMCharacterData,appendData)148 PHP_METHOD(DOMCharacterData, appendData)
149 {
150 	zval *id;
151 	xmlNode *nodep;
152 	dom_object *intern;
153 	char *arg;
154 	size_t arg_len;
155 
156 	id = ZEND_THIS;
157 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &arg, &arg_len) == FAILURE) {
158 		RETURN_THROWS();
159 	}
160 
161 	DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
162 	xmlTextConcat(nodep, (xmlChar *) arg, arg_len);
163 	RETURN_TRUE;
164 }
165 /* }}} end dom_characterdata_append_data */
166 
167 /* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-3EDB695F
168 Since:
169 */
PHP_METHOD(DOMCharacterData,insertData)170 PHP_METHOD(DOMCharacterData, insertData)
171 {
172 	zval *id;
173 	xmlChar		*cur, *first, *second;
174 	xmlNodePtr  node;
175 	char		*arg;
176 	zend_long        offset;
177 	int         length;
178 	size_t arg_len;
179 	dom_object	*intern;
180 
181 	id = ZEND_THIS;
182 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "ls", &offset, &arg, &arg_len) == FAILURE) {
183 		RETURN_THROWS();
184 	}
185 
186 	DOM_GET_OBJ(node, id, xmlNodePtr, intern);
187 
188 	cur = node->content;
189 	if (cur == NULL) {
190 		RETURN_FALSE;
191 	}
192 
193 	length = xmlUTF8Strlen(cur);
194 
195 	if (offset < 0 || ZEND_LONG_INT_OVFL(offset) || offset > length) {
196 		php_dom_throw_error(INDEX_SIZE_ERR, dom_get_strict_error(intern->document));
197 		RETURN_FALSE;
198 	}
199 
200 	first = xmlUTF8Strndup(cur, (int)offset);
201 	second = xmlUTF8Strsub(cur, (int)offset, length - (int)offset);
202 
203 	xmlNodeSetContent(node, first);
204 	xmlNodeAddContent(node, (xmlChar *) arg);
205 	xmlNodeAddContent(node, second);
206 
207 	xmlFree(first);
208 	xmlFree(second);
209 
210 	RETURN_TRUE;
211 }
212 /* }}} end dom_characterdata_insert_data */
213 
214 /* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-7C603781
215 Since:
216 */
PHP_METHOD(DOMCharacterData,deleteData)217 PHP_METHOD(DOMCharacterData, deleteData)
218 {
219 	zval *id;
220 	xmlChar    *cur, *substring, *second;
221 	xmlNodePtr  node;
222 	zend_long        offset, count;
223 	int         length;
224 	dom_object	*intern;
225 
226 	id = ZEND_THIS;
227 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "ll", &offset, &count) == FAILURE) {
228 		RETURN_THROWS();
229 	}
230 
231 	DOM_GET_OBJ(node, id, xmlNodePtr, intern);
232 
233 	cur = node->content;
234 	if (cur == NULL) {
235 		RETURN_FALSE;
236 	}
237 
238 	length = xmlUTF8Strlen(cur);
239 
240 	if (offset < 0 || count < 0 || ZEND_LONG_INT_OVFL(offset) || ZEND_LONG_INT_OVFL(count) || offset > length) {
241 		php_dom_throw_error(INDEX_SIZE_ERR, dom_get_strict_error(intern->document));
242 		RETURN_FALSE;
243 	}
244 
245 	if (offset > 0) {
246 		substring = xmlUTF8Strsub(cur, 0, (int)offset);
247 	} else {
248 		substring = NULL;
249 	}
250 
251 	if ((offset + count) > length) {
252 		count = length - offset;
253 	}
254 
255 	second = xmlUTF8Strsub(cur, (int)offset + (int)count, length - (int)offset);
256 	substring = xmlStrcat(substring, second);
257 
258 	xmlNodeSetContent(node, substring);
259 
260 	xmlFree(second);
261 	xmlFree(substring);
262 
263 	RETURN_TRUE;
264 }
265 /* }}} end dom_characterdata_delete_data */
266 
267 /* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-E5CBA7FB
268 Since:
269 */
PHP_METHOD(DOMCharacterData,replaceData)270 PHP_METHOD(DOMCharacterData, replaceData)
271 {
272 	zval *id;
273 	xmlChar		*cur, *substring, *second = NULL;
274 	xmlNodePtr  node;
275 	char		*arg;
276 	zend_long        offset, count;
277 	int         length;
278 	size_t arg_len;
279 	dom_object	*intern;
280 
281 	id = ZEND_THIS;
282 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "lls", &offset, &count, &arg, &arg_len) == FAILURE) {
283 		RETURN_THROWS();
284 	}
285 
286 	DOM_GET_OBJ(node, id, xmlNodePtr, intern);
287 
288 	cur = node->content;
289 	if (cur == NULL) {
290 		RETURN_FALSE;
291 	}
292 
293 	length = xmlUTF8Strlen(cur);
294 
295 	if (offset < 0 || count < 0 || ZEND_LONG_INT_OVFL(offset) || ZEND_LONG_INT_OVFL(count) || offset > length) {
296 		php_dom_throw_error(INDEX_SIZE_ERR, dom_get_strict_error(intern->document));
297 		RETURN_FALSE;
298 	}
299 
300 	if (offset > 0) {
301 		substring = xmlUTF8Strsub(cur, 0, (int)offset);
302 	} else {
303 		substring = NULL;
304 	}
305 
306 	if ((offset + count) > length) {
307 		count = length - offset;
308 	}
309 
310 	if (offset < length) {
311 		second = xmlUTF8Strsub(cur, (int)offset + count, length - (int)offset);
312 	}
313 
314 	substring = xmlStrcat(substring, (xmlChar *) arg);
315 	substring = xmlStrcat(substring, second);
316 
317 	xmlNodeSetContent(node, substring);
318 
319 	if (second) {
320 		xmlFree(second);
321 	}
322 	xmlFree(substring);
323 
324 	RETURN_TRUE;
325 }
326 /* }}} end dom_characterdata_replace_data */
327 
328 #endif
329