added a routine xmlStrncatNew to create a new string from 2 frags. added

* parser.c, include/libxml/parser.h: added a routine
  xmlStrncatNew to create a new string from 2 frags.
* tree.c: added code to check if node content is from
  dictionary before trying to change or concatenate.
diff --git a/ChangeLog b/ChangeLog
index 8f2f321..901f663 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Sun Jan  4 22:45:14 HKT 2004 William Brack <wbarck@mmm.com.hk>
+
+	* parser.c, include/libxml/parser.h: added a routine
+	  xmlStrncatNew to create a new string from 2 frags.
+	* tree.c: added code to check if node content is from
+	  dictionary before trying to change or concatenate.
+
 Sun Jan  4 08:57:51 HKT 2004 William Brack <wbrack@mmm.com.hk>
 
 	* xmlmemory.c: applied suggestion from Miloslav Trmac (see
diff --git a/include/libxml/parser.h b/include/libxml/parser.h
index c4b5ff3..d3c092c 100644
--- a/include/libxml/parser.h
+++ b/include/libxml/parser.h
@@ -861,6 +861,11 @@
 					 const xmlChar *add,
 					 int len);
 
+XMLPUBFUN xmlChar * XMLCALL	
+		xmlStrncatNew		(const xmlChar *str1,
+					 const xmlChar *str2,
+					 int len);
+
 XMLPUBFUN int XMLCALL	
 		xmlStrPrintf		(xmlChar *buf,
 					 int len,
diff --git a/parser.c b/parser.c
index e279102..1025900 100644
--- a/parser.c
+++ b/parser.c
@@ -2463,6 +2463,39 @@
 }
 
 /**
+ * xmlStrncatNew:
+ * @str1:  first xmlChar string
+ * @str2:  second xmlChar string
+ * @len:  the len of @str2
+ *
+ * same as xmlStrncat, but creates a new string.  The original
+ * two strings are not freed.
+ *
+ * Returns a new xmlChar * or NULL
+ */
+xmlChar *
+xmlStrncatNew(const xmlChar *str1, const xmlChar *str2, int len) {
+    int size;
+    xmlChar *ret;
+
+    if ((str2 == NULL) || (len == 0))
+        return(xmlStrdup(str1));
+    if (str1 == NULL)
+        return(xmlStrndup(str2, len));
+
+    size = xmlStrlen(str1);
+    ret = (xmlChar *) xmlMalloc((size + len + 1) * sizeof(xmlChar));
+    if (ret == NULL) {
+        xmlErrMemory(NULL, NULL);
+        return(xmlStrndup(str1, size));
+    }
+    memcpy(ret, str1, size * sizeof(xmlChar));
+    memcpy(&ret[size], str2, len * sizeof(xmlChar));
+    ret[size + len] = 0;
+    return(ret);
+}
+
+/**
  * xmlStrcat:
  * @cur:  the original xmlChar * array
  * @add:  the xmlChar * array added
diff --git a/tree.c b/tree.c
index d13fbcd..b804a98 100644
--- a/tree.c
+++ b/tree.c
@@ -5024,7 +5024,9 @@
         case XML_PI_NODE:
         case XML_COMMENT_NODE:
 	    if (cur->content != NULL) {
-		xmlFree(cur->content);
+	        if (!((cur->doc != NULL) && (cur->doc->dict != NULL) &&
+			xmlDictOwns(cur->doc->dict, cur->content)))
+		    xmlFree(cur->content);
 	    }	
 	    if (cur->children != NULL) xmlFreeNodeList(cur->children);
 	    cur->last = cur->children = NULL;
@@ -5172,6 +5174,12 @@
         case XML_COMMENT_NODE:
         case XML_NOTATION_NODE:
 	    if (content != NULL) {
+	        if ((cur->doc != NULL) && (cur->doc->dict != NULL) &&
+			    xmlDictOwns(cur->doc->dict, cur->content)) {
+		    cur->content =
+			    xmlStrncatNew(cur->content, content, len);
+		    break;
+		}
 		cur->content = xmlStrncat(cur->content, content, len);
             }
         case XML_DOCUMENT_NODE:
@@ -6362,7 +6370,13 @@
 #endif
         return(-1);
     }
-    node->content = xmlStrncat(node->content, content, len);
+    /* need to check if content is currently in the dictionary */
+    if ((node->doc != NULL) && (node->doc->dict != NULL) &&
+		xmlDictOwns(node->doc->dict, node->content)) {
+	node->content = xmlStrncatNew(node->content, content, len);
+    } else {
+        node->content = xmlStrncat(node->content, content, len);
+    }
     if (node->content == NULL)
         return(-1);
     return(0);