1 /*
2 +----------------------------------------------------------------------+
3 | PHP Version 7 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1997-2018 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_get_string(newval);
108
109 xmlNodeSetContentLen(nodep, (xmlChar *) ZSTR_VAL(str), ZSTR_LEN(str) + 1);
110
111 zend_string_release_ex(str, 0);
112 return SUCCESS;
113 }
114
115 /* }}} */
116
117 /* {{{ length long
118 readonly=yes
119 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-7D61178C
120 Since:
121 */
dom_characterdata_length_read(dom_object * obj,zval * retval)122 int dom_characterdata_length_read(dom_object *obj, zval *retval)
123 {
124 xmlNodePtr nodep = dom_object_get_node(obj);
125 xmlChar *content;
126 long length = 0;
127
128 if (nodep == NULL) {
129 php_dom_throw_error(INVALID_STATE_ERR, 0);
130 return FAILURE;
131 }
132
133 content = xmlNodeGetContent(nodep);
134
135 if (content) {
136 length = xmlUTF8Strlen(content);
137 xmlFree(content);
138 }
139
140 ZVAL_LONG(retval, length);
141
142 return SUCCESS;
143 }
144
145 /* }}} */
146
147 /* {{{ proto string dom_characterdata_substring_data(int offset, int count);
148 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-6531BCCF
149 Since:
150 */
PHP_FUNCTION(dom_characterdata_substring_data)151 PHP_FUNCTION(dom_characterdata_substring_data)
152 {
153 zval *id;
154 xmlChar *cur;
155 xmlChar *substring;
156 xmlNodePtr node;
157 zend_long offset, count;
158 int length;
159 dom_object *intern;
160
161 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Oll", &id, dom_characterdata_class_entry, &offset, &count) == FAILURE) {
162 return;
163 }
164
165 DOM_GET_OBJ(node, id, xmlNodePtr, intern);
166
167 cur = xmlNodeGetContent(node);
168 if (cur == NULL) {
169 RETURN_FALSE;
170 }
171
172 length = xmlUTF8Strlen(cur);
173
174 if (offset < 0 || count < 0 || ZEND_LONG_INT_OVFL(offset) || ZEND_LONG_INT_OVFL(count) || offset > length) {
175 xmlFree(cur);
176 php_dom_throw_error(INDEX_SIZE_ERR, dom_get_strict_error(intern->document));
177 RETURN_FALSE;
178 }
179
180 if ((offset + count) > length) {
181 count = length - offset;
182 }
183
184 substring = xmlUTF8Strsub(cur, (int)offset, (int)count);
185 xmlFree(cur);
186
187 if (substring) {
188 RETVAL_STRING((char *) substring);
189 xmlFree(substring);
190 } else {
191 RETVAL_EMPTY_STRING();
192 }
193 }
194 /* }}} end dom_characterdata_substring_data */
195
196 /* {{{ proto void dom_characterdata_append_data(string arg);
197 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-32791A2F
198 Since:
199 */
PHP_FUNCTION(dom_characterdata_append_data)200 PHP_FUNCTION(dom_characterdata_append_data)
201 {
202 zval *id;
203 xmlNode *nodep;
204 dom_object *intern;
205 char *arg;
206 size_t arg_len;
207
208 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os", &id, dom_characterdata_class_entry, &arg, &arg_len) == FAILURE) {
209 return;
210 }
211
212 DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
213 #if LIBXML_VERSION < 20627
214 /* Implement logic from libxml xmlTextConcat to add support for comments and PI */
215 if ((nodep->content == (xmlChar *) &(nodep->properties)) ||
216 ((nodep->doc != NULL) && (nodep->doc->dict != NULL) &&
217 xmlDictOwns(nodep->doc->dict, nodep->content))) {
218 nodep->content = xmlStrncatNew(nodep->content, arg, arg_len);
219 } else {
220 nodep->content = xmlStrncat(nodep->content, arg, arg_len);
221 }
222 nodep->properties = NULL;
223 #else
224 xmlTextConcat(nodep, (xmlChar *) arg, arg_len);
225 #endif
226 RETURN_TRUE;
227 }
228 /* }}} end dom_characterdata_append_data */
229
230 /* {{{ proto void dom_characterdata_insert_data(int offset, string arg);
231 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-3EDB695F
232 Since:
233 */
PHP_FUNCTION(dom_characterdata_insert_data)234 PHP_FUNCTION(dom_characterdata_insert_data)
235 {
236 zval *id;
237 xmlChar *cur, *first, *second;
238 xmlNodePtr node;
239 char *arg;
240 zend_long offset;
241 int length;
242 size_t arg_len;
243 dom_object *intern;
244
245 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Ols", &id, dom_characterdata_class_entry, &offset, &arg, &arg_len) == FAILURE) {
246 return;
247 }
248
249 DOM_GET_OBJ(node, id, xmlNodePtr, intern);
250
251 cur = xmlNodeGetContent(node);
252 if (cur == NULL) {
253 RETURN_FALSE;
254 }
255
256 length = xmlUTF8Strlen(cur);
257
258 if (offset < 0 || ZEND_LONG_INT_OVFL(offset) || offset > length) {
259 xmlFree(cur);
260 php_dom_throw_error(INDEX_SIZE_ERR, dom_get_strict_error(intern->document));
261 RETURN_FALSE;
262 }
263
264 first = xmlUTF8Strndup(cur, (int)offset);
265 second = xmlUTF8Strsub(cur, (int)offset, length - (int)offset);
266 xmlFree(cur);
267
268 xmlNodeSetContent(node, first);
269 xmlNodeAddContent(node, (xmlChar *) arg);
270 xmlNodeAddContent(node, second);
271
272 xmlFree(first);
273 xmlFree(second);
274
275 RETURN_TRUE;
276 }
277 /* }}} end dom_characterdata_insert_data */
278
279 /* {{{ proto void dom_characterdata_delete_data(int offset, int count);
280 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-7C603781
281 Since:
282 */
PHP_FUNCTION(dom_characterdata_delete_data)283 PHP_FUNCTION(dom_characterdata_delete_data)
284 {
285 zval *id;
286 xmlChar *cur, *substring, *second;
287 xmlNodePtr node;
288 zend_long offset, count;
289 int length;
290 dom_object *intern;
291
292 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Oll", &id, dom_characterdata_class_entry, &offset, &count) == FAILURE) {
293 return;
294 }
295
296 DOM_GET_OBJ(node, id, xmlNodePtr, intern);
297
298 cur = xmlNodeGetContent(node);
299 if (cur == NULL) {
300 RETURN_FALSE;
301 }
302
303 length = xmlUTF8Strlen(cur);
304
305 if (offset < 0 || count < 0 || ZEND_LONG_INT_OVFL(offset) || ZEND_LONG_INT_OVFL(count) || offset > length) {
306 xmlFree(cur);
307 php_dom_throw_error(INDEX_SIZE_ERR, dom_get_strict_error(intern->document));
308 RETURN_FALSE;
309 }
310
311 if (offset > 0) {
312 substring = xmlUTF8Strsub(cur, 0, (int)offset);
313 } else {
314 substring = NULL;
315 }
316
317 if ((offset + count) > length) {
318 count = length - offset;
319 }
320
321 second = xmlUTF8Strsub(cur, (int)offset + (int)count, length - (int)offset);
322 substring = xmlStrcat(substring, second);
323
324 xmlNodeSetContent(node, substring);
325
326 xmlFree(cur);
327 xmlFree(second);
328 xmlFree(substring);
329
330 RETURN_TRUE;
331 }
332 /* }}} end dom_characterdata_delete_data */
333
334 /* {{{ proto void dom_characterdata_replace_data(int offset, int count, string arg);
335 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-E5CBA7FB
336 Since:
337 */
PHP_FUNCTION(dom_characterdata_replace_data)338 PHP_FUNCTION(dom_characterdata_replace_data)
339 {
340 zval *id;
341 xmlChar *cur, *substring, *second = NULL;
342 xmlNodePtr node;
343 char *arg;
344 zend_long offset, count;
345 int length;
346 size_t arg_len;
347 dom_object *intern;
348
349 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Olls", &id, dom_characterdata_class_entry, &offset, &count, &arg, &arg_len) == FAILURE) {
350 return;
351 }
352
353 DOM_GET_OBJ(node, id, xmlNodePtr, intern);
354
355 cur = xmlNodeGetContent(node);
356 if (cur == NULL) {
357 RETURN_FALSE;
358 }
359
360 length = xmlUTF8Strlen(cur);
361
362 if (offset < 0 || count < 0 || ZEND_LONG_INT_OVFL(offset) || ZEND_LONG_INT_OVFL(count) || offset > length) {
363 xmlFree(cur);
364 php_dom_throw_error(INDEX_SIZE_ERR, dom_get_strict_error(intern->document));
365 RETURN_FALSE;
366 }
367
368 if (offset > 0) {
369 substring = xmlUTF8Strsub(cur, 0, (int)offset);
370 } else {
371 substring = NULL;
372 }
373
374 if ((offset + count) > length) {
375 count = length - offset;
376 }
377
378 if (offset < length) {
379 second = xmlUTF8Strsub(cur, (int)offset + count, length - (int)offset);
380 }
381
382 substring = xmlStrcat(substring, (xmlChar *) arg);
383 substring = xmlStrcat(substring, second);
384
385 xmlNodeSetContent(node, substring);
386
387 xmlFree(cur);
388 if (second) {
389 xmlFree(second);
390 }
391 xmlFree(substring);
392
393 RETURN_TRUE;
394 }
395 /* }}} end dom_characterdata_replace_data */
396
397 #endif
398
399 /*
400 * Local variables:
401 * tab-width: 4
402 * c-basic-offset: 4
403 * End:
404 * vim600: noet sw=4 ts=4 fdm=marker
405 * vim<600: noet sw=4 ts=4
406 */
407