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;