1
0
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:
Nick Wellnhofer
2023-03-21 13:08:44 +01:00
parent 44ecefc8cc
commit 04d1bedd8c
4 changed files with 10 additions and 44 deletions

View File

@@ -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);
} }

View File

@@ -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__ */

View File

@@ -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;
} }
} }

View File

@@ -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);
} }
/** /**