characterdata.c 10 KB

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