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 /* $Id$ */
21
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #include "php.h"
27 #if HAVE_LIBXML && HAVE_DOM
28 #include "php_dom.h"
29
30
31 /* {{{ arginfo */
32 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_characterdata_substring_data, 0, 0, 2)
33 ZEND_ARG_INFO(0, offset)
34 ZEND_ARG_INFO(0, count)
35 ZEND_END_ARG_INFO();
36
37 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_characterdata_append_data, 0, 0, 1)
38 ZEND_ARG_INFO(0, arg)
39 ZEND_END_ARG_INFO();
40
41 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_characterdata_insert_data, 0, 0, 2)
42 ZEND_ARG_INFO(0, offset)
43 ZEND_ARG_INFO(0, arg)
44 ZEND_END_ARG_INFO();
45
46 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_characterdata_delete_data, 0, 0, 2)
47 ZEND_ARG_INFO(0, offset)
48 ZEND_ARG_INFO(0, count)
49 ZEND_END_ARG_INFO();
50
51 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_characterdata_replace_data, 0, 0, 3)
52 ZEND_ARG_INFO(0, offset)
53 ZEND_ARG_INFO(0, count)
54 ZEND_ARG_INFO(0, arg)
55 ZEND_END_ARG_INFO();
56 /* }}} */
57
58 /*
59 * class DOMCharacterData extends DOMNode
60 *
61 * URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-FF21A306
62 * Since:
63 */
64
65 const zend_function_entry php_dom_characterdata_class_functions[] = {
66 PHP_FALIAS(substringData, dom_characterdata_substring_data, arginfo_dom_characterdata_substring_data)
67 PHP_FALIAS(appendData, dom_characterdata_append_data, arginfo_dom_characterdata_append_data)
68 PHP_FALIAS(insertData, dom_characterdata_insert_data, arginfo_dom_characterdata_insert_data)
69 PHP_FALIAS(deleteData, dom_characterdata_delete_data, arginfo_dom_characterdata_delete_data)
70 PHP_FALIAS(replaceData, dom_characterdata_replace_data, arginfo_dom_characterdata_replace_data)
71 PHP_FE_END
72 };
73
74 /* {{{ data string
75 readonly=no
76 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-72AB8359
77 Since:
78 */
dom_characterdata_data_read(dom_object * obj,zval * retval)79 int dom_characterdata_data_read(dom_object *obj, zval *retval)
80 {
81 xmlNodePtr nodep = dom_object_get_node(obj);
82 xmlChar *content;
83
84 if (nodep == NULL) {
85 php_dom_throw_error(INVALID_STATE_ERR, 0);
86 return FAILURE;
87 }
88
89 if ((content = xmlNodeGetContent(nodep)) != NULL) {
90 ZVAL_STRING(retval, (char *) content);
91 xmlFree(content);
92 } else {
93 ZVAL_EMPTY_STRING(retval);
94 }
95
96 return SUCCESS;
97 }
98
dom_characterdata_data_write(dom_object * obj,zval * newval)99 int dom_characterdata_data_write(dom_object *obj, zval *newval)
100 {
101 xmlNode *nodep = dom_object_get_node(obj);
102 zend_string *str;
103
104 if (nodep == NULL) {
105 php_dom_throw_error(INVALID_STATE_ERR, 0);
106 return FAILURE;
107 }
108
109 str = zval_get_string(newval);
110
111 xmlNodeSetContentLen(nodep, (xmlChar *) ZSTR_VAL(str), ZSTR_LEN(str) + 1);
112
113 zend_string_release(str);
114 return SUCCESS;
115 }
116
117 /* }}} */
118
119 /* {{{ length long
120 readonly=yes
121 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-7D61178C
122 Since:
123 */
dom_characterdata_length_read(dom_object * obj,zval * retval)124 int dom_characterdata_length_read(dom_object *obj, zval *retval)
125 {
126 xmlNodePtr nodep = dom_object_get_node(obj);
127 xmlChar *content;
128 long length = 0;
129
130 if (nodep == NULL) {
131 php_dom_throw_error(INVALID_STATE_ERR, 0);
132 return FAILURE;
133 }
134
135 content = xmlNodeGetContent(nodep);
136
137 if (content) {
138 length = xmlUTF8Strlen(content);
139 xmlFree(content);
140 }
141
142 ZVAL_LONG(retval, length);
143
144 return SUCCESS;
145 }
146
147 /* }}} */
148
149 /* {{{ proto string dom_characterdata_substring_data(int offset, int count);
150 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-6531BCCF
151 Since:
152 */
PHP_FUNCTION(dom_characterdata_substring_data)153 PHP_FUNCTION(dom_characterdata_substring_data)
154 {
155 zval *id;
156 xmlChar *cur;
157 xmlChar *substring;
158 xmlNodePtr node;
159 zend_long offset, count;
160 int length;
161 dom_object *intern;
162
163 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Oll", &id, dom_characterdata_class_entry, &offset, &count) == FAILURE) {
164 return;
165 }
166
167 DOM_GET_OBJ(node, id, xmlNodePtr, intern);
168
169 cur = xmlNodeGetContent(node);
170 if (cur == NULL) {
171 RETURN_FALSE;
172 }
173
174 length = xmlUTF8Strlen(cur);
175
176 if (offset < 0 || count < 0 || ZEND_LONG_INT_OVFL(offset) || ZEND_LONG_INT_OVFL(count) || offset > length) {
177 xmlFree(cur);
178 php_dom_throw_error(INDEX_SIZE_ERR, dom_get_strict_error(intern->document));
179 RETURN_FALSE;
180 }
181
182 if ((offset + count) > length) {
183 count = length - offset;
184 }
185
186 substring = xmlUTF8Strsub(cur, (int)offset, (int)count);
187 xmlFree(cur);
188
189 if (substring) {
190 RETVAL_STRING((char *) substring);
191 xmlFree(substring);
192 } else {
193 RETVAL_EMPTY_STRING();
194 }
195 }
196 /* }}} end dom_characterdata_substring_data */
197
198 /* {{{ proto void dom_characterdata_append_data(string arg);
199 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-32791A2F
200 Since:
201 */
PHP_FUNCTION(dom_characterdata_append_data)202 PHP_FUNCTION(dom_characterdata_append_data)
203 {
204 zval *id;
205 xmlNode *nodep;
206 dom_object *intern;
207 char *arg;
208 size_t arg_len;
209
210 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os", &id, dom_characterdata_class_entry, &arg, &arg_len) == FAILURE) {
211 return;
212 }
213
214 DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
215 #if LIBXML_VERSION < 20627
216 /* Implement logic from libxml xmlTextConcat to add suport for comments and PI */
217 if ((nodep->content == (xmlChar *) &(nodep->properties)) ||
218 ((nodep->doc != NULL) && (nodep->doc->dict != NULL) &&
219 xmlDictOwns(nodep->doc->dict, nodep->content))) {
220 nodep->content = xmlStrncatNew(nodep->content, arg, arg_len);
221 } else {
222 nodep->content = xmlStrncat(nodep->content, arg, arg_len);
223 }
224 nodep->properties = NULL;
225 #else
226 xmlTextConcat(nodep, (xmlChar *) arg, arg_len);
227 #endif
228 RETURN_TRUE;
229 }
230 /* }}} end dom_characterdata_append_data */
231
232 /* {{{ proto void dom_characterdata_insert_data(int offset, string arg);
233 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-3EDB695F
234 Since:
235 */
PHP_FUNCTION(dom_characterdata_insert_data)236 PHP_FUNCTION(dom_characterdata_insert_data)
237 {
238 zval *id;
239 xmlChar *cur, *first, *second;
240 xmlNodePtr node;
241 char *arg;
242 zend_long offset;
243 int length;
244 size_t arg_len;
245 dom_object *intern;
246
247 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Ols", &id, dom_characterdata_class_entry, &offset, &arg, &arg_len) == FAILURE) {
248 return;
249 }
250
251 DOM_GET_OBJ(node, id, xmlNodePtr, intern);
252
253 cur = xmlNodeGetContent(node);
254 if (cur == NULL) {
255 RETURN_FALSE;
256 }
257
258 length = xmlUTF8Strlen(cur);
259
260 if (offset < 0 || ZEND_LONG_INT_OVFL(offset) || offset > length) {
261 xmlFree(cur);
262 php_dom_throw_error(INDEX_SIZE_ERR, dom_get_strict_error(intern->document));
263 RETURN_FALSE;
264 }
265
266 first = xmlUTF8Strndup(cur, (int)offset);
267 second = xmlUTF8Strsub(cur, (int)offset, length - (int)offset);
268 xmlFree(cur);
269
270 xmlNodeSetContent(node, first);
271 xmlNodeAddContent(node, (xmlChar *) arg);
272 xmlNodeAddContent(node, second);
273
274 xmlFree(first);
275 xmlFree(second);
276
277 RETURN_TRUE;
278 }
279 /* }}} end dom_characterdata_insert_data */
280
281 /* {{{ proto void dom_characterdata_delete_data(int offset, int count);
282 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-7C603781
283 Since:
284 */
PHP_FUNCTION(dom_characterdata_delete_data)285 PHP_FUNCTION(dom_characterdata_delete_data)
286 {
287 zval *id;
288 xmlChar *cur, *substring, *second;
289 xmlNodePtr node;
290 zend_long offset, count;
291 int length;
292 dom_object *intern;
293
294 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Oll", &id, dom_characterdata_class_entry, &offset, &count) == FAILURE) {
295 return;
296 }
297
298 DOM_GET_OBJ(node, id, xmlNodePtr, intern);
299
300 cur = xmlNodeGetContent(node);
301 if (cur == NULL) {
302 RETURN_FALSE;
303 }
304
305 length = xmlUTF8Strlen(cur);
306
307 if (offset < 0 || count < 0 || ZEND_LONG_INT_OVFL(offset) || ZEND_LONG_INT_OVFL(count) || offset > length) {
308 xmlFree(cur);
309 php_dom_throw_error(INDEX_SIZE_ERR, dom_get_strict_error(intern->document));
310 RETURN_FALSE;
311 }
312
313 if (offset > 0) {
314 substring = xmlUTF8Strsub(cur, 0, (int)offset);
315 } else {
316 substring = NULL;
317 }
318
319 if ((offset + count) > length) {
320 count = length - offset;
321 }
322
323 second = xmlUTF8Strsub(cur, (int)offset + (int)count, length - (int)offset);
324 substring = xmlStrcat(substring, second);
325
326 xmlNodeSetContent(node, substring);
327
328 xmlFree(cur);
329 xmlFree(second);
330 xmlFree(substring);
331
332 RETURN_TRUE;
333 }
334 /* }}} end dom_characterdata_delete_data */
335
336 /* {{{ proto void dom_characterdata_replace_data(int offset, int count, string arg);
337 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-E5CBA7FB
338 Since:
339 */
PHP_FUNCTION(dom_characterdata_replace_data)340 PHP_FUNCTION(dom_characterdata_replace_data)
341 {
342 zval *id;
343 xmlChar *cur, *substring, *second = NULL;
344 xmlNodePtr node;
345 char *arg;
346 zend_long offset, count;
347 int length;
348 size_t arg_len;
349 dom_object *intern;
350
351 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Olls", &id, dom_characterdata_class_entry, &offset, &count, &arg, &arg_len) == FAILURE) {
352 return;
353 }
354
355 DOM_GET_OBJ(node, id, xmlNodePtr, intern);
356
357 cur = xmlNodeGetContent(node);
358 if (cur == NULL) {
359 RETURN_FALSE;
360 }
361
362 length = xmlUTF8Strlen(cur);
363
364 if (offset < 0 || count < 0 || ZEND_LONG_INT_OVFL(offset) || ZEND_LONG_INT_OVFL(count) || offset > length) {
365 xmlFree(cur);
366 php_dom_throw_error(INDEX_SIZE_ERR, dom_get_strict_error(intern->document));
367 RETURN_FALSE;
368 }
369
370 if (offset > 0) {
371 substring = xmlUTF8Strsub(cur, 0, (int)offset);
372 } else {
373 substring = NULL;
374 }
375
376 if ((offset + count) > length) {
377 count = length - offset;
378 }
379
380 if (offset < length) {
381 second = xmlUTF8Strsub(cur, (int)offset + count, length - (int)offset);
382 }
383
384 substring = xmlStrcat(substring, (xmlChar *) arg);
385 substring = xmlStrcat(substring, second);
386
387 xmlNodeSetContent(node, substring);
388
389 xmlFree(cur);
390 if (second) {
391 xmlFree(second);
392 }
393 xmlFree(substring);
394
395 RETURN_TRUE;
396 }
397 /* }}} end dom_characterdata_replace_data */
398
399 #endif
400
401 /*
402 * Local variables:
403 * tab-width: 4
404 * c-basic-offset: 4
405 * End:
406 * vim600: noet sw=4 ts=4 fdm=marker
407 * vim<600: noet sw=4 ts=4
408 */
409