xref: /PHP-8.1/ext/dom/characterdata.c (revision abb1d2e8)
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 int dom_characterdata_data_read(dom_object *obj, zval *retval)
39 {
40 	xmlNodePtr nodep = dom_object_get_node(obj);
41 	xmlChar *content;
42 
43 	if (nodep == NULL) {
44 		php_dom_throw_error(INVALID_STATE_ERR, 1);
45 		return FAILURE;
46 	}
47 
48 	if ((content = xmlNodeGetContent(nodep)) != NULL) {
49 		ZVAL_STRING(retval, (char *) content);
50 		xmlFree(content);
51 	} else {
52 		ZVAL_EMPTY_STRING(retval);
53 	}
54 
55 	return SUCCESS;
56 }
57 
dom_characterdata_data_write(dom_object * obj,zval * newval)58 int dom_characterdata_data_write(dom_object *obj, zval *newval)
59 {
60 	xmlNode *nodep = dom_object_get_node(obj);
61 	zend_string *str;
62 
63 	if (nodep == NULL) {
64 		php_dom_throw_error(INVALID_STATE_ERR, 1);
65 		return FAILURE;
66 	}
67 
68 	str = zval_try_get_string(newval);
69 	if (UNEXPECTED(!str)) {
70 		return FAILURE;
71 	}
72 
73 	xmlNodeSetContentLen(nodep, (xmlChar *) ZSTR_VAL(str), ZSTR_LEN(str) + 1);
74 
75 	zend_string_release_ex(str, 0);
76 	return SUCCESS;
77 }
78 
79 /* }}} */
80 
81 /* {{{ length	long
82 readonly=yes
83 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-7D61178C
84 Since:
85 */
dom_characterdata_length_read(dom_object * obj,zval * retval)86 int dom_characterdata_length_read(dom_object *obj, zval *retval)
87 {
88 	xmlNodePtr nodep = dom_object_get_node(obj);
89 	xmlChar *content;
90 	long length = 0;
91 
92 	if (nodep == NULL) {
93 		php_dom_throw_error(INVALID_STATE_ERR, 1);
94 		return FAILURE;
95 	}
96 
97 	content = xmlNodeGetContent(nodep);
98 
99 	if (content) {
100 		length = xmlUTF8Strlen(content);
101 		xmlFree(content);
102 	}
103 
104 	ZVAL_LONG(retval, length);
105 
106 	return SUCCESS;
107 }
108 
109 /* }}} */
110 
111 /* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-6531BCCF
112 Since:
113 */
PHP_METHOD(DOMCharacterData,substringData)114 PHP_METHOD(DOMCharacterData, substringData)
115 {
116 	zval       *id;
117 	xmlChar    *cur;
118 	xmlChar    *substring;
119 	xmlNodePtr  node;
120 	zend_long        offset, count;
121 	int         length;
122 	dom_object	*intern;
123 
124 	id = ZEND_THIS;
125 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "ll", &offset, &count) == FAILURE) {
126 		RETURN_THROWS();
127 	}
128 
129 	DOM_GET_OBJ(node, id, xmlNodePtr, intern);
130 
131 	cur = xmlNodeGetContent(node);
132 	if (cur == NULL) {
133 		RETURN_FALSE;
134 	}
135 
136 	length = xmlUTF8Strlen(cur);
137 
138 	if (offset < 0 || count < 0 || ZEND_LONG_INT_OVFL(offset) || ZEND_LONG_INT_OVFL(count) || offset > length) {
139 		xmlFree(cur);
140 		php_dom_throw_error(INDEX_SIZE_ERR, dom_get_strict_error(intern->document));
141 		RETURN_FALSE;
142 	}
143 
144 	if ((offset + count) > length) {
145 		count = length - offset;
146 	}
147 
148 	substring = xmlUTF8Strsub(cur, (int)offset, (int)count);
149 	xmlFree(cur);
150 
151 	if (substring) {
152 		RETVAL_STRING((char *) substring);
153 		xmlFree(substring);
154 	} else {
155 		RETVAL_EMPTY_STRING();
156 	}
157 }
158 /* }}} end dom_characterdata_substring_data */
159 
160 /* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-32791A2F
161 Since:
162 */
PHP_METHOD(DOMCharacterData,appendData)163 PHP_METHOD(DOMCharacterData, appendData)
164 {
165 	zval *id;
166 	xmlNode *nodep;
167 	dom_object *intern;
168 	char *arg;
169 	size_t arg_len;
170 
171 	id = ZEND_THIS;
172 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &arg, &arg_len) == FAILURE) {
173 		RETURN_THROWS();
174 	}
175 
176 	DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
177 	xmlTextConcat(nodep, (xmlChar *) arg, arg_len);
178 	RETURN_TRUE;
179 }
180 /* }}} end dom_characterdata_append_data */
181 
182 /* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-3EDB695F
183 Since:
184 */
PHP_METHOD(DOMCharacterData,insertData)185 PHP_METHOD(DOMCharacterData, insertData)
186 {
187 	zval *id;
188 	xmlChar		*cur, *first, *second;
189 	xmlNodePtr  node;
190 	char		*arg;
191 	zend_long        offset;
192 	int         length;
193 	size_t arg_len;
194 	dom_object	*intern;
195 
196 	id = ZEND_THIS;
197 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "ls", &offset, &arg, &arg_len) == FAILURE) {
198 		RETURN_THROWS();
199 	}
200 
201 	DOM_GET_OBJ(node, id, xmlNodePtr, intern);
202 
203 	cur = xmlNodeGetContent(node);
204 	if (cur == NULL) {
205 		RETURN_FALSE;
206 	}
207 
208 	length = xmlUTF8Strlen(cur);
209 
210 	if (offset < 0 || ZEND_LONG_INT_OVFL(offset) || offset > length) {
211 		xmlFree(cur);
212 		php_dom_throw_error(INDEX_SIZE_ERR, dom_get_strict_error(intern->document));
213 		RETURN_FALSE;
214 	}
215 
216 	first = xmlUTF8Strndup(cur, (int)offset);
217 	second = xmlUTF8Strsub(cur, (int)offset, length - (int)offset);
218 	xmlFree(cur);
219 
220 	xmlNodeSetContent(node, first);
221 	xmlNodeAddContent(node, (xmlChar *) arg);
222 	xmlNodeAddContent(node, second);
223 
224 	xmlFree(first);
225 	xmlFree(second);
226 
227 	RETURN_TRUE;
228 }
229 /* }}} end dom_characterdata_insert_data */
230 
231 /* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-7C603781
232 Since:
233 */
PHP_METHOD(DOMCharacterData,deleteData)234 PHP_METHOD(DOMCharacterData, deleteData)
235 {
236 	zval *id;
237 	xmlChar    *cur, *substring, *second;
238 	xmlNodePtr  node;
239 	zend_long        offset, count;
240 	int         length;
241 	dom_object	*intern;
242 
243 	id = ZEND_THIS;
244 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "ll", &offset, &count) == FAILURE) {
245 		RETURN_THROWS();
246 	}
247 
248 	DOM_GET_OBJ(node, id, xmlNodePtr, intern);
249 
250 	cur = xmlNodeGetContent(node);
251 	if (cur == NULL) {
252 		RETURN_FALSE;
253 	}
254 
255 	length = xmlUTF8Strlen(cur);
256 
257 	if (offset < 0 || count < 0 || ZEND_LONG_INT_OVFL(offset) || ZEND_LONG_INT_OVFL(count) || offset > length) {
258 		xmlFree(cur);
259 		php_dom_throw_error(INDEX_SIZE_ERR, dom_get_strict_error(intern->document));
260 		RETURN_FALSE;
261 	}
262 
263 	if (offset > 0) {
264 		substring = xmlUTF8Strsub(cur, 0, (int)offset);
265 	} else {
266 		substring = NULL;
267 	}
268 
269 	if ((offset + count) > length) {
270 		count = length - offset;
271 	}
272 
273 	second = xmlUTF8Strsub(cur, (int)offset + (int)count, length - (int)offset);
274 	substring = xmlStrcat(substring, second);
275 
276 	xmlNodeSetContent(node, substring);
277 
278 	xmlFree(cur);
279 	xmlFree(second);
280 	xmlFree(substring);
281 
282 	RETURN_TRUE;
283 }
284 /* }}} end dom_characterdata_delete_data */
285 
286 /* {{{ URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-E5CBA7FB
287 Since:
288 */
PHP_METHOD(DOMCharacterData,replaceData)289 PHP_METHOD(DOMCharacterData, replaceData)
290 {
291 	zval *id;
292 	xmlChar		*cur, *substring, *second = NULL;
293 	xmlNodePtr  node;
294 	char		*arg;
295 	zend_long        offset, count;
296 	int         length;
297 	size_t arg_len;
298 	dom_object	*intern;
299 
300 	id = ZEND_THIS;
301 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "lls", &offset, &count, &arg, &arg_len) == FAILURE) {
302 		RETURN_THROWS();
303 	}
304 
305 	DOM_GET_OBJ(node, id, xmlNodePtr, intern);
306 
307 	cur = xmlNodeGetContent(node);
308 	if (cur == NULL) {
309 		RETURN_FALSE;
310 	}
311 
312 	length = xmlUTF8Strlen(cur);
313 
314 	if (offset < 0 || count < 0 || ZEND_LONG_INT_OVFL(offset) || ZEND_LONG_INT_OVFL(count) || offset > length) {
315 		xmlFree(cur);
316 		php_dom_throw_error(INDEX_SIZE_ERR, dom_get_strict_error(intern->document));
317 		RETURN_FALSE;
318 	}
319 
320 	if (offset > 0) {
321 		substring = xmlUTF8Strsub(cur, 0, (int)offset);
322 	} else {
323 		substring = NULL;
324 	}
325 
326 	if ((offset + count) > length) {
327 		count = length - offset;
328 	}
329 
330 	if (offset < length) {
331 		second = xmlUTF8Strsub(cur, (int)offset + count, length - (int)offset);
332 	}
333 
334 	substring = xmlStrcat(substring, (xmlChar *) arg);
335 	substring = xmlStrcat(substring, second);
336 
337 	xmlNodeSetContent(node, substring);
338 
339 	xmlFree(cur);
340 	if (second) {
341 		xmlFree(second);
342 	}
343 	xmlFree(substring);
344 
345 	RETURN_TRUE;
346 }
347 /* }}} end dom_characterdata_replace_data */
348 
PHP_METHOD(DOMCharacterData,remove)349 PHP_METHOD(DOMCharacterData, remove)
350 {
351 	zval *id = ZEND_THIS;
352 	xmlNodePtr child;
353 	dom_object *intern;
354 
355 	if (zend_parse_parameters_none() == FAILURE) {
356 		RETURN_THROWS();
357 	}
358 
359 	DOM_GET_OBJ(child, id, xmlNodePtr, intern);
360 
361 	dom_child_node_remove(intern);
362 	RETURN_NULL();
363 }
364 
PHP_METHOD(DOMCharacterData,after)365 PHP_METHOD(DOMCharacterData, after)
366 {
367 	int argc = 0;
368 	zval *args, *id;
369 	dom_object *intern;
370 	xmlNode *context;
371 
372 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "*", &args, &argc) == FAILURE) {
373 		RETURN_THROWS();
374 	}
375 
376 	id = ZEND_THIS;
377 	DOM_GET_OBJ(context, id, xmlNodePtr, intern);
378 
379 	dom_parent_node_after(intern, args, argc);
380 }
381 
PHP_METHOD(DOMCharacterData,before)382 PHP_METHOD(DOMCharacterData, before)
383 {
384 	int argc = 0;
385 	zval *args, *id;
386 	dom_object *intern;
387 	xmlNode *context;
388 
389 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "*", &args, &argc) == FAILURE) {
390 		RETURN_THROWS();
391 	}
392 
393 	id = ZEND_THIS;
394 	DOM_GET_OBJ(context, id, xmlNodePtr, intern);
395 
396 	dom_parent_node_before(intern, args, argc);
397 }
398 
PHP_METHOD(DOMCharacterData,replaceWith)399 PHP_METHOD(DOMCharacterData, replaceWith)
400 {
401 	int argc = 0;
402 	zval *args, *id;
403 	dom_object *intern;
404 	xmlNode *context;
405 
406 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "*", &args, &argc) == FAILURE) {
407 		RETURN_THROWS();
408 	}
409 
410 	id = ZEND_THIS;
411 	DOM_GET_OBJ(context, id, xmlNodePtr, intern);
412 
413 	dom_child_replace_with(intern, args, argc);
414 }
415 
416 #endif
417