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