| 694 | #define TMP_TAG_END_LEN (sizeof(TMP_TAG_END_S) - 1) |
| 695 | |
| 696 | static int set_node_content_w_cdata(xmlNode *node, str new_content, |
| 697 | xmlDoc *xml_doc) |
| 698 | { |
| 699 | xmlNode *n, *tmp = NULL, *tmp_root; |
| 700 | xmlDoc *tmp_doc = NULL; |
| 701 | str tmp_doc_str = STR_NULL; |
| 702 | |
| 703 | /* remove all existing CDATA and text nodes */ |
| 704 | for (n = node->children; n; n = tmp) { |
| 705 | tmp = n->next; |
| 706 | |
| 707 | if (n->type == XML_TEXT_NODE || n->type == XML_CDATA_SECTION_NODE) { |
| 708 | xmlUnlinkNode(n); |
| 709 | xmlFreeNode(n); |
| 710 | } |
| 711 | } |
| 712 | |
| 713 | /* build a temporary XML doc just to help us parse the cdata sections and |
| 714 | * potentially extra text; then copy the corresponding nodes to the |
| 715 | * original tree */ |
| 716 | tmp_doc_str.len = new_content.len + TMP_TAG_LEN + TMP_TAG_END_LEN; |
| 717 | tmp_doc_str.s = pkg_malloc(tmp_doc_str.len); |
| 718 | if (!tmp_doc_str.s) { |
| 719 | LM_ERR("no more pkg memory\n"); |
| 720 | return -1; |
| 721 | } |
| 722 | |
| 723 | memcpy(tmp_doc_str.s, TMP_TAG_S, TMP_TAG_LEN); |
| 724 | memcpy(tmp_doc_str.s+TMP_TAG_LEN, new_content.s, new_content.len); |
| 725 | memcpy(tmp_doc_str.s+TMP_TAG_LEN+new_content.len, |
| 726 | TMP_TAG_END_S, TMP_TAG_END_LEN); |
| 727 | |
| 728 | tmp_doc = xmlParseMemory(tmp_doc_str.s, tmp_doc_str.len); |
| 729 | if (!tmp_doc) { |
| 730 | LM_ERR("Failed to parse xml block\n"); |
| 731 | goto error; |
| 732 | } |
| 733 | |
| 734 | tmp_root = xmlDocGetRootElement(tmp_doc); |
| 735 | for (n = tmp_root->children; n; n = n->next) { |
| 736 | if (n->type == XML_TEXT_NODE || n->type == XML_CDATA_SECTION_NODE) { |
| 737 | tmp = xmlDocCopyNode(n, xml_doc, 0); |
| 738 | if (!tmp) { |
| 739 | LM_ERR("Failed to copy node\n"); |
| 740 | goto error; |
| 741 | } |
| 742 | |
| 743 | if (!xmlAddChild(node, tmp)) { |
| 744 | LM_ERR("Unable to link copied node\n"); |
| 745 | goto error; |
| 746 | } |
| 747 | } |
| 748 | } |
| 749 | |
| 750 | xmlFreeDoc(tmp_doc); |
| 751 | pkg_free(tmp_doc_str.s); |
| 752 | |
| 753 | return 0; |