* xmlSetTreeDoc: * @tree: root of a subtree * @doc: new document * * This is an internal function which shouldn't be used. It is * invoked by functions like xmlAddChild, xmlAddSibling or * xmlReplaceNode. @tree must be the root node of an unlinked * subtree. * * Associate all nodes in a tree with a new document. * * Also copy strings from the old document's dictionary and * remove ID
| 2859 | * may be lost. |
| 2860 | */ |
| 2861 | int |
| 2862 | xmlSetTreeDoc(xmlNodePtr tree, xmlDocPtr doc) { |
| 2863 | int ret = 0; |
| 2864 | xmlDocPtr oldDoc; |
| 2865 | |
| 2866 | if ((tree == NULL) || (tree->type == XML_NAMESPACE_DECL)) |
| 2867 | return(0); |
| 2868 | oldDoc = tree->doc; |
| 2869 | if (oldDoc == doc) |
| 2870 | return(0); |
| 2871 | |
| 2872 | if (tree->type == XML_ELEMENT_NODE) { |
| 2873 | xmlAttrPtr prop = tree->properties; |
| 2874 | |
| 2875 | while (prop != NULL) { |
| 2876 | if (prop->children != NULL) { |
| 2877 | if (xmlSetListDoc(prop->children, doc) < 0) |
| 2878 | ret = -1; |
| 2879 | } |
| 2880 | |
| 2881 | if (xmlNodeSetDoc((xmlNodePtr) prop, doc) < 0) |
| 2882 | ret = -1; |
| 2883 | |
| 2884 | prop = prop->next; |
| 2885 | } |
| 2886 | } |
| 2887 | |
| 2888 | if ((tree->children != NULL) && |
| 2889 | (tree->type != XML_ENTITY_REF_NODE)) { |
| 2890 | if (xmlSetListDoc(tree->children, doc) < 0) |
| 2891 | ret = -1; |
| 2892 | } |
| 2893 | |
| 2894 | if (xmlNodeSetDoc(tree, doc) < 0) |
| 2895 | ret = -1; |
| 2896 | |
| 2897 | /* |
| 2898 | * Reconcile namespaces when moving between documents. |
| 2899 | * This prevents use-after-free when namespaces from the old |
| 2900 | * document are accessed after the old document is freed. |
| 2901 | */ |
| 2902 | if ((ret == 0) && (oldDoc != doc) && (tree->type == XML_ELEMENT_NODE)) { |
| 2903 | if (xmlReconciliateNs(doc, tree) < 0) { |
| 2904 | /* Reconciliation failed, but document was already changed */ |
| 2905 | ret = -1; |
| 2906 | } |
| 2907 | } |
| 2908 | |
| 2909 | return(ret); |
| 2910 | } |
| 2911 | |
| 2912 | /** |
| 2913 | * xmlSetListDoc: |
no test coverage detected