Jumbo patch, resync of W3C/Gnome CVS trees:
- uri.c tree.c SAX.c parser.c entities.c debugXML.c: finished
  the cleanup of the computation of URI references when seeking
  external entities. The URI reference string and the resulting
  URI are both stored now.
- parser.c HTMLparser.c valid.c nanoftp.c nanohttp.c xpath.c:
  large s(n)printf checks and cleanup from Denis Barbier
  <barbier@imacs.polytechnique.fr>
- xmlversion.h.in tree.h: couple of SGML declarations for a
  possible docbook module.
- result/VC/ : a couple of test output changed due to the change
  of the entities URI
Daniel
diff --git a/ChangeLog b/ChangeLog
index 3e0c193..cf13527 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+Sun Sep 10 17:53:48 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* uri.c tree.c SAX.c parser.c entities.c debugXML.c: finished
+	  the cleanup of the computation of URI references when seeking
+	  external entities. The URI reference string and the resulting
+	  URI are both stored now.
+	* parser.c HTMLparser.c valid.c nanoftp.c nanohttp.c xpath.c:
+	  large s(n)printf checks and cleanup from Denis Barbier
+	  <barbier@imacs.polytechnique.fr>
+	* xmlversion.h.in tree.h: couple of SGML declarations for a
+	  possible docbook module.
+	* result/VC/ : a couple of test output changed due to the change
+	  of the entities URI
+
 Sun Sep 10 15:59:58 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
 
 	* parser.h: added a _private field for linking user's data
diff --git a/HTMLparser.c b/HTMLparser.c
index b0b43bd..bbd2974 100644
--- a/HTMLparser.c
+++ b/HTMLparser.c
@@ -630,7 +630,7 @@
 int
 htmlCheckAutoClose(const xmlChar *newtag, const xmlChar *oldtag) {
     int i, index;
-    char **close;
+    char **close = NULL;
 
     if (htmlStartCloseIndexinitialized == 0) htmlInitAutoClose();
 
@@ -3535,6 +3535,10 @@
                       xmlMalloc(5 * sizeof(htmlParserInputPtr));
     if (ctxt->inputTab == NULL) {
         fprintf(stderr, "htmlInitParserCtxt: out of memory\n");
+	ctxt->inputNr = 0;
+	ctxt->inputMax = 0;
+	ctxt->input = NULL;
+	return;
     }
     ctxt->inputNr = 0;
     ctxt->inputMax = 5;
@@ -3546,12 +3550,35 @@
 
     /* Allocate the Node stack */
     ctxt->nodeTab = (htmlNodePtr *) xmlMalloc(10 * sizeof(htmlNodePtr));
+    if (ctxt->nodeTab == NULL) {
+        fprintf(stderr, "htmlInitParserCtxt: out of memory\n");
+	ctxt->nodeNr = 0;
+	ctxt->nodeMax = 0;
+	ctxt->node = NULL;
+	ctxt->inputNr = 0;
+	ctxt->inputMax = 0;
+	ctxt->input = NULL;
+	return;
+    }
     ctxt->nodeNr = 0;
     ctxt->nodeMax = 10;
     ctxt->node = NULL;
 
     /* Allocate the Name stack */
     ctxt->nameTab = (xmlChar **) xmlMalloc(10 * sizeof(xmlChar *));
+    if (ctxt->nameTab == NULL) {
+        fprintf(stderr, "htmlInitParserCtxt: out of memory\n");
+	ctxt->nameNr = 0;
+	ctxt->nameMax = 10;
+	ctxt->name = NULL;
+	ctxt->nodeNr = 0;
+	ctxt->nodeMax = 0;
+	ctxt->node = NULL;
+	ctxt->inputNr = 0;
+	ctxt->inputMax = 0;
+	ctxt->input = NULL;
+	return;
+    }
     ctxt->nameNr = 0;
     ctxt->nameMax = 10;
     ctxt->name = NULL;
diff --git a/HTMLtree.c b/HTMLtree.c
index d8c5dc6..2d3b8a4 100644
--- a/HTMLtree.c
+++ b/HTMLtree.c
@@ -181,12 +181,13 @@
 	return(-1);
 
     if (encoding != NULL) {
-#ifndef HAVE_SNPRINTF
+#ifdef HAVE_SNPRINTF
+	snprintf(newcontent, sizeof(newcontent), "text/html; charset=%s",
+                encoding);
+#else
 	sprintf(newcontent, "text/html; charset=%s", encoding);
-#else /* HAVE_SNPRINTF */
-	snprintf(newcontent, 99, "text/html; charset=%s", encoding);
-#endif /* HAVE_SNPRINTF */
-	newcontent[99] = 0;
+#endif
+	newcontent[sizeof(newcontent) - 1] = 0;
     }
 
     cur = doc->children;
diff --git a/SAX.c b/SAX.c
index 3a7d9a9..3d1475b 100644
--- a/SAX.c
+++ b/SAX.c
@@ -311,13 +311,26 @@
 resolveEntity(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
 {
     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+    xmlParserInputPtr ret;
+    char *URI;
+    const char *base = NULL;
+
+    if (ctxt->input != NULL)
+	base = ctxt->input->filename;
+    if (base == NULL)
+	base = ctxt->directory;
+
+    URI = xmlBuildURI(systemId, base);
 
 #ifdef DEBUG_SAX
     fprintf(stderr, "SAX.resolveEntity(%s, %s)\n", publicId, systemId);
 #endif
 
-    return(xmlLoadExternalEntity((const char *) systemId,
-				 (const char *) publicId, ctxt));
+    ret = xmlLoadExternalEntity((const char *) URI,
+				(const char *) publicId, ctxt);
+    if (URI != NULL)
+	xmlFree(URI);
+    return(ret);
 }
 
 /**
@@ -409,6 +422,18 @@
 	    (ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
 	    ctxt->sax->warning(ctxt, 
 	     "Entity(%s) already defined in the internal subset\n", name);
+	if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
+	    char *URI;
+	    const char *base = NULL;
+
+	    if (ctxt->input != NULL)
+		base = ctxt->input->filename;
+	    if (base == NULL)
+		base = ctxt->directory;
+	
+	    URI = xmlBuildURI(systemId, base);
+	    ent->URI = URI;
+	}
     } else if (ctxt->inSubset == 2) {
 	ent = xmlAddDtdEntity(ctxt->myDoc, name, type, publicId,
 		              systemId, content);
@@ -416,6 +441,18 @@
 	    (ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
 	    ctxt->sax->warning(ctxt, 
 	     "Entity(%s) already defined in the external subset\n", name);
+	if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
+	    char *URI;
+	    const char *base = NULL;
+
+	    if (ctxt->input != NULL)
+		base = ctxt->input->filename;
+	    if (base == NULL)
+		base = ctxt->directory;
+	
+	    URI = xmlBuildURI(systemId, base);
+	    ent->URI = URI;
+	}
     } else {
 	if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
 	    ctxt->sax->error(ctxt, 
@@ -1603,3 +1640,73 @@
     htmlDefaultSAXHandler.error = xmlParserError;
     htmlDefaultSAXHandler.fatalError = xmlParserError;
 }
+
+/*
+ * Default handler for HTML, builds the DOM tree
+ */
+xmlSAXHandler sgmlDefaultSAXHandler = {
+    internalSubset,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    getEntity,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    setDocumentLocator,
+    startDocument,
+    endDocument,
+    startElement,
+    endElement,
+    NULL,
+    characters,
+    ignorableWhitespace,
+    NULL,
+    comment,
+    xmlParserWarning,
+    xmlParserError,
+    xmlParserError,
+    getParameterEntity,
+    NULL,
+    NULL,
+};
+
+/**
+ * sgmlDefaultSAXHandlerInit:
+ *
+ * Initialize the default SAX handler
+ */
+void
+sgmlDefaultSAXHandlerInit(void)
+{
+    sgmlDefaultSAXHandler.internalSubset = internalSubset;
+    sgmlDefaultSAXHandler.externalSubset = NULL;
+    sgmlDefaultSAXHandler.isStandalone = NULL;
+    sgmlDefaultSAXHandler.hasInternalSubset = NULL;
+    sgmlDefaultSAXHandler.hasExternalSubset = NULL;
+    sgmlDefaultSAXHandler.resolveEntity = NULL;
+    sgmlDefaultSAXHandler.getEntity = getEntity;
+    sgmlDefaultSAXHandler.getParameterEntity = NULL;
+    sgmlDefaultSAXHandler.entityDecl = NULL;
+    sgmlDefaultSAXHandler.attributeDecl = NULL;
+    sgmlDefaultSAXHandler.elementDecl = NULL;
+    sgmlDefaultSAXHandler.notationDecl = NULL;
+    sgmlDefaultSAXHandler.unparsedEntityDecl = NULL;
+    sgmlDefaultSAXHandler.setDocumentLocator = setDocumentLocator;
+    sgmlDefaultSAXHandler.startDocument = startDocument;
+    sgmlDefaultSAXHandler.endDocument = endDocument;
+    sgmlDefaultSAXHandler.startElement = startElement;
+    sgmlDefaultSAXHandler.endElement = endElement;
+    sgmlDefaultSAXHandler.reference = NULL;
+    sgmlDefaultSAXHandler.characters = characters;
+    sgmlDefaultSAXHandler.cdataBlock = NULL;
+    sgmlDefaultSAXHandler.ignorableWhitespace = ignorableWhitespace;
+    sgmlDefaultSAXHandler.processingInstruction = NULL;
+    sgmlDefaultSAXHandler.comment = comment;
+    sgmlDefaultSAXHandler.warning = xmlParserWarning;
+    sgmlDefaultSAXHandler.error = xmlParserError;
+    sgmlDefaultSAXHandler.fatalError = xmlParserError;
+}
diff --git a/SAX.h b/SAX.h
index 3c0f4cb..5825793 100644
--- a/SAX.h
+++ b/SAX.h
@@ -109,6 +109,7 @@
 
 void		xmlDefaultSAXHandlerInit	(void);
 void		htmlDefaultSAXHandlerInit	(void);
+void		sgmlDefaultSAXHandlerInit	(void);
 #ifdef __cplusplus
 }
 #endif
diff --git a/debugXML.c b/debugXML.c
index ddce5c5..e0c41f9 100644
--- a/debugXML.c
+++ b/debugXML.c
@@ -249,11 +249,11 @@
 	    break;
     }
     if (elem->content != NULL) {
-	char buf[1001];
+	char buf[5001];
 
 	buf[0] = 0;
 	xmlSprintfElementContent(buf, elem->content, 1);
-	buf[1000] = 0;
+	buf[5000] = 0;
 	fprintf(output, "%s", buf);
     }
     printf("\n");
@@ -325,15 +325,19 @@
     }
     if (ent->ExternalID) {
         fprintf(output, shift);
-        fprintf(output, "ExternalID=%s\n", ent->ExternalID);
+        fprintf(output, " ExternalID=%s\n", ent->ExternalID);
     }
     if (ent->SystemID) {
         fprintf(output, shift);
-        fprintf(output, "SystemID=%s\n", ent->SystemID);
+        fprintf(output, " SystemID=%s\n", ent->SystemID);
+    }
+    if (ent->URI != NULL) {
+        fprintf(output, shift);
+        fprintf(output, " URI=%s\n", ent->URI);
     }
     if (ent->content) {
         fprintf(output, shift);
-	fprintf(output, "content=");
+	fprintf(output, " content=");
 	xmlDebugDumpString(output, ent->content);
 	fprintf(output, "\n");
     }
@@ -434,6 +438,10 @@
         fprintf(output, shift);
         fprintf(output, "SystemID=%s\n", ent->SystemID);
     }
+    if (ent->URI) {
+        fprintf(output, shift);
+        fprintf(output, "URI=%s\n", ent->URI);
+    }
     if (ent->content) {
         fprintf(output, shift);
 	fprintf(output, "content=");
@@ -618,7 +626,7 @@
 
 void xmlDebugDumpNode(FILE *output, xmlNodePtr node, int depth) {
     xmlDebugDumpOneNode(output, node, depth);
-    if (node->children != NULL)
+    if ((node->children != NULL) && (node->type != XML_ENTITY_REF_NODE))
 	xmlDebugDumpNodeList(output, node->children, depth + 1);
 }
 
@@ -695,6 +703,11 @@
         xmlDebugDumpString(output, doc->encoding);
 	fprintf(output, "\n");
     }
+    if (doc->URL != NULL) {
+	fprintf(output, "URL=");
+        xmlDebugDumpString(output, doc->URL);
+	fprintf(output, "\n");
+    }
     if (doc->standalone)
         fprintf(output, "standalone=true\n");
     if (doc->oldNs != NULL) 
@@ -714,6 +727,47 @@
         xmlDebugDumpNodeList(output, doc->children, 1);
 }    
 
+void xmlDebugDumpDTD(FILE *output, xmlDtdPtr dtd) {
+    if (dtd == NULL)
+	return;
+    if (dtd->type != XML_DTD_NODE) {
+	fprintf(output, "PBM: not a DTD\n");
+	return;
+    }
+    if (dtd->name != NULL)
+	fprintf(output, "DTD(%s)", dtd->name);
+    else
+	fprintf(output, "DTD");
+    if (dtd->ExternalID != NULL)
+	fprintf(output, ", PUBLIC %s", dtd->ExternalID);
+    if (dtd->SystemID != NULL)
+	fprintf(output, ", SYSTEM %s", dtd->SystemID);
+    fprintf(output, "\n");
+    /*
+     * Do a bit of checking
+     */
+    if ((dtd->parent != NULL) && (dtd->doc != dtd->parent->doc))
+	fprintf(output, "PBM: Dtd doc differs from parent's one\n");
+    if (dtd->prev == NULL) {
+	if ((dtd->parent != NULL) && (dtd->parent->children != (xmlNodePtr)dtd))
+	    fprintf(output, "PBM: Dtd has no prev and not first of list\n");
+    } else {
+	if (dtd->prev->next != (xmlNodePtr) dtd)
+	    fprintf(output, "PBM: Dtd prev->next : back link wrong\n");
+    }
+    if (dtd->next == NULL) {
+	if ((dtd->parent != NULL) && (dtd->parent->last != (xmlNodePtr) dtd))
+	    fprintf(output, "PBM: Dtd has no next and not last of list\n");
+    } else {
+	if (dtd->next->prev != (xmlNodePtr) dtd)
+	    fprintf(output, "PBM: Dtd next->prev : forward link wrong\n");
+    }
+    if (dtd->children == NULL)
+	fprintf(output, "    DTD is empty\n");
+    else
+        xmlDebugDumpNodeList(output, dtd->children, 1);
+}
+
 void xmlDebugDumpEntities(FILE *output, xmlDocPtr doc) {
     int i;
     xmlEntityPtr cur;
@@ -1456,9 +1510,29 @@
 	    next = cur->parent;
 	}
 	if (occur == 0)
+#ifdef HAVE_SNPRINTF
+	    snprintf(buf, sizeof(buf), "%c%s%s", sep, name, buffer);
+#else
 	    sprintf(buf, "%c%s%s", sep, name, buffer);
-	else
+#endif
+        else
+#ifdef HAVE_SNPRINTF
+	    snprintf(buf, sizeof(buf), "%c%s[%d]%s",
+                    sep, name, occur, buffer);
+#else
 	    sprintf(buf, "%c%s[%d]%s", sep, name, occur, buffer);
+#endif
+        buf[sizeof(buf) - 1] = 0;
+        /*
+         * This test prevents buffer overflow, because this routine
+         * is only called by xmlShell, in which the second argument is
+         * 500 chars long.
+         * It is a dirty hack before a cleaner solution is found.
+         * Documentation should mention that the second argument must
+         * be at least 500 chars long, and could be stripped if too long.
+         */
+        if (strlen(buffer) + strlen(buf) > 499)
+           break;
 	strcpy(buffer, buf);
         cur = next;
     } while (cur != NULL);
@@ -1516,9 +1590,14 @@
         if (ctxt->node == (xmlNodePtr) ctxt->doc)
 	    sprintf(prompt, "%s > ", "/");
 	else if (ctxt->node->name)
-	    sprintf(prompt, "%s > ", ctxt->node->name);
-	else
+#ifdef HAVE_SNPRINTF
+	    snprintf(prompt, sizeof(prompt), "%s > ", ctxt->node->name);
+#else
+	    sprintf(buf, "%s > ", ctxt->node->name);
+#endif
+        else
 	    sprintf(prompt, "? > ");
+        prompt[sizeof(prompt) - 1] = 0;
 
         cmdline = ctxt->input(prompt);
         if (cmdline == NULL) break;
diff --git a/debugXML.h b/debugXML.h
index 3138469..4a55fa8 100644
--- a/debugXML.h
+++ b/debugXML.h
@@ -42,6 +42,8 @@
 				 xmlDocPtr doc);
 void	xmlDebugDumpDocument	(FILE *output,
 				 xmlDocPtr doc);
+void	xmlDebugDumpDTD		(FILE *output,
+				 xmlDtdPtr doc);
 void	xmlDebugDumpEntities	(FILE *output,
 				 xmlDocPtr doc);
 void	xmlLsOneNode		(FILE *output,
diff --git a/entities.c b/entities.c
index 63ebda7..5facf3b 100644
--- a/entities.c
+++ b/entities.c
@@ -76,6 +76,8 @@
         xmlFree((char *) entity->ExternalID);
     if (entity->SystemID != NULL)
         xmlFree((char *) entity->SystemID);
+    if (entity->URI != NULL)
+        xmlFree((char *) entity->URI);
     if (entity->content != NULL)
         xmlFree((char *) entity->content);
     if (entity->orig != NULL)
@@ -198,6 +200,8 @@
         ret->length = 0;
         ret->content = NULL;
     }
+    ret->URI = NULL; /* to be computed by the layer knowing
+			the defining entity */
     ret->orig = NULL;
     table->nb_entities++;
 
@@ -590,8 +594,6 @@
     xmlEntitiesTablePtr table;
     xmlEntityPtr ret;
 
-    if (doc == NULL)
-	return(NULL);
     if ((doc->intSubset != NULL) && (doc->intSubset->entities != NULL)) {
 	table = (xmlEntitiesTablePtr) doc->intSubset->entities;
 	ret = xmlGetEntityFromTable(table, name, 1);
@@ -619,8 +621,6 @@
 xmlGetDtdEntity(xmlDocPtr doc, const xmlChar *name) {
     xmlEntitiesTablePtr table;
 
-    if (doc == NULL)
-	return(NULL);
     if ((doc->extSubset != NULL) && (doc->extSubset->entities != NULL)) {
 	table = (xmlEntitiesTablePtr) doc->extSubset->entities;
 	return(xmlGetEntityFromTable(table, name, 0));
@@ -783,11 +783,13 @@
 #ifndef USE_UTF_8
 	} else if ((sizeof(xmlChar) == 1) && (*cur >= 0x80)) {
 	    char buf[10], *ptr;
+
 #ifdef HAVE_SNPRINTF
-	    snprintf(buf, 9, "&#%d;", *cur);
+	    snprintf(buf, sizeof(buf), "&#%d;", *cur);
 #else
 	    sprintf(buf, "&#%d;", *cur);
 #endif
+            buf[sizeof(buf) - 1] = 0;
             ptr = buf;
 	    while (*ptr != 0) *out++ = *ptr++;
 #endif
@@ -795,10 +797,11 @@
 	    char buf[10], *ptr;
 
 #ifdef HAVE_SNPRINTF
-	    snprintf(buf, 9, "&#%d;", *cur);
+	    snprintf(buf, sizeof(buf), "&#%d;", *cur);
 #else
 	    sprintf(buf, "&#%d;", *cur);
 #endif
+            buf[sizeof(buf) - 1] = 0;
             ptr = buf;
 	    while (*ptr != 0) *out++ = *ptr++;
 	}
@@ -918,9 +921,15 @@
 	} else if (*cur >= 0x80) {
 	    if ((doc->encoding != NULL) || (html)) {
 		/*
-		 * TODO !!!
+		 * Bjørn Reese <br@sseusa.com> provided the patch
+	        xmlChar xc;
+	        xc = (*cur & 0x3F) << 6;
+	        if (cur[1] != 0) {
+		    xc += *(++cur) & 0x3F;
+		    *out++ = xc;
+	        } else
 		 */
-		*out++ = *cur;
+		    *out++ = *cur;
 	    } else {
 		/*
 		 * We assume we have UTF-8 input.
@@ -933,10 +942,11 @@
 			    "xmlEncodeEntitiesReentrant : input not UTF-8\n");
 		    doc->encoding = xmlStrdup(BAD_CAST "ISO-8859-1");
 #ifdef HAVE_SNPRINTF
-		    snprintf(buf, 9, "&#%d;", *cur);
+		    snprintf(buf, sizeof(buf), "&#%d;", *cur);
 #else
 		    sprintf(buf, "&#%d;", *cur);
 #endif
+		    buf[sizeof(buf) - 1] = 0;
 		    ptr = buf;
 		    while (*ptr != 0) *out++ = *ptr++;
 		    continue;
@@ -967,11 +977,11 @@
 			"xmlEncodeEntitiesReentrant : char out of range\n");
 		    doc->encoding = xmlStrdup(BAD_CAST "ISO-8859-1");
 #ifdef HAVE_SNPRINTF
-		    snprintf(buf, 9, "&#%d;", *cur);
+		    snprintf(buf, sizeof(buf), "&#%d;", *cur);
 #else
 		    sprintf(buf, "&#%d;", *cur);
 #endif
-		    buf[9] = 0;
+		    buf[sizeof(buf) - 1] = 0;
 		    ptr = buf;
 		    while (*ptr != 0) *out++ = *ptr++;
 		    cur++;
@@ -981,11 +991,11 @@
 		 * We could do multiple things here. Just save as a char ref
 		 */
 #ifdef HAVE_SNPRINTF
-		snprintf(buf, 9, "&#x%X;", val);
+		snprintf(buf, sizeof(buf), "&#x%X;", val);
 #else
 		sprintf(buf, "&#x%X;", val);
 #endif
-		buf[9] = 0;
+		buf[sizeof(buf) - 1] = 0;
 		ptr = buf;
 		while (*ptr != 0) *out++ = *ptr++;
 		cur += l;
@@ -995,11 +1005,11 @@
 	    char buf[10], *ptr;
 
 #ifdef HAVE_SNPRINTF
-	    snprintf(buf, 9, "&#%d;", *cur);
+	    snprintf(buf, sizeof(buf), "&#%d;", *cur);
 #else
 	    sprintf(buf, "&#%d;", *cur);
 #endif
-	    buf[9] = 0;
+	    buf[sizeof(buf) - 1] = 0;
             ptr = buf;
 	    while (*ptr != 0) *out++ = *ptr++;
 	}
diff --git a/entities.h b/entities.h
index e393042..e5bcc1b 100644
--- a/entities.h
+++ b/entities.h
@@ -55,6 +55,7 @@
     const xmlChar      *SystemID;	/* URI for a SYSTEM or PUBLIC Entity */
 
     struct _xmlEntity     *nexte;	/* next entity in the hash table */
+    const xmlChar           *URI;	/* the full URI as computed */
 
 #ifdef WITH_EXTRA_ENT_DETECT
     /* Referenced entities name stack */
diff --git a/error.c b/error.c
index 4a124db..b51aebe 100644
--- a/error.c
+++ b/error.c
@@ -87,28 +87,32 @@
 xmlParserError(void *ctx, const char *msg, ...)
 {
     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-    xmlParserInputPtr input;
+    xmlParserInputPtr input = NULL;
     xmlParserInputPtr cur = NULL;
     va_list args;
 
-    input = ctxt->input;
-    if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
-	cur = input;
-        input = ctxt->inputTab[ctxt->inputNr - 2];
+    if (ctxt != NULL) {
+	input = ctxt->input;
+	if ((input != NULL) && (input->filename == NULL) &&
+	    (ctxt->inputNr > 1)) {
+	    cur = input;
+	    input = ctxt->inputTab[ctxt->inputNr - 2];
+	}
+	xmlParserPrintFileInfo(input);
     }
-        
-    xmlParserPrintFileInfo(input);
 
     fprintf(stderr, "error: ");
     va_start(args, msg);
     vfprintf(stderr, msg, args);
     va_end(args);
 
-    xmlParserPrintFileContext(input);
-    if (cur != NULL) {
-        xmlParserPrintFileInfo(cur);
-	fprintf(stderr, "\n");
-	xmlParserPrintFileContext(cur);
+    if (ctxt != NULL) {
+	xmlParserPrintFileContext(input);
+	if (cur != NULL) {
+	    xmlParserPrintFileInfo(cur);
+	    fprintf(stderr, "\n");
+	    xmlParserPrintFileContext(cur);
+	}
     }
 }
 
@@ -125,29 +129,32 @@
 xmlParserWarning(void *ctx, const char *msg, ...)
 {
     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-    xmlParserInputPtr input;
+    xmlParserInputPtr input = NULL;
     xmlParserInputPtr cur = NULL;
     va_list args;
 
-    input = ctxt->input;
-    if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
-	cur = input;
-        input = ctxt->inputTab[ctxt->inputNr - 2];
+    if (ctxt != NULL) {
+	input = ctxt->input;
+	if ((input != NULL) && (input->filename == NULL) &&
+	    (ctxt->inputNr > 1)) {
+	    cur = input;
+	    input = ctxt->inputTab[ctxt->inputNr - 2];
+	}
+	xmlParserPrintFileInfo(input);
     }
         
-
-    xmlParserPrintFileInfo(input);
-        
     fprintf(stderr, "warning: ");
     va_start(args, msg);
     vfprintf(stderr, msg, args);
     va_end(args);
 
-    xmlParserPrintFileContext(input);
-    if (cur != NULL) {
-        xmlParserPrintFileInfo(cur);
-	fprintf(stderr, "\n");
-	xmlParserPrintFileContext(cur);
+    if (ctxt != NULL) {
+	xmlParserPrintFileContext(input);
+	if (cur != NULL) {
+	    xmlParserPrintFileInfo(cur);
+	    fprintf(stderr, "\n");
+	    xmlParserPrintFileContext(cur);
+	}
     }
 }
 
@@ -164,21 +171,25 @@
 xmlParserValidityError(void *ctx, const char *msg, ...)
 {
     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-    xmlParserInputPtr input;
+    xmlParserInputPtr input = NULL;
     va_list args;
 
-    input = ctxt->input;
-    if ((input->filename == NULL) && (ctxt->inputNr > 1))
-        input = ctxt->inputTab[ctxt->inputNr - 2];
-        
-    xmlParserPrintFileInfo(input);
+    if (ctxt != NULL) {
+	input = ctxt->input;
+	if ((input->filename == NULL) && (ctxt->inputNr > 1))
+	    input = ctxt->inputTab[ctxt->inputNr - 2];
+	    
+	xmlParserPrintFileInfo(input);
+    }
 
     fprintf(stderr, "validity error: ");
     va_start(args, msg);
     vfprintf(stderr, msg, args);
     va_end(args);
 
-    xmlParserPrintFileContext(input);
+    if (ctxt != NULL) {
+	xmlParserPrintFileContext(input);
+    }
 }
 
 /**
@@ -194,20 +205,24 @@
 xmlParserValidityWarning(void *ctx, const char *msg, ...)
 {
     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-    xmlParserInputPtr input;
+    xmlParserInputPtr input = NULL;
     va_list args;
 
-    input = ctxt->input;
-    if ((input->filename == NULL) && (ctxt->inputNr > 1))
-        input = ctxt->inputTab[ctxt->inputNr - 2];
+    if (ctxt != NULL) {
+	input = ctxt->input;
+	if ((input->filename == NULL) && (ctxt->inputNr > 1))
+	    input = ctxt->inputTab[ctxt->inputNr - 2];
 
-    xmlParserPrintFileInfo(input);
+	xmlParserPrintFileInfo(input);
+    }
         
     fprintf(stderr, "validity warning: ");
     va_start(args, msg);
     vfprintf(stderr, msg, args);
     va_end(args);
 
-    xmlParserPrintFileContext(input);
+    if (ctxt != NULL) {
+	xmlParserPrintFileContext(input);
+    }
 }
 
diff --git a/include/libxml/SAX.h b/include/libxml/SAX.h
index 3c0f4cb..5825793 100644
--- a/include/libxml/SAX.h
+++ b/include/libxml/SAX.h
@@ -109,6 +109,7 @@
 
 void		xmlDefaultSAXHandlerInit	(void);
 void		htmlDefaultSAXHandlerInit	(void);
+void		sgmlDefaultSAXHandlerInit	(void);
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/libxml/debugXML.h b/include/libxml/debugXML.h
index 3138469..4a55fa8 100644
--- a/include/libxml/debugXML.h
+++ b/include/libxml/debugXML.h
@@ -42,6 +42,8 @@
 				 xmlDocPtr doc);
 void	xmlDebugDumpDocument	(FILE *output,
 				 xmlDocPtr doc);
+void	xmlDebugDumpDTD		(FILE *output,
+				 xmlDtdPtr doc);
 void	xmlDebugDumpEntities	(FILE *output,
 				 xmlDocPtr doc);
 void	xmlLsOneNode		(FILE *output,
diff --git a/include/libxml/entities.h b/include/libxml/entities.h
index e393042..e5bcc1b 100644
--- a/include/libxml/entities.h
+++ b/include/libxml/entities.h
@@ -55,6 +55,7 @@
     const xmlChar      *SystemID;	/* URI for a SYSTEM or PUBLIC Entity */
 
     struct _xmlEntity     *nexte;	/* next entity in the hash table */
+    const xmlChar           *URI;	/* the full URI as computed */
 
 #ifdef WITH_EXTRA_ENT_DETECT
     /* Referenced entities name stack */
diff --git a/include/libxml/tree.h b/include/libxml/tree.h
index a3ae15f..e4cf730 100644
--- a/include/libxml/tree.h
+++ b/include/libxml/tree.h
@@ -41,7 +41,12 @@
     XML_DTD_NODE=		14,
     XML_ELEMENT_DECL=		15,
     XML_ATTRIBUTE_DECL=		16,
+#ifdef LIBXML_SGML_ENABLED
+    XML_ENTITY_DECL=		17,
+    XML_SGML_DOCUMENT_NODE=	18
+#else
     XML_ENTITY_DECL=		17
+#endif
 } xmlElementType;
 
 /*
diff --git a/include/libxml/xmlIO.h b/include/libxml/xmlIO.h
index b966c4a..6ef91fd 100644
--- a/include/libxml/xmlIO.h
+++ b/include/libxml/xmlIO.h
@@ -37,7 +37,7 @@
     
     xmlCharEncodingHandlerPtr encoder; /* I18N conversions to UTF-8 */
     
-    xmlBufferPtr buffer;    /* Local buffer encoded in UTF-8 or ISOLatin */
+    xmlBufferPtr buffer;    /* Local buffer encoded in UTF-8 */
     xmlBufferPtr raw;       /* if encoder != NULL buffer for raw input */
 };
 
diff --git a/include/libxml/xmlversion.h.in b/include/libxml/xmlversion.h.in
index 664d89d..c0544e6 100644
--- a/include/libxml/xmlversion.h.in
+++ b/include/libxml/xmlversion.h.in
@@ -50,6 +50,15 @@
 #endif
 
 /*
+ * Whether the Docbook support is configured in
+#if @WITH_SGML@
+#define LIBXML_SGML_ENABLED
+#else
+#define LIBXML_SGML_DISABLED
+#endif
+ */
+
+/*
  * Whether XPath is configured in
  */
 #if @WITH_XPATH@
diff --git a/nanoftp.c b/nanoftp.c
index e009402..55ccb3a 100644
--- a/nanoftp.c
+++ b/nanoftp.c
@@ -731,17 +731,15 @@
     int res;
 
     if (ctxt->user == NULL)
-#ifndef HAVE_SNPRINTF
-	len = sprintf(buf, "USER anonymous\r\n");
-#else /* HAVE_SNPRINTF */
-	len = snprintf(buf, sizeof(buf), "USER anonymous\r\n");
-#endif /* HAVE_SNPRINTF */
+	sprintf(buf, "USER anonymous\r\n");
     else
-#ifndef HAVE_SNPRINTF
-	len = sprintf(buf, "USER %s\r\n", ctxt->user);
-#else /* HAVE_SNPRINTF */
-	len = snprintf(buf, sizeof(buf), "USER %s\r\n", ctxt->user);
-#endif /* HAVE_SNPRINTF */
+#ifdef HAVE_SNPRINTF
+	snprintf(buf, sizeof(buf), "USER %s\r\n", ctxt->user);
+#else
+	sprintf(buf, "USER %s\r\n", ctxt->user);
+#endif
+    buf[sizeof(buf) - 1] = 0;
+    len = strlen(buf);
 #ifdef DEBUG_FTP
     printf(buf);
 #endif
@@ -762,17 +760,19 @@
     int res;
 
     if (ctxt->passwd == NULL)
-#ifndef HAVE_SNPRINTF
-	len = sprintf(buf, "PASS libxml@%s\r\n", hostname);
-#else /* HAVE_SNPRINTF */
-	len = snprintf(buf, sizeof(buf), "PASS libxml@%s\r\n", hostname);
-#endif /* HAVE_SNPRINTF */
+#ifdef HAVE_SNPRINTF
+	snprintf(buf, sizeof(buf), "PASS libxml@%s\r\n", hostname);
+#else
+	sprintf(buf, "PASS libxml@%s\r\n", hostname);
+#endif
     else
-#ifndef HAVE_SNPRINTF
-	len = sprintf(buf, "PASS %s\r\n", ctxt->passwd);
-#else /* HAVE_SNPRINTF */
-	len = snprintf(buf, sizeof(buf), "PASS %s\r\n", ctxt->passwd);
-#endif /* HAVE_SNPRINTF */
+#ifdef HAVE_SNPRINTF
+	snprintf(buf, sizeof(buf), "PASS %s\r\n", ctxt->passwd);
+#else
+	sprintf(buf, "PASS %s\r\n", ctxt->passwd);
+#endif
+    buf[sizeof(buf) - 1] = 0;
+    len = strlen(buf);
 #ifdef DEBUG_FTP
     printf(buf);
 #endif
@@ -798,11 +798,8 @@
     int len;
     int res;
 
-#ifndef HAVE_SNPRINTF
-    len = sprintf(buf, "QUIT\r\n");
-#else /* HAVE_SNPRINTF */
-    len = snprintf(buf, sizeof(buf), "QUIT\r\n");
-#endif /* HAVE_SNPRINTF */
+    sprintf(buf, "QUIT\r\n");
+    len = strlen(buf);
 #ifdef DEBUG_FTP
     printf(buf);
 #endif
@@ -922,11 +919,13 @@
 	    /*
 	     * We need proxy auth
 	     */
-#ifndef HAVE_SNPRINTF
-	    len = sprintf(buf, "USER %s\r\n", proxyUser);
-#else /* HAVE_SNPRINTF */
-	    len = snprintf(buf, sizeof(buf), "USER %s\r\n", proxyUser);
-#endif /* HAVE_SNPRINTF */
+#ifdef HAVE_SNPRINTF
+	    snprintf(buf, sizeof(buf), "USER %s\r\n", proxyUser);
+#else
+	    sprintf(buf, "USER %s\r\n", proxyUser);
+#endif
+            buf[sizeof(buf) - 1] = 0;
+            len = strlen(buf);
 #ifdef DEBUG_FTP
 	    printf(buf);
 #endif
@@ -943,19 +942,20 @@
 			break;
 		case 3:
 		    if (proxyPasswd != NULL)
-#ifndef HAVE_SNPRINTF
-			len = sprintf(buf, "PASS %s\r\n", proxyPasswd);
-#else /* HAVE_SNPRINTF */
-			len = snprintf(buf, sizeof(buf), "PASS %s\r\n", proxyPasswd);
-#endif /* HAVE_SNPRINTF */
+#ifdef HAVE_SNPRINTF
+			snprintf(buf, sizeof(buf), "PASS %s\r\n", proxyPasswd);
+#else
+			sprintf(buf, "PASS %s\r\n", proxyPasswd);
+#endif
 		    else
-#ifndef HAVE_SNPRINTF
-			len = sprintf(buf, "PASS libxml@%s\r\n",
+#ifdef HAVE_SNPRINTF
+			snprintf(buf, sizeof(buf), "PASS libxml@%s\r\n",
 			               hostname);
-#else /* HAVE_SNPRINTF */
-			len = snprintf(buf, sizeof(buf), "PASS libxml@%s\r\n",
-			               hostname);
-#endif /* HAVE_SNPRINTF */
+#else
+			sprintf(buf, "PASS libxml@%s\r\n", hostname);
+#endif
+                    buf[sizeof(buf) - 1] = 0;
+                    len = strlen(buf);
 #ifdef DEBUG_FTP
 		    printf(buf);
 #endif
@@ -993,11 +993,13 @@
 		/* we will try in seqence */
 	    case 1:
 		/* Using SITE command */
-#ifndef HAVE_SNPRINTF
-		len = sprintf(buf, "SITE %s\r\n", ctxt->hostname);
-#else /* HAVE_SNPRINTF */
-		len = snprintf(buf, sizeof(buf), "SITE %s\r\n", ctxt->hostname);
-#endif /* HAVE_SNPRINTF */
+#ifdef HAVE_SNPRINTF
+		snprintf(buf, sizeof(buf), "SITE %s\r\n", ctxt->hostname);
+#else
+		sprintf(buf, "SITE %s\r\n", ctxt->hostname);
+#endif
+                buf[sizeof(buf) - 1] = 0;
+                len = strlen(buf);
 #ifdef DEBUG_FTP
 		printf(buf);
 #endif
@@ -1021,19 +1023,22 @@
 	    case 2:
 		/* USER user@host command */
 		if (ctxt->user == NULL)
-#ifndef HAVE_SNPRINTF
-		    len = sprintf(buf, "USER anonymous@%s\r\n",
-#else /* HAVE_SNPRINTF */
-		    len = snprintf(buf, sizeof(buf), "USER anonymous@%s\r\n",
-#endif /* HAVE_SNPRINTF */
+#ifdef HAVE_SNPRINTF
+		    snprintf(buf, sizeof(buf), "USER anonymous@%s\r\n",
 			           ctxt->hostname);
+#else
+		    sprintf(buf, "USER anonymous@%s\r\n", ctxt->hostname);
+#endif
 		else
-#ifndef HAVE_SNPRINTF
-		    len = sprintf(buf, "USER %s@%s\r\n",
-#else /* HAVE_SNPRINTF */
-		    len = snprintf(buf, sizeof(buf), "USER %s@%s\r\n",
-#endif /* HAVE_SNPRINTF */
+#ifdef HAVE_SNPRINTF
+		    snprintf(buf, sizeof(buf), "USER %s@%s\r\n",
 			           ctxt->user, ctxt->hostname);
+#else
+		    sprintf(buf, "USER %s@%s\r\n",
+			           ctxt->user, ctxt->hostname);
+#endif
+                buf[sizeof(buf) - 1] = 0;
+                len = strlen(buf);
 #ifdef DEBUG_FTP
 		printf(buf);
 #endif
@@ -1050,17 +1055,19 @@
 		    return(0);
 		}    
 		if (ctxt->passwd == NULL)
-#ifndef HAVE_SNPRINTF
-		    len = sprintf(buf, "PASS libxml@%s\r\n", hostname);
-#else /* HAVE_SNPRINTF */
-		    len = snprintf(buf, sizeof(buf), "PASS libxml@%s\r\n", hostname);
-#endif /* HAVE_SNPRINTF */
+#ifdef HAVE_SNPRINTF
+		    snprintf(buf, sizeof(buf), "PASS libxml@%s\r\n", hostname);
+#else
+		    sprintf(buf, "PASS libxml@%s\r\n", hostname);
+#endif
 		else
-#ifndef HAVE_SNPRINTF
-		    len = sprintf(buf, "PASS %s\r\n", ctxt->passwd);
-#else /* HAVE_SNPRINTF */
-		    len = snprintf(buf, sizeof(buf), "PASS %s\r\n", ctxt->passwd);
-#endif /* HAVE_SNPRINTF */
+#ifdef HAVE_SNPRINTF
+		    snprintf(buf, sizeof(buf), "PASS %s\r\n", ctxt->passwd);
+#else
+		    sprintf(buf, "PASS %s\r\n", ctxt->passwd);
+#endif
+                buf[sizeof(buf) - 1] = 0;
+                len = strlen(buf);
 #ifdef DEBUG_FTP
 		printf(buf);
 #endif
@@ -1195,11 +1202,13 @@
      *     250
      *     500, 501, 502, 421, 530, 550
      */
-#ifndef HAVE_SNPRINTF
-    len = sprintf(buf, "CWD %s\r\n", directory);
-#else /* HAVE_SNPRINTF */
-    len = snprintf(buf, sizeof(buf), "CWD %s\r\n", directory);
-#endif /* HAVE_SNPRINTF */
+#ifdef HAVE_SNPRINTF
+    snprintf(buf, sizeof(buf), "CWD %s\r\n", directory);
+#else
+    sprintf(buf, "CWD %s\r\n", directory);
+#endif
+    buf[sizeof(buf) - 1] = 0;
+    len = strlen(buf);
 #ifdef DEBUG_FTP
     printf(buf);
 #endif
@@ -1246,11 +1255,8 @@
     dataAddr.sin_family = AF_INET;
 
     if (ctxt->passive) {
-#ifndef HAVE_SNPRINTF
-	len = sprintf(buf, "PASV\r\n");
-#else /* HAVE_SNPRINTF */
-	len = snprintf(buf, sizeof(buf), "PASV\r\n");
-#endif /* HAVE_SNPRINTF */
+	sprintf(buf, "PASV\r\n");
+        len = strlen(buf);
 #ifdef DEBUG_FTP
 	printf(buf);
 #endif
@@ -1308,16 +1314,17 @@
 	}
 	adp = (unsigned char *) &dataAddr.sin_addr;
 	portp = (unsigned char *) &dataAddr.sin_port;
-#ifndef HAVE_SNPRINTF
-	len = sprintf(buf, "PORT %d,%d,%d,%d,%d,%d\r\n",
+#ifdef HAVE_SNPRINTF
+	snprintf(buf, sizeof(buf), "PORT %d,%d,%d,%d,%d,%d\r\n",
 	       adp[0] & 0xff, adp[1] & 0xff, adp[2] & 0xff, adp[3] & 0xff,
 	       portp[0] & 0xff, portp[1] & 0xff);
-#else /* HAVE_SNPRINTF */
-	len = snprintf(buf, sizeof(buf), "PORT %d,%d,%d,%d,%d,%d\r\n",
+#else
+	sprintf(buf, "PORT %d,%d,%d,%d,%d,%d\r\n",
 	       adp[0] & 0xff, adp[1] & 0xff, adp[2] & 0xff, adp[3] & 0xff,
 	       portp[0] & 0xff, portp[1] & 0xff);
-#endif /* HAVE_SNPRINTF */
+#endif
         buf[sizeof(buf) - 1] = 0;
+        len = strlen(buf);
 #ifdef DEBUG_FTP
 	printf(buf);
 #endif
@@ -1538,11 +1545,7 @@
 	ctxt->dataFd = xmlNanoFTPGetConnection(ctxt);
 	if (ctxt->dataFd == -1)
 	    return(-1);
-#ifndef HAVE_SNPRINTF
-	len = sprintf(buf, "LIST -L\r\n");
-#else /* HAVE_SNPRINTF */
-	len = snprintf(buf, sizeof(buf), "LIST -L\r\n");
-#endif /* HAVE_SNPRINTF */
+	sprintf(buf, "LIST -L\r\n");
     } else {
 	if (filename[0] != '/') {
 	    if (xmlNanoFTPCwd(ctxt, ctxt->path) < 1)
@@ -1551,12 +1554,14 @@
 	ctxt->dataFd = xmlNanoFTPGetConnection(ctxt);
 	if (ctxt->dataFd == -1)
 	    return(-1);
-#ifndef HAVE_SNPRINTF
-	len = sprintf(buf, "LIST -L %s\r\n", filename);
-#else /* HAVE_SNPRINTF */
-	len = snprintf(buf, sizeof(buf), "LIST -L %s\r\n", filename);
-#endif /* HAVE_SNPRINTF */
+#ifdef HAVE_SNPRINTF
+	snprintf(buf, sizeof(buf), "LIST -L %s\r\n", filename);
+#else
+	sprintf(buf, "LIST -L %s\r\n", filename);
+#endif
     }
+    buf[sizeof(buf) - 1] = 0;
+    len = strlen(buf);
 #ifdef DEBUG_FTP
     printf(buf);
 #endif
@@ -1649,11 +1654,8 @@
     if (ctxt->dataFd == -1)
 	return(-1);
 
-#ifndef HAVE_SNPRINTF
-    len = sprintf(buf, "TYPE I\r\n");
-#else /* HAVE_SNPRINTF */
-    len = snprintf(buf, sizeof(buf), "TYPE I\r\n");
-#endif /* HAVE_SNPRINTF */
+    sprintf(buf, "TYPE I\r\n");
+    len = strlen(buf);
 #ifdef DEBUG_FTP
     printf(buf);
 #endif
@@ -1668,17 +1670,19 @@
 	return(-res);
     }
     if (filename == NULL)
-#ifndef HAVE_SNPRINTF
-	len = sprintf(buf, "RETR %s\r\n", ctxt->path);
-#else /* HAVE_SNPRINTF */
-	len = snprintf(buf, sizeof(buf), "RETR %s\r\n", ctxt->path);
-#endif /* HAVE_SNPRINTF */
+#ifdef HAVE_SNPRINTF
+	snprintf(buf, sizeof(buf), "RETR %s\r\n", ctxt->path);
+#else
+	sprintf(buf, "RETR %s\r\n", ctxt->path);
+#endif
     else
-#ifndef HAVE_SNPRINTF
-	len = sprintf(buf, "RETR %s\r\n", filename);
-#else /* HAVE_SNPRINTF */
-	len = snprintf(buf, sizeof(buf), "RETR %s\r\n", filename);
-#endif /* HAVE_SNPRINTF */
+#ifdef HAVE_SNPRINTF
+	snprintf(buf, sizeof(buf), "RETR %s\r\n", filename);
+#else
+	sprintf(buf, "RETR %s\r\n", filename);
+#endif
+    buf[sizeof(buf) - 1] = 0;
+    len = strlen(buf);
 #ifdef DEBUG_FTP
     printf(buf);
 #endif
diff --git a/nanohttp.c b/nanohttp.c
index 51f1e92..4c63f37 100644
--- a/nanohttp.c
+++ b/nanohttp.c
@@ -772,20 +772,21 @@
     }
     ctxt->fd = ret;
     if (proxy) {
-#ifdef HAVE_SNPRINTF
 	if (ctxt->port != 80)
+#ifdef HAVE_SNPRINTF
 	    snprintf(buf, sizeof(buf),
 		     "GET http://%s:%d%s HTTP/1.0\r\nHost: %s\r\n\r\n",
 		 ctxt->hostname, ctxt->port, ctxt->path, ctxt->hostname);
-	else 
-	    snprintf(buf, sizeof(buf),"GET http://%s%s HTTP/1.0\r\nHost: %s\r\n\r\n",
-		 ctxt->hostname, ctxt->path, ctxt->hostname);
 #else
-	if (ctxt->port != 80)
 	    sprintf(buf, 
 		     "GET http://%s:%d%s HTTP/1.0\r\nHost: %s\r\n\r\n",
 		 ctxt->hostname, ctxt->port, ctxt->path, ctxt->hostname);
+#endif
 	else 
+#ifdef HAVE_SNPRINTF
+	    snprintf(buf, sizeof(buf),"GET http://%s%s HTTP/1.0\r\nHost: %s\r\n\r\n",
+		 ctxt->hostname, ctxt->path, ctxt->hostname);
+#else
 	    sprintf(buf, "GET http://%s%s HTTP/1.0\r\nHost: %s\r\n\r\n",
 		 ctxt->hostname, ctxt->path, ctxt->hostname);
 #endif
@@ -810,6 +811,7 @@
 	       ctxt->path, ctxt->hostname);
 #endif
     }
+    buf[sizeof(buf) - 1] = 0;
     ctxt->outptr = ctxt->out = xmlMemStrdup(buf);
     ctxt->state = XML_NANO_HTTP_WRITE;
     xmlNanoHTTPSend(ctxt);
@@ -1073,6 +1075,7 @@
 	    }
 	}
     }
+    buf[sizeof(buf) - 1] = 0;
 #ifdef DEBUG_HTTP
     printf("-> %s", buf);
 #endif
diff --git a/parser.c b/parser.c
index 372652c..1b6af43 100644
--- a/parser.c
+++ b/parser.c
@@ -16,8 +16,10 @@
 
 #ifdef WIN32
 #include "win32config.h"
+#define XML_DIR_SEP '\\'
 #else
 #include "config.h"
+#define XML_DIR_SEP '/'
 #endif
 
 #include <stdio.h>
@@ -307,6 +309,11 @@
 	    /* Allocate the Node stack */
 	    ctxt->vctxt.nodeTab = (xmlNodePtr *)
 		       xmlMalloc(4 * sizeof(xmlNodePtr));
+	    if (ctxt->vctxt.nodeTab == NULL) {
+		ctxt->vctxt.nodeMax = 0;
+		ctxt->validate = 0;
+		return(-1);
+	    }
 	    ctxt->vctxt.nodeNr = 0;
 	    ctxt->vctxt.nodeMax = 4;
 	    ctxt->vctxt.node = NULL;
@@ -1861,7 +1868,7 @@
                 break;
             case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
             case XML_EXTERNAL_PARAMETER_ENTITY:
-		return(xmlLoadExternalEntity((char *) entity->SystemID,
+		return(xmlLoadExternalEntity((char *) entity->URI,
 		       (char *) entity->ExternalID, ctxt));
             case XML_INTERNAL_GENERAL_ENTITY:
 		if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
@@ -1887,7 +1894,7 @@
     if (input == NULL) {
 	return(NULL);
     }
-    input->filename = (char *) entity->SystemID;
+    input->filename = (char *) entity->URI;
     input->base = entity->content;
     input->cur = entity->content;
     input->length = entity->length;
@@ -1939,49 +1946,26 @@
     xmlParserInputBufferPtr buf;
     xmlParserInputPtr inputStream;
     char *directory = NULL;
+    xmlChar *URI = NULL;
 
     if (xmlParserDebugEntities)
 	fprintf(stderr, "new input from file: %s\n", filename);
     if (ctxt == NULL) return(NULL);
     buf = xmlParserInputBufferCreateFilename(filename, XML_CHAR_ENCODING_NONE);
-    if (buf == NULL) {
-	char name[XML_PARSER_BIG_BUFFER_SIZE];
+    if (buf == NULL)
+	return(NULL);
 
-        if ((ctxt->input != NULL) && (ctxt->input->directory != NULL)) {
-#ifdef WIN32
-            sprintf(name, "%s\\%s", ctxt->input->directory, filename);
-#else
-            sprintf(name, "%s/%s", ctxt->input->directory, filename);
-#endif
-            buf = xmlParserInputBufferCreateFilename(name,
-	                                             XML_CHAR_ENCODING_NONE);
-	    if (buf != NULL)
-		directory = xmlParserGetDirectory(name);
-	}
-	if ((buf == NULL) && (ctxt->directory != NULL)) {
-#ifdef WIN32
-            sprintf(name, "%s\\%s", ctxt->directory, filename);
-#else
-            sprintf(name, "%s/%s", ctxt->directory, filename);
-#endif
-            buf = xmlParserInputBufferCreateFilename(name,
-	                                             XML_CHAR_ENCODING_NONE);
-	    if (buf != NULL)
-		directory = xmlParserGetDirectory(name);
-	}
-	if (buf == NULL)
-	    return(NULL);
-    }
-    if (directory == NULL)
-        directory = xmlParserGetDirectory(filename);
+    URI = xmlStrdup((xmlChar *) filename);
+    directory = xmlParserGetDirectory(URI);
 
     inputStream = xmlNewInputStream(ctxt);
     if (inputStream == NULL) {
 	if (directory != NULL) xmlFree((char *) directory);
+	if (URI != NULL) xmlFree((char *) URI);
 	return(NULL);
     }
 
-    inputStream->filename = xmlMemStrdup(filename);
+    inputStream->filename = URI;
     inputStream->directory = directory;
     inputStream->buf = buf;
 
@@ -2020,6 +2004,13 @@
 
     /* Allocate the Input stack */
     ctxt->inputTab = (xmlParserInputPtr *) xmlMalloc(5 * sizeof(xmlParserInputPtr));
+    if (ctxt->inputTab == NULL) {
+        fprintf(stderr, "xmlInitParserCtxt: out of memory\n");
+	ctxt->inputNr = 0;
+	ctxt->inputMax = 0;
+	ctxt->input = NULL;
+	return;
+    }
     ctxt->inputNr = 0;
     ctxt->inputMax = 5;
     ctxt->input = NULL;
@@ -2037,18 +2028,57 @@
 
     /* Allocate the Node stack */
     ctxt->nodeTab = (xmlNodePtr *) xmlMalloc(10 * sizeof(xmlNodePtr));
+    if (ctxt->nodeTab == NULL) {
+        fprintf(stderr, "xmlInitParserCtxt: out of memory\n");
+	ctxt->nodeNr = 0;
+	ctxt->nodeMax = 0;
+	ctxt->node = NULL;
+	ctxt->inputNr = 0;
+	ctxt->inputMax = 0;
+	ctxt->input = NULL;
+	return;
+    }
     ctxt->nodeNr = 0;
     ctxt->nodeMax = 10;
     ctxt->node = NULL;
 
     /* Allocate the Name stack */
     ctxt->nameTab = (xmlChar **) xmlMalloc(10 * sizeof(xmlChar *));
+    if (ctxt->nameTab == NULL) {
+        fprintf(stderr, "xmlInitParserCtxt: out of memory\n");
+	ctxt->nodeNr = 0;
+	ctxt->nodeMax = 0;
+	ctxt->node = NULL;
+	ctxt->inputNr = 0;
+	ctxt->inputMax = 0;
+	ctxt->input = NULL;
+	ctxt->nameNr = 0;
+	ctxt->nameMax = 0;
+	ctxt->name = NULL;
+	return;
+    }
     ctxt->nameNr = 0;
     ctxt->nameMax = 10;
     ctxt->name = NULL;
 
     /* Allocate the space stack */
     ctxt->spaceTab = (int *) xmlMalloc(10 * sizeof(int));
+    if (ctxt->spaceTab == NULL) {
+        fprintf(stderr, "xmlInitParserCtxt: out of memory\n");
+	ctxt->nodeNr = 0;
+	ctxt->nodeMax = 0;
+	ctxt->node = NULL;
+	ctxt->inputNr = 0;
+	ctxt->inputMax = 0;
+	ctxt->input = NULL;
+	ctxt->nameNr = 0;
+	ctxt->nameMax = 0;
+	ctxt->name = NULL;
+	ctxt->spaceNr = 0;
+	ctxt->spaceMax = 0;
+	ctxt->space = NULL;
+	return;
+    }
     ctxt->spaceNr = 1;
     ctxt->spaceMax = 10;
     ctxt->spaceTab[0] = -1;
@@ -2076,9 +2106,17 @@
 	    ctxt->vctxt.warning = xmlParserValidityWarning;
 	/* Allocate the Node stack */
 	ctxt->vctxt.nodeTab = (xmlNodePtr *) xmlMalloc(4 * sizeof(xmlNodePtr));
-	ctxt->vctxt.nodeNr = 0;
-	ctxt->vctxt.nodeMax = 4;
-	ctxt->vctxt.node = NULL;
+	if (ctxt->vctxt.nodeTab == NULL) {
+	    fprintf(stderr, "xmlInitParserCtxt: out of memory\n");
+	    ctxt->vctxt.nodeMax = 0;
+	    ctxt->validate = 0;
+	    ctxt->vctxt.error = NULL;
+	    ctxt->vctxt.warning = NULL;
+	} else {
+	    ctxt->vctxt.nodeNr = 0;
+	    ctxt->vctxt.nodeMax = 4;
+	    ctxt->vctxt.node = NULL;
+	}
     } else {
 	ctxt->vctxt.error = NULL;
 	ctxt->vctxt.warning = NULL;
@@ -5861,7 +5899,7 @@
 	 * handle the various case of definitions...
 	 */
 	if (isParameter) {
-	    if ((RAW == '"') || (RAW == '\''))
+	    if ((RAW == '"') || (RAW == '\'')) {
 	        value = xmlParseEntityValue(ctxt, &orig);
 		if (value) {
 		    if ((ctxt->sax != NULL) &&
@@ -5870,7 +5908,7 @@
 		                    XML_INTERNAL_PARAMETER_ENTITY,
 				    NULL, NULL, value);
 		}
-	    else {
+	    } else {
 	        URI = xmlParseExternalID(ctxt, &literal, 1);
 		if ((URI == NULL) && (literal == NULL)) {
 		    if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
@@ -7648,7 +7686,7 @@
 			ctxt->depth++;
 			ret = xmlParseExternalEntity(ctxt->myDoc,
 				   ctxt->sax, NULL, ctxt->depth,
-				   ent->SystemID, ent->ExternalID, &list);
+				   ent->URI, ent->ExternalID, &list);
 			ctxt->depth--;
 		    } else {
 			ret = -1;
@@ -11004,6 +11042,7 @@
  * @cur:  a pointer to an array of xmlChar
  *
  * Creates a parser context for an XML in-memory document.
+ * TODO: buggy need to be converted to new I/O functions ....
  *
  * Returns the new parser context or NULL
  */
@@ -11298,7 +11337,7 @@
 	return(-1);
 
 
-    ctxt = xmlCreateEntityParserCtxt(URL, ID, ctx->myDoc->URL);
+    ctxt = xmlCreateEntityParserCtxt(URL, ID, NULL);
     if (ctxt == NULL) return(-1);
     ctxt->userData = ctxt;
     oldsax = ctxt->sax;
@@ -11354,9 +11393,16 @@
 	ctxt->vctxt.warning = ctx->vctxt.warning;
 	/* Allocate the Node stack */
 	ctxt->vctxt.nodeTab = (xmlNodePtr *) xmlMalloc(4 * sizeof(xmlNodePtr));
-	ctxt->vctxt.nodeNr = 0;
-	ctxt->vctxt.nodeMax = 4;
-	ctxt->vctxt.node = NULL;
+	if (ctxt->vctxt.nodeTab == NULL) {
+	    fprintf(stderr, "xmlParseCtxtExternalEntity: out of memory\n");
+	    ctxt->validate = 0;
+	    ctxt->vctxt.error = NULL;
+	    ctxt->vctxt.warning = NULL;
+	} else {
+	    ctxt->vctxt.nodeNr = 0;
+	    ctxt->vctxt.nodeMax = 4;
+	    ctxt->vctxt.node = NULL;
+	}
     } else {
 	ctxt->vctxt.error = NULL;
 	ctxt->vctxt.warning = NULL;
@@ -11462,7 +11508,7 @@
 	return(-1);
 
 
-    ctxt = xmlCreateEntityParserCtxt(URL, ID, doc->URL);
+    ctxt = xmlCreateEntityParserCtxt(URL, ID, NULL);
     if (ctxt == NULL) return(-1);
     ctxt->userData = ctxt;
     if (sax != NULL) {
@@ -11829,10 +11875,15 @@
     char *directory = NULL;
 
     buf = xmlParserInputBufferCreateFilename(filename, XML_CHAR_ENCODING_NONE);
-    if (buf == NULL) return(NULL);
+    if (buf == NULL) {
+	return(NULL);
+    }
 
     ctxt = xmlNewParserCtxt();
     if (ctxt == NULL) {
+	if (xmlDefaultSAXHandler.error != NULL) {
+	    xmlDefaultSAXHandler.error(NULL, "out of memory\n");
+	}
 	return(NULL);
     }
 
@@ -11879,7 +11930,9 @@
     char *directory = NULL;
 
     ctxt = xmlCreateFileParserCtxt(filename);
-    if (ctxt == NULL) return(NULL);
+    if (ctxt == NULL) {
+	return(NULL);
+    }
     if (sax != NULL) {
 	if (ctxt->sax != NULL)
 	    xmlFree(ctxt->sax);
diff --git a/result/VC/OneID3 b/result/VC/OneID3
index 3f08c9e..ac81a9b 100644
--- a/result/VC/OneID3
+++ b/result/VC/OneID3
@@ -1,3 +1,3 @@
-dtds/doc.dtd:2: validity error: Element doc has ID attributes defined in the internal and external subset : val
+./test/VC/dtds/doc.dtd:2: validity error: Element doc has ID attributes defined in the internal and external subset : val
 <!ATTLIST doc val ID #IMPLIED>
                              ^
diff --git a/result/VC/UniqueElementTypeDeclaration b/result/VC/UniqueElementTypeDeclaration
index e24b8e7..a255ef6 100644
--- a/result/VC/UniqueElementTypeDeclaration
+++ b/result/VC/UniqueElementTypeDeclaration
@@ -1,3 +1,3 @@
-dtds/a.dtd:1: validity error: Redefinition of element a
+./test/VC/dtds/a.dtd:1: validity error: Redefinition of element a
 <!ELEMENT a (#PCDATA | b | c)*>
                               ^
diff --git a/tree.c b/tree.c
index 21c8663..4366336 100644
--- a/tree.c
+++ b/tree.c
@@ -2634,12 +2634,12 @@
         case XML_ELEMENT_DECL:
         case XML_ATTRIBUTE_DECL:
         case XML_ENTITY_DECL:
-	    return;
-        case XML_ELEMENT_NODE:
-        case XML_ATTRIBUTE_NODE:
         case XML_PI_NODE:
         case XML_ENTITY_REF_NODE:
         case XML_ENTITY_NODE:
+	    return;
+        case XML_ELEMENT_NODE:
+        case XML_ATTRIBUTE_NODE:
 	    break;
     }
     xmlSetProp(cur, BAD_CAST "xml:lang", lang);
@@ -2757,6 +2757,9 @@
     if ((doc != NULL) && (doc->type == XML_HTML_DOCUMENT_NODE)) {
         cur = doc->children;
 	while ((cur != NULL) && (cur->name != NULL)) {
+	    if (cur->type == XML_ENTITY_DECL) {
+		/* TODO: we are crossing entity boundaries */
+	    }
 	    if (cur->type != XML_ELEMENT_NODE) {
 	        cur = cur->next;
 		continue;
diff --git a/tree.h b/tree.h
index a3ae15f..e4cf730 100644
--- a/tree.h
+++ b/tree.h
@@ -41,7 +41,12 @@
     XML_DTD_NODE=		14,
     XML_ELEMENT_DECL=		15,
     XML_ATTRIBUTE_DECL=		16,
+#ifdef LIBXML_SGML_ENABLED
+    XML_ENTITY_DECL=		17,
+    XML_SGML_DOCUMENT_NODE=	18
+#else
     XML_ENTITY_DECL=		17
+#endif
 } xmlElementType;
 
 /*
diff --git a/uri.c b/uri.c
index 30a9047..efba43f 100644
--- a/uri.c
+++ b/uri.c
@@ -1637,8 +1637,8 @@
 	/*
 	 * Ensure the path includes a '/'
 	 */
-	if (res->path[0] != '/' && ref->path[0] != 0 &&
-	    ref->path[index] != '/') {
+	if ((out >0) && (res->path[out -1] != '/') &&
+	    (ref->path[0] != 0) && (ref->path[index] != '/')) {
 	    res->path[out++] = '/';
 	}
 	while (ref->path[index] != 0) {
@@ -1664,7 +1664,7 @@
 done:
     if (ref != NULL)
 	xmlFreeURI(ref);
-    if (base != NULL)
+    if (bas != NULL)
 	xmlFreeURI(bas);
     if (res != NULL)
 	xmlFreeURI(res);
diff --git a/valid.c b/valid.c
index 7aa76ab..dc091e6 100644
--- a/valid.c
+++ b/valid.c
@@ -2856,8 +2856,9 @@
 	snprintf((char *) qname, sizeof(qname), "%s:%s",
 		 elem->ns->prefix, elem->name);
 #else
-	sprintf(qname, "%s:%s", elem->name, elem->ns->prefix);
+	sprintf((char *) qname, "%s:%s", elem->ns->prefix, elem->name);
 #endif
+        qname[sizeof(qname) - 1] = 0;
 	attrDecl = xmlGetDtdAttrDesc(doc->intSubset, qname, name);
 	if ((attrDecl == NULL) && (doc->extSubset != NULL))
 	    attrDecl = xmlGetDtdAttrDesc(doc->extSubset, qname, name);
@@ -3133,8 +3134,9 @@
 	snprintf((char *) qname, sizeof(qname), "%s:%s",
 		 elem->ns->prefix, elem->name);
 #else
-	sprintf(qname, "%s:%s", elem->name, elem->ns->prefix);
+	sprintf((char *) qname, "%s:%s", elem->ns->prefix, elem->name);
 #endif
+        qname[sizeof(qname) - 1] = 0;
 	if (attr->ns != NULL) {
 	    attrDecl = xmlGetDtdQAttrDesc(doc->intSubset, qname,
 		                          attr->name, attr->ns->prefix);
@@ -3699,8 +3701,10 @@
 			snprintf((char *) qname, sizeof(qname), "%s:%s",
 				 child->ns->prefix, child->name);
 #else
-			sprintf(qname, "%s:%s", child->name, child->ns->prefix);
+			sprintf((char *) qname, "%s:%s",
+                                 child->ns->prefix, child->name);
 #endif
+                        qname[sizeof(qname) - 1] = 0;
 			cont = elemDecl->content;
 			while (cont != NULL) {
 			    if (cont->type == XML_ELEMENT_CONTENT_ELEMENT) {
@@ -3876,8 +3880,9 @@
 	    snprintf((char *) qname, sizeof(qname), "%s:%s",
 		     root->ns->prefix, root->name);
 #else
-	    sprintf(qname, "%s:%s", root->name, root->ns->prefix);
+	    sprintf((char *) qname, "%s:%s", root->ns->prefix, root->name);
 #endif
+            qname[sizeof(qname) - 1] = 0;
 	    if (!xmlStrcmp(doc->intSubset->name, qname))
 		goto name_ok;
 	} 
diff --git a/xmlIO.c b/xmlIO.c
index 3172917..7240f2c 100644
--- a/xmlIO.c
+++ b/xmlIO.c
@@ -873,9 +873,6 @@
 	}
     }
     if (context == NULL) {
-#ifdef DEBUG_INPUT
-	fprintf(stderr, "No input filter matching \"%s\"\n", URI);
-#endif
 	return(NULL);
     }
 
@@ -947,9 +944,6 @@
 	}
     }
     if (context == NULL) {
-#ifdef DEBUG_INPUT
-	fprintf(stderr, "No output filter matching \"%s\"\n", URI);
-#endif
 	return(NULL);
     }
 
@@ -1533,6 +1527,7 @@
 xmlDefaultExternalEntityLoader(const char *URL, const char *ID,
                                xmlParserCtxtPtr ctxt) {
     xmlParserInputPtr ret = NULL;
+
 #ifdef DEBUG_EXTERNAL_ENTITIES
     fprintf(stderr, "xmlDefaultExternalEntityLoader(%s, xxx)\n", URL);
 #endif
diff --git a/xmlIO.h b/xmlIO.h
index b966c4a..6ef91fd 100644
--- a/xmlIO.h
+++ b/xmlIO.h
@@ -37,7 +37,7 @@
     
     xmlCharEncodingHandlerPtr encoder; /* I18N conversions to UTF-8 */
     
-    xmlBufferPtr buffer;    /* Local buffer encoded in UTF-8 or ISOLatin */
+    xmlBufferPtr buffer;    /* Local buffer encoded in UTF-8 */
     xmlBufferPtr raw;       /* if encoder != NULL buffer for raw input */
 };
 
diff --git a/xmlversion.h.in b/xmlversion.h.in
index 664d89d..c0544e6 100644
--- a/xmlversion.h.in
+++ b/xmlversion.h.in
@@ -50,6 +50,15 @@
 #endif
 
 /*
+ * Whether the Docbook support is configured in
+#if @WITH_SGML@
+#define LIBXML_SGML_ENABLED
+#else
+#define LIBXML_SGML_DISABLED
+#endif
+ */
+
+/*
  * Whether XPath is configured in
  */
 #if @WITH_XPATH@
diff --git a/xpath.c b/xpath.c
index 413c16c..433bb56 100644
--- a/xpath.c
+++ b/xpath.c
@@ -2417,9 +2417,16 @@
 	    
 	else {
 	    char name[2000];
+#ifdef HAVE_SNPRINTF
+	    snprintf(name, sizeof(name), "%s:%s", 
+	            (char *) cur->nodesetval->nodeTab[i]->ns->prefix,
+	            (char *) cur->nodesetval->nodeTab[i]->name);
+#else
 	    sprintf(name, "%s:%s", 
 	            (char *) cur->nodesetval->nodeTab[i]->ns->prefix,
 	            (char *) cur->nodesetval->nodeTab[i]->name);
+#endif
+            name[sizeof(name) - 1] = 0;
 	    valuePush(ctxt, xmlXPathNewCString(name));
         }
     }