diff --git a/HTMLparser.c b/HTMLparser.c
index 840e6ebf..843b497d 100644
--- a/HTMLparser.c
+++ b/HTMLparser.c
@@ -6719,7 +6719,8 @@ htmlCtxtReadMemory(htmlParserCtxtPtr ctxt, const char *buffer, int size,
htmlCtxtReset(ctxt);
- input = xmlParserInputBufferCreateMem(buffer, size, XML_CHAR_ENCODING_NONE);
+ input = xmlParserInputBufferCreateStatic(buffer, size,
+ XML_CHAR_ENCODING_NONE);
if (input == NULL) {
htmlErrMemory(ctxt, NULL);
return(NULL);
diff --git a/include/libxml/xmlIO.h b/include/libxml/xmlIO.h
index 7e88da5b..94c7c236 100644
--- a/include/libxml/xmlIO.h
+++ b/include/libxml/xmlIO.h
@@ -216,7 +216,6 @@ XMLPUBFUN xmlParserInputBufferPtr
XMLPUBFUN xmlParserInputBufferPtr
xmlParserInputBufferCreateMem (const char *mem, int size,
xmlCharEncoding enc);
-XML_DEPRECATED
XMLPUBFUN xmlParserInputBufferPtr
xmlParserInputBufferCreateStatic (const char *mem, int size,
xmlCharEncoding enc);
diff --git a/parser.c b/parser.c
index 43ef214e..d6b8f2a1 100644
--- a/parser.c
+++ b/parser.c
@@ -14871,7 +14871,8 @@ xmlCtxtReadMemory(xmlParserCtxtPtr ctxt, const char *buffer, int size,
xmlCtxtReset(ctxt);
- input = xmlParserInputBufferCreateMem(buffer, size, XML_CHAR_ENCODING_NONE);
+ input = xmlParserInputBufferCreateStatic(buffer, size,
+ XML_CHAR_ENCODING_NONE);
if (input == NULL) {
xmlErrMemory(ctxt, NULL);
return(NULL);
diff --git a/testchar.c b/testchar.c
index 8895d8d0..f4b2f4f5 100644
--- a/testchar.c
+++ b/testchar.c
@@ -648,8 +648,8 @@ static int testCharRanges(void) {
fprintf(stderr, "Failed to allocate parser context\n");
return(1);
}
- buf = xmlParserInputBufferCreateMem(data, sizeof(data),
- XML_CHAR_ENCODING_NONE);
+ buf = xmlParserInputBufferCreateStatic(data, sizeof(data),
+ XML_CHAR_ENCODING_NONE);
if (buf == NULL) {
fprintf(stderr, "Failed to allocate input buffer\n");
test_ret = 1;
diff --git a/xmlIO.c b/xmlIO.c
index 520720bf..db4039e3 100644
--- a/xmlIO.c
+++ b/xmlIO.c
@@ -2833,7 +2833,8 @@ xmlParserInputBufferCreateFd(int fd, xmlCharEncoding enc) {
}
typedef struct {
- const char *mem;
+ char *mem;
+ const char *cur;
size_t size;
} xmlMemIOCtxt;
@@ -2844,8 +2845,8 @@ xmlMemRead(void *vctxt, char *buf, int size) {
if ((size_t) size > ctxt->size)
size = ctxt->size;
- memcpy(buf, ctxt->mem, size);
- ctxt->mem += size;
+ memcpy(buf, ctxt->cur, size);
+ ctxt->cur += size;
ctxt->size -= size;
return size;
@@ -2853,7 +2854,11 @@ xmlMemRead(void *vctxt, char *buf, int size) {
static int
xmlMemClose(void *vctxt) {
- xmlFree(vctxt);
+ xmlMemIOCtxt *ctxt = vctxt;
+
+ if (ctxt->mem != 0)
+ xmlFree(ctxt->mem);
+ xmlFree(ctxt);
return(0);
}
@@ -2863,22 +2868,70 @@ xmlMemClose(void *vctxt) {
* @size: the length of the memory block
* @enc: the charset encoding if known (deprecated)
*
- * Create a buffered parser input for the progressive parsing for the input
- * from a memory area.
+ * Create a parser input buffer for parsing from a memory area.
+ *
+ * This function makes a copy of the whole input buffer. If you are sure
+ * that the contents of the buffer will remain valid until the document
+ * was parsed, you can avoid the copy by using
+ * xmlParserInputBufferCreateStatic.
*
* The encoding argument is deprecated and should be set to
* XML_CHAR_ENCODING_NONE. The encoding can be changed with
* xmlSwitchEncoding or xmlSwitchEncodingName later on.
*
- * Returns the new parser input or NULL
+ * Returns the new parser input or NULL in case of error.
*/
xmlParserInputBufferPtr
xmlParserInputBufferCreateMem(const char *mem, int size, xmlCharEncoding enc) {
+ xmlParserInputBufferPtr buf;
+ xmlMemIOCtxt *ctxt;
+ char *copy;
+
+ if ((size < 0) || (mem == NULL))
+ return(NULL);
+
+ copy = (char *) xmlStrndup((const xmlChar *) mem, size);
+ if (copy == NULL)
+ return(NULL);
+
+ buf = xmlParserInputBufferCreateStatic(copy, size, enc);
+ if (buf == NULL) {
+ xmlFree(copy);
+ return(NULL);
+ }
+
+ ctxt = buf->context;
+ ctxt->mem = copy;
+
+ return(buf);
+}
+
+/**
+ * xmlParserInputBufferCreateStatic:
+ * @mem: the memory input
+ * @size: the length of the memory block
+ * @enc: the charset encoding if known
+ *
+ * Create a parser input buffer for parsing from a memory area.
+ *
+ * This functions assumes that the contents of the input buffer remain
+ * valid until the document was parsed. Use xmlParserInputBufferCreateMem
+ * otherwise.
+ *
+ * The encoding argument is deprecated and should be set to
+ * XML_CHAR_ENCODING_NONE. The encoding can be changed with
+ * xmlSwitchEncoding or xmlSwitchEncodingName later on.
+ *
+ * Returns the new parser input or NULL in case of error.
+ */
+xmlParserInputBufferPtr
+xmlParserInputBufferCreateStatic(const char *mem, int size,
+ xmlCharEncoding enc) {
xmlParserInputBufferPtr ret;
xmlMemIOCtxt *ctxt;
- if (size < 0) return(NULL);
- if (mem == NULL) return(NULL);
+ if ((size < 0) || (mem == NULL))
+ return(NULL);
ret = xmlAllocParserInputBuffer(enc);
if (ret == NULL)
@@ -2889,7 +2942,8 @@ xmlParserInputBufferCreateMem(const char *mem, int size, xmlCharEncoding enc) {
xmlFreeParserInputBuffer(ret);
return(NULL);
}
- ctxt->mem = mem;
+ ctxt->mem = NULL;
+ ctxt->cur = mem;
ctxt->size = size;
ret->context = ctxt;
@@ -2899,22 +2953,6 @@ xmlParserInputBufferCreateMem(const char *mem, int size, xmlCharEncoding enc) {
return(ret);
}
-/**
- * xmlParserInputBufferCreateStatic:
- * @mem: the memory input
- * @size: the length of the memory block
- * @enc: the charset encoding if known
- *
- * DEPRECATED: Use xmlParserInputBufferCreateMem.
- *
- * Returns the new parser input or NULL
- */
-xmlParserInputBufferPtr
-xmlParserInputBufferCreateStatic(const char *mem, int size,
- xmlCharEncoding enc) {
- return(xmlParserInputBufferCreateMem(mem, size, enc));
-}
-
typedef struct {
const xmlChar *str;
} xmlStringIOCtxt;