mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2025-10-24 13:33:01 +03:00
parser: Rework shrinking of input buffers
Don't try to grow the input buffer in xmlParserShrink. This makes sure that no memory allocations are made and the function always succeeds. Remove unnecessary invocations of SHRINK. Invoke SHRINK at the end of DTD parsing loops. Shrink before growing.
This commit is contained in:
@@ -3100,7 +3100,6 @@ htmlParseScript(htmlParserCtxtPtr ctxt) {
|
|||||||
int nbchar = 0;
|
int nbchar = 0;
|
||||||
int cur,l;
|
int cur,l;
|
||||||
|
|
||||||
SHRINK;
|
|
||||||
cur = CUR_CHAR(l);
|
cur = CUR_CHAR(l);
|
||||||
while (cur != 0) {
|
while (cur != 0) {
|
||||||
if ((cur == '<') && (NXT(1) == '/')) {
|
if ((cur == '<') && (NXT(1) == '/')) {
|
||||||
@@ -3358,7 +3357,6 @@ htmlParsePI(htmlParserCtxtPtr ctxt) {
|
|||||||
* this is a Processing Instruction.
|
* this is a Processing Instruction.
|
||||||
*/
|
*/
|
||||||
SKIP(2);
|
SKIP(2);
|
||||||
SHRINK;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parse the target name and check for special support like
|
* Parse the target name and check for special support like
|
||||||
@@ -3481,7 +3479,6 @@ htmlParseComment(htmlParserCtxtPtr ctxt) {
|
|||||||
|
|
||||||
state = ctxt->instate;
|
state = ctxt->instate;
|
||||||
ctxt->instate = XML_PARSER_COMMENT;
|
ctxt->instate = XML_PARSER_COMMENT;
|
||||||
SHRINK;
|
|
||||||
SKIP(4);
|
SKIP(4);
|
||||||
buf = (xmlChar *) xmlMallocAtomic(size);
|
buf = (xmlChar *) xmlMallocAtomic(size);
|
||||||
if (buf == NULL) {
|
if (buf == NULL) {
|
||||||
@@ -4477,8 +4474,8 @@ htmlParseContent(htmlParserCtxtPtr ctxt) {
|
|||||||
htmlParseCharData(ctxt);
|
htmlParseCharData(ctxt);
|
||||||
}
|
}
|
||||||
|
|
||||||
GROW;
|
|
||||||
SHRINK;
|
SHRINK;
|
||||||
|
GROW;
|
||||||
}
|
}
|
||||||
if (currentNode != NULL) xmlFree(currentNode);
|
if (currentNode != NULL) xmlFree(currentNode);
|
||||||
}
|
}
|
||||||
@@ -4920,8 +4917,8 @@ htmlParseContentInternal(htmlParserCtxtPtr ctxt) {
|
|||||||
htmlParseCharData(ctxt);
|
htmlParseCharData(ctxt);
|
||||||
}
|
}
|
||||||
|
|
||||||
GROW;
|
|
||||||
SHRINK;
|
SHRINK;
|
||||||
|
GROW;
|
||||||
}
|
}
|
||||||
if (currentNode != NULL) xmlFree(currentNode);
|
if (currentNode != NULL) xmlFree(currentNode);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ XML_HIDDEN void
|
|||||||
xmlHaltParser(xmlParserCtxtPtr ctxt);
|
xmlHaltParser(xmlParserCtxtPtr ctxt);
|
||||||
XML_HIDDEN int
|
XML_HIDDEN int
|
||||||
xmlParserGrow(xmlParserCtxtPtr ctxt);
|
xmlParserGrow(xmlParserCtxtPtr ctxt);
|
||||||
XML_HIDDEN int
|
XML_HIDDEN void
|
||||||
xmlParserShrink(xmlParserCtxtPtr ctxt);
|
xmlParserShrink(xmlParserCtxtPtr ctxt);
|
||||||
|
|
||||||
#endif /* XML_PARSER_H_PRIVATE__ */
|
#endif /* XML_PARSER_H_PRIVATE__ */
|
||||||
|
|||||||
29
parser.c
29
parser.c
@@ -4183,7 +4183,6 @@ xmlParseSystemLiteral(xmlParserCtxtPtr ctxt) {
|
|||||||
xmlChar stop;
|
xmlChar stop;
|
||||||
int state = ctxt->instate;
|
int state = ctxt->instate;
|
||||||
|
|
||||||
SHRINK;
|
|
||||||
if (RAW == '"') {
|
if (RAW == '"') {
|
||||||
NEXT;
|
NEXT;
|
||||||
stop = '"';
|
stop = '"';
|
||||||
@@ -4265,7 +4264,6 @@ xmlParsePubidLiteral(xmlParserCtxtPtr ctxt) {
|
|||||||
xmlChar stop;
|
xmlChar stop;
|
||||||
xmlParserInputState oldstate = ctxt->instate;
|
xmlParserInputState oldstate = ctxt->instate;
|
||||||
|
|
||||||
SHRINK;
|
|
||||||
if (RAW == '"') {
|
if (RAW == '"') {
|
||||||
NEXT;
|
NEXT;
|
||||||
stop = '"';
|
stop = '"';
|
||||||
@@ -4387,7 +4385,6 @@ xmlParseCharData(xmlParserCtxtPtr ctxt, ATTRIBUTE_UNUSED int cdata) {
|
|||||||
int col = ctxt->input->col;
|
int col = ctxt->input->col;
|
||||||
int ccol;
|
int ccol;
|
||||||
|
|
||||||
SHRINK;
|
|
||||||
GROW;
|
GROW;
|
||||||
/*
|
/*
|
||||||
* Accelerated common case where input don't need to be
|
* Accelerated common case where input don't need to be
|
||||||
@@ -4533,7 +4530,6 @@ xmlParseCharDataComplex(xmlParserCtxtPtr ctxt) {
|
|||||||
int nbchar = 0;
|
int nbchar = 0;
|
||||||
int cur, l;
|
int cur, l;
|
||||||
|
|
||||||
SHRINK;
|
|
||||||
cur = CUR_CHAR(l);
|
cur = CUR_CHAR(l);
|
||||||
while ((cur != '<') && /* checked */
|
while ((cur != '<') && /* checked */
|
||||||
(cur != '&') &&
|
(cur != '&') &&
|
||||||
@@ -4629,8 +4625,6 @@ xmlChar *
|
|||||||
xmlParseExternalID(xmlParserCtxtPtr ctxt, xmlChar **publicID, int strict) {
|
xmlParseExternalID(xmlParserCtxtPtr ctxt, xmlChar **publicID, int strict) {
|
||||||
xmlChar *URI = NULL;
|
xmlChar *URI = NULL;
|
||||||
|
|
||||||
SHRINK;
|
|
||||||
|
|
||||||
*publicID = NULL;
|
*publicID = NULL;
|
||||||
if (CMP6(CUR_PTR, 'S', 'Y', 'S', 'T', 'E', 'M')) {
|
if (CMP6(CUR_PTR, 'S', 'Y', 'S', 'T', 'E', 'M')) {
|
||||||
SKIP(6);
|
SKIP(6);
|
||||||
@@ -4847,7 +4841,6 @@ xmlParseComment(xmlParserCtxtPtr ctxt) {
|
|||||||
ctxt->instate = XML_PARSER_COMMENT;
|
ctxt->instate = XML_PARSER_COMMENT;
|
||||||
inputid = ctxt->input->id;
|
inputid = ctxt->input->id;
|
||||||
SKIP(2);
|
SKIP(2);
|
||||||
SHRINK;
|
|
||||||
GROW;
|
GROW;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -5133,7 +5126,6 @@ xmlParsePI(xmlParserCtxtPtr ctxt) {
|
|||||||
* this is a Processing Instruction.
|
* this is a Processing Instruction.
|
||||||
*/
|
*/
|
||||||
SKIP(2);
|
SKIP(2);
|
||||||
SHRINK;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parse the target name and check for special support like
|
* Parse the target name and check for special support like
|
||||||
@@ -5272,7 +5264,6 @@ xmlParseNotationDecl(xmlParserCtxtPtr ctxt) {
|
|||||||
|
|
||||||
if (CMP8(CUR_PTR, 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N')) {
|
if (CMP8(CUR_PTR, 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N')) {
|
||||||
int inputid = ctxt->input->id;
|
int inputid = ctxt->input->id;
|
||||||
SHRINK;
|
|
||||||
SKIP(8);
|
SKIP(8);
|
||||||
if (SKIP_BLANKS == 0) {
|
if (SKIP_BLANKS == 0) {
|
||||||
xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
|
xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
|
||||||
@@ -5360,7 +5351,6 @@ xmlParseEntityDecl(xmlParserCtxtPtr ctxt) {
|
|||||||
/* GROW; done in the caller */
|
/* GROW; done in the caller */
|
||||||
if (CMP6(CUR_PTR, 'E', 'N', 'T', 'I', 'T', 'Y')) {
|
if (CMP6(CUR_PTR, 'E', 'N', 'T', 'I', 'T', 'Y')) {
|
||||||
int inputid = ctxt->input->id;
|
int inputid = ctxt->input->id;
|
||||||
SHRINK;
|
|
||||||
SKIP(6);
|
SKIP(6);
|
||||||
if (SKIP_BLANKS == 0) {
|
if (SKIP_BLANKS == 0) {
|
||||||
xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
|
xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
|
||||||
@@ -5684,7 +5674,6 @@ xmlParseNotationType(xmlParserCtxtPtr ctxt) {
|
|||||||
xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_STARTED, NULL);
|
xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_STARTED, NULL);
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
SHRINK;
|
|
||||||
do {
|
do {
|
||||||
NEXT;
|
NEXT;
|
||||||
SKIP_BLANKS;
|
SKIP_BLANKS;
|
||||||
@@ -5756,7 +5745,6 @@ xmlParseEnumerationType(xmlParserCtxtPtr ctxt) {
|
|||||||
xmlFatalErr(ctxt, XML_ERR_ATTLIST_NOT_STARTED, NULL);
|
xmlFatalErr(ctxt, XML_ERR_ATTLIST_NOT_STARTED, NULL);
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
SHRINK;
|
|
||||||
do {
|
do {
|
||||||
NEXT;
|
NEXT;
|
||||||
SKIP_BLANKS;
|
SKIP_BLANKS;
|
||||||
@@ -5885,7 +5873,6 @@ xmlParseEnumeratedType(xmlParserCtxtPtr ctxt, xmlEnumerationPtr *tree) {
|
|||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
xmlParseAttributeType(xmlParserCtxtPtr ctxt, xmlEnumerationPtr *tree) {
|
xmlParseAttributeType(xmlParserCtxtPtr ctxt, xmlEnumerationPtr *tree) {
|
||||||
SHRINK;
|
|
||||||
if (CMP5(CUR_PTR, 'C', 'D', 'A', 'T', 'A')) {
|
if (CMP5(CUR_PTR, 'C', 'D', 'A', 'T', 'A')) {
|
||||||
SKIP(5);
|
SKIP(5);
|
||||||
return(XML_ATTRIBUTE_CDATA);
|
return(XML_ATTRIBUTE_CDATA);
|
||||||
@@ -6070,7 +6057,6 @@ xmlParseElementMixedContentDecl(xmlParserCtxtPtr ctxt, int inputchk) {
|
|||||||
if (CMP7(CUR_PTR, '#', 'P', 'C', 'D', 'A', 'T', 'A')) {
|
if (CMP7(CUR_PTR, '#', 'P', 'C', 'D', 'A', 'T', 'A')) {
|
||||||
SKIP(7);
|
SKIP(7);
|
||||||
SKIP_BLANKS;
|
SKIP_BLANKS;
|
||||||
SHRINK;
|
|
||||||
if (RAW == ')') {
|
if (RAW == ')') {
|
||||||
if (ctxt->input->id != inputchk) {
|
if (ctxt->input->id != inputchk) {
|
||||||
xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
|
xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
|
||||||
@@ -6242,7 +6228,6 @@ xmlParseElementChildrenContentDeclPriv(xmlParserCtxtPtr ctxt, int inputchk,
|
|||||||
GROW;
|
GROW;
|
||||||
}
|
}
|
||||||
SKIP_BLANKS;
|
SKIP_BLANKS;
|
||||||
SHRINK;
|
|
||||||
while ((RAW != ')') && (ctxt->instate != XML_PARSER_EOF)) {
|
while ((RAW != ')') && (ctxt->instate != XML_PARSER_EOF)) {
|
||||||
/*
|
/*
|
||||||
* Each loop we parse one separator and one element.
|
* Each loop we parse one separator and one element.
|
||||||
@@ -6787,6 +6772,7 @@ xmlParseConditionalSections(xmlParserCtxtPtr ctxt) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
SKIP_BLANKS;
|
SKIP_BLANKS;
|
||||||
|
SHRINK;
|
||||||
GROW;
|
GROW;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7018,6 +7004,7 @@ xmlParseExternalSubset(xmlParserCtxtPtr ctxt, const xmlChar *ExternalID,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SKIP_BLANKS;
|
SKIP_BLANKS;
|
||||||
|
SHRINK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RAW != 0) {
|
if (RAW != 0) {
|
||||||
@@ -8343,6 +8330,8 @@ xmlParseInternalSubset(xmlParserCtxtPtr ctxt) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SKIP_BLANKS;
|
SKIP_BLANKS;
|
||||||
|
SHRINK;
|
||||||
|
GROW;
|
||||||
}
|
}
|
||||||
if (RAW == ']') {
|
if (RAW == ']') {
|
||||||
NEXT;
|
NEXT;
|
||||||
@@ -9229,14 +9218,6 @@ xmlParseStartTag2(xmlParserCtxtPtr ctxt, const xmlChar **pref,
|
|||||||
if (RAW != '<') return(NULL);
|
if (RAW != '<') return(NULL);
|
||||||
NEXT1;
|
NEXT1;
|
||||||
|
|
||||||
/*
|
|
||||||
* NOTE: it is crucial with the SAX2 API to never call SHRINK beyond that
|
|
||||||
* point since the attribute values may be stored as pointers to
|
|
||||||
* the buffer and calling SHRINK would destroy them !
|
|
||||||
* The Shrinking is only possible once the full set of attribute
|
|
||||||
* callbacks have been done.
|
|
||||||
*/
|
|
||||||
SHRINK;
|
|
||||||
cur = ctxt->input->cur - ctxt->input->base;
|
cur = ctxt->input->cur - ctxt->input->base;
|
||||||
inputid = ctxt->input->id;
|
inputid = ctxt->input->id;
|
||||||
nbatts = 0;
|
nbatts = 0;
|
||||||
@@ -9881,8 +9862,8 @@ xmlParseContentInternal(xmlParserCtxtPtr ctxt) {
|
|||||||
xmlParseCharData(ctxt, 0);
|
xmlParseCharData(ctxt, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
GROW;
|
|
||||||
SHRINK;
|
SHRINK;
|
||||||
|
GROW;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -409,17 +409,16 @@ xmlParserInputGrow(xmlParserInputPtr in, int len) {
|
|||||||
* xmlParserShrink:
|
* xmlParserShrink:
|
||||||
* @ctxt: an XML parser context
|
* @ctxt: an XML parser context
|
||||||
*/
|
*/
|
||||||
int
|
void
|
||||||
xmlParserShrink(xmlParserCtxtPtr ctxt) {
|
xmlParserShrink(xmlParserCtxtPtr ctxt) {
|
||||||
xmlParserInputPtr in = ctxt->input;
|
xmlParserInputPtr in = ctxt->input;
|
||||||
xmlParserInputBufferPtr buf = in->buf;
|
xmlParserInputBufferPtr buf = in->buf;
|
||||||
size_t used;
|
size_t used;
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
/* Don't shrink memory buffers. */
|
/* Don't shrink memory buffers. */
|
||||||
if ((buf == NULL) ||
|
if ((buf == NULL) ||
|
||||||
((buf->encoder == NULL) && (buf->readcallback == NULL)))
|
((buf->encoder == NULL) && (buf->readcallback == NULL)))
|
||||||
return(0);
|
return;
|
||||||
|
|
||||||
used = in->cur - in->base;
|
used = in->cur - in->base;
|
||||||
/*
|
/*
|
||||||
@@ -439,18 +438,7 @@ xmlParserShrink(xmlParserCtxtPtr ctxt) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xmlBufUse(buf->buffer) < INPUT_CHUNK)
|
|
||||||
ret = xmlParserInputBufferGrow(buf, INPUT_CHUNK);
|
|
||||||
|
|
||||||
xmlBufSetInputBaseCur(buf->buffer, in, 0, used);
|
xmlBufSetInputBaseCur(buf->buffer, in, 0, used);
|
||||||
|
|
||||||
/* TODO: Get error code from xmlParserInputBufferGrow */
|
|
||||||
if (ret < 0) {
|
|
||||||
xmlErrInternal(ctxt, "Growing input buffer", NULL);
|
|
||||||
xmlHaltParser(ctxt);
|
|
||||||
}
|
|
||||||
|
|
||||||
return(ret);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user