mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2025-03-21 22:50:08 +03:00
io: Fix memory lifetime issue with input buffers
xmlParserInputBufferCreateMem must make a copy of the buffer. This fixes a regression from 2.11 which could cause reads from freed memory depending on the use case. Undeprecate xmlParserInputBufferCreateStatic which can avoid copying the whole buffer.
This commit is contained in:
parent
0e4a11bb30
commit
c2bbeed1fd
@ -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);
|
||||
|
@ -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);
|
||||
|
3
parser.c
3
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);
|
||||
|
@ -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;
|
||||
|
90
xmlIO.c
90
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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user