mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2025-03-09 04:58:16 +03:00
Improve buffer allocation scheme
In most places, we really need the double-it scheme to avoid quadratic behavior. The hybrid scheme still can cause many reallocations and the bounded scheme doesn't seem to provide meaningful protection in xmlreader.c.
This commit is contained in:
parent
422176ad29
commit
d99ddd9bd5
1
parser.c
1
parser.c
@ -8068,6 +8068,7 @@ xmlLoadEntityContent(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
|
||||
"xmlLoadEntityContent parameter error");
|
||||
return(-1);
|
||||
}
|
||||
xmlBufferSetAllocationScheme(buf, XML_BUFFER_ALLOC_DOUBLEIT);
|
||||
|
||||
input = xmlNewEntityInputStream(ctxt, entity);
|
||||
if (input == NULL) {
|
||||
|
@ -325,6 +325,7 @@ xsdIncorrectTestCase(xmlNodePtr cur) {
|
||||
fprintf(stderr, "out of memory !\n");
|
||||
fatalError();
|
||||
}
|
||||
xmlBufferSetAllocationScheme(buf, XML_BUFFER_ALLOC_DOUBLEIT);
|
||||
xmlNodeDump(buf, test->doc, test, 0, 0);
|
||||
pctxt = xmlRelaxNGNewMemParserCtxt((const char *)buf->content, buf->use);
|
||||
xmlRelaxNGSetParserErrors(pctxt, testErrorHandler, testErrorHandler,
|
||||
@ -363,6 +364,7 @@ installResources(xmlNodePtr tst, const xmlChar *base) {
|
||||
fprintf(stderr, "out of memory !\n");
|
||||
fatalError();
|
||||
}
|
||||
xmlBufferSetAllocationScheme(buf, XML_BUFFER_ALLOC_DOUBLEIT);
|
||||
xmlNodeDump(buf, tst->doc, tst, 0, 0);
|
||||
|
||||
while (tst != NULL) {
|
||||
@ -458,6 +460,7 @@ xsdTestCase(xmlNodePtr tst) {
|
||||
fprintf(stderr, "out of memory !\n");
|
||||
fatalError();
|
||||
}
|
||||
xmlBufferSetAllocationScheme(buf, XML_BUFFER_ALLOC_DOUBLEIT);
|
||||
xmlNodeDump(buf, test->doc, test, 0, 0);
|
||||
pctxt = xmlRelaxNGNewMemParserCtxt((const char *)buf->content, buf->use);
|
||||
xmlRelaxNGSetParserErrors(pctxt, testErrorHandler, testErrorHandler,
|
||||
|
7
tree.c
7
tree.c
@ -1284,7 +1284,7 @@ xmlStringLenGetNodeList(const xmlDoc *doc, const xmlChar *value, int len) {
|
||||
|
||||
buf = xmlBufCreateSize(0);
|
||||
if (buf == NULL) return(NULL);
|
||||
xmlBufSetAllocationScheme(buf, XML_BUFFER_ALLOC_HYBRID);
|
||||
xmlBufSetAllocationScheme(buf, XML_BUFFER_ALLOC_DOUBLEIT);
|
||||
|
||||
q = cur;
|
||||
while ((cur < end) && (*cur != 0)) {
|
||||
@ -1505,7 +1505,7 @@ xmlStringGetNodeList(const xmlDoc *doc, const xmlChar *value) {
|
||||
|
||||
buf = xmlBufCreateSize(0);
|
||||
if (buf == NULL) return(NULL);
|
||||
xmlBufSetAllocationScheme(buf, XML_BUFFER_ALLOC_HYBRID);
|
||||
xmlBufSetAllocationScheme(buf, XML_BUFFER_ALLOC_DOUBLEIT);
|
||||
|
||||
q = cur;
|
||||
while (*cur != 0) {
|
||||
@ -5559,6 +5559,7 @@ xmlNodeGetContent(const xmlNode *cur)
|
||||
buf = xmlBufCreateSize(64);
|
||||
if (buf == NULL)
|
||||
return (NULL);
|
||||
xmlBufSetAllocationScheme(buf, XML_BUFFER_ALLOC_DOUBLEIT);
|
||||
xmlBufGetNodeContent(buf, cur);
|
||||
ret = xmlBufDetach(buf);
|
||||
xmlBufFree(buf);
|
||||
@ -5584,6 +5585,7 @@ xmlNodeGetContent(const xmlNode *cur)
|
||||
buf = xmlBufCreate();
|
||||
if (buf == NULL)
|
||||
return (NULL);
|
||||
xmlBufSetAllocationScheme(buf, XML_BUFFER_ALLOC_DOUBLEIT);
|
||||
|
||||
xmlBufGetNodeContent(buf, cur);
|
||||
|
||||
@ -5606,6 +5608,7 @@ xmlNodeGetContent(const xmlNode *cur)
|
||||
buf = xmlBufCreate();
|
||||
if (buf == NULL)
|
||||
return (NULL);
|
||||
xmlBufSetAllocationScheme(buf, XML_BUFFER_ALLOC_DOUBLEIT);
|
||||
|
||||
xmlBufGetNodeContent(buf, (xmlNodePtr) cur);
|
||||
|
||||
|
5
xmlIO.c
5
xmlIO.c
@ -2389,10 +2389,7 @@ xmlAllocOutputBuffer(xmlCharEncodingHandlerPtr encoder) {
|
||||
xmlFree(ret);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/* try to avoid a performance problem with Windows realloc() */
|
||||
if (xmlBufGetAllocationScheme(ret->buffer) == XML_BUFFER_ALLOC_EXACT)
|
||||
xmlBufSetAllocationScheme(ret->buffer, XML_BUFFER_ALLOC_DOUBLEIT);
|
||||
xmlBufSetAllocationScheme(ret->buffer, XML_BUFFER_ALLOC_DOUBLEIT);
|
||||
|
||||
ret->encoder = encoder;
|
||||
if (encoder != NULL) {
|
||||
|
13
xmlreader.c
13
xmlreader.c
@ -1180,6 +1180,7 @@ xmlTextReaderCollectSiblings(xmlNodePtr node)
|
||||
buffer = xmlBufferCreate();
|
||||
if (buffer == NULL)
|
||||
return NULL;
|
||||
xmlBufferSetAllocationScheme(buffer, XML_BUFFER_ALLOC_DOUBLEIT);
|
||||
|
||||
for ( ; node != NULL; node = node->next) {
|
||||
switch (node->type) {
|
||||
@ -1633,11 +1634,14 @@ xmlTextReaderReadInnerXml(xmlTextReaderPtr reader ATTRIBUTE_UNUSED)
|
||||
buff = xmlBufferCreate();
|
||||
if (buff == NULL)
|
||||
return NULL;
|
||||
xmlBufferSetAllocationScheme(buff, XML_BUFFER_ALLOC_DOUBLEIT);
|
||||
for (cur_node = reader->node->children; cur_node != NULL;
|
||||
cur_node = cur_node->next) {
|
||||
/* XXX: Why is the node copied? */
|
||||
node = xmlDocCopyNode(cur_node, doc, 1);
|
||||
/* XXX: Why do we need a second buffer? */
|
||||
buff2 = xmlBufferCreate();
|
||||
xmlBufferSetAllocationScheme(buff2, XML_BUFFER_ALLOC_DOUBLEIT);
|
||||
if (xmlNodeDump(buff2, doc, node, 0, 0) == -1) {
|
||||
xmlFreeNode(node);
|
||||
xmlBufferFree(buff2);
|
||||
@ -1687,6 +1691,7 @@ xmlTextReaderReadOuterXml(xmlTextReaderPtr reader ATTRIBUTE_UNUSED)
|
||||
node = xmlDocCopyNode(node, doc, 1);
|
||||
}
|
||||
buff = xmlBufferCreate();
|
||||
xmlBufferSetAllocationScheme(buff, XML_BUFFER_ALLOC_DOUBLEIT);
|
||||
if (xmlNodeDump(buff, doc, node, 0, 0) == -1) {
|
||||
xmlFreeNode(node);
|
||||
xmlBufferFree(buff);
|
||||
@ -2017,7 +2022,7 @@ xmlNewTextReader(xmlParserInputBufferPtr input, const char *URI) {
|
||||
}
|
||||
/* no operation on a reader should require a huge buffer */
|
||||
xmlBufSetAllocationScheme(ret->buffer,
|
||||
XML_BUFFER_ALLOC_BOUNDED);
|
||||
XML_BUFFER_ALLOC_DOUBLEIT);
|
||||
ret->sax = (xmlSAXHandler *) xmlMalloc(sizeof(xmlSAXHandler));
|
||||
if (ret->sax == NULL) {
|
||||
xmlBufFree(ret->buffer);
|
||||
@ -3555,7 +3560,7 @@ xmlTextReaderConstValue(xmlTextReaderPtr reader) {
|
||||
return (NULL);
|
||||
}
|
||||
xmlBufSetAllocationScheme(reader->buffer,
|
||||
XML_BUFFER_ALLOC_BOUNDED);
|
||||
XML_BUFFER_ALLOC_DOUBLEIT);
|
||||
} else
|
||||
xmlBufEmpty(reader->buffer);
|
||||
xmlBufGetNodeContent(reader->buffer, node);
|
||||
@ -3565,7 +3570,7 @@ xmlTextReaderConstValue(xmlTextReaderPtr reader) {
|
||||
xmlBufFree(reader->buffer);
|
||||
reader->buffer = xmlBufCreateSize(100);
|
||||
xmlBufSetAllocationScheme(reader->buffer,
|
||||
XML_BUFFER_ALLOC_BOUNDED);
|
||||
XML_BUFFER_ALLOC_DOUBLEIT);
|
||||
ret = BAD_CAST "";
|
||||
}
|
||||
return(ret);
|
||||
@ -5079,7 +5084,7 @@ xmlTextReaderSetup(xmlTextReaderPtr reader,
|
||||
}
|
||||
/* no operation on a reader should require a huge buffer */
|
||||
xmlBufSetAllocationScheme(reader->buffer,
|
||||
XML_BUFFER_ALLOC_BOUNDED);
|
||||
XML_BUFFER_ALLOC_DOUBLEIT);
|
||||
if (reader->sax == NULL)
|
||||
reader->sax = (xmlSAXHandler *) xmlMalloc(sizeof(xmlSAXHandler));
|
||||
if (reader->sax == NULL) {
|
||||
|
@ -474,6 +474,7 @@ xmlBufDumpNotationTable(xmlBufPtr buf, xmlNotationTablePtr table) {
|
||||
*/
|
||||
return;
|
||||
}
|
||||
xmlBufferSetAllocationScheme(buffer, XML_BUFFER_ALLOC_DOUBLEIT);
|
||||
xmlDumpNotationTable(buffer, table);
|
||||
xmlBufMergeBuffer(buf, buffer);
|
||||
}
|
||||
@ -497,6 +498,7 @@ xmlBufDumpElementDecl(xmlBufPtr buf, xmlElementPtr elem) {
|
||||
*/
|
||||
return;
|
||||
}
|
||||
xmlBufferSetAllocationScheme(buffer, XML_BUFFER_ALLOC_DOUBLEIT);
|
||||
xmlDumpElementDecl(buffer, elem);
|
||||
xmlBufMergeBuffer(buf, buffer);
|
||||
}
|
||||
@ -520,6 +522,7 @@ xmlBufDumpAttributeDecl(xmlBufPtr buf, xmlAttributePtr attr) {
|
||||
*/
|
||||
return;
|
||||
}
|
||||
xmlBufferSetAllocationScheme(buffer, XML_BUFFER_ALLOC_DOUBLEIT);
|
||||
xmlDumpAttributeDecl(buffer, attr);
|
||||
xmlBufMergeBuffer(buf, buffer);
|
||||
}
|
||||
@ -542,6 +545,7 @@ xmlBufDumpEntityDecl(xmlBufPtr buf, xmlEntityPtr ent) {
|
||||
*/
|
||||
return;
|
||||
}
|
||||
xmlBufferSetAllocationScheme(buffer, XML_BUFFER_ALLOC_DOUBLEIT);
|
||||
xmlDumpEntityDecl(buffer, ent);
|
||||
xmlBufMergeBuffer(buf, buffer);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user