From b167c7314497b6cb0d9a587a31874ae0d273ffaa Mon Sep 17 00:00:00 2001 From: Nick Wellnhofer Date: Tue, 14 Mar 2023 14:42:36 +0100 Subject: parser: Fix short-lived regression causing infinite loops Fix 3eb6bf03. We really have to halt the parser, so the input buffer gets reset. --- parserInternals.c | 49 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 9 deletions(-) (limited to 'parserInternals.c') diff --git a/parserInternals.c b/parserInternals.c index 90c428d1..a7f0aa95 100644 --- a/parserInternals.c +++ b/parserInternals.c @@ -258,6 +258,41 @@ void check_buffer(xmlParserInputPtr in) { #endif +/** + * xmlHaltParser: + * @ctxt: an XML parser context + * + * Blocks further parser processing don't override error + * for internal use + */ +void +xmlHaltParser(xmlParserCtxtPtr ctxt) { + if (ctxt == NULL) + return; + ctxt->instate = XML_PARSER_EOF; + ctxt->disableSAX = 1; + while (ctxt->inputNr > 1) + xmlFreeInputStream(inputPop(ctxt)); + if (ctxt->input != NULL) { + /* + * in case there was a specific allocation deallocate before + * overriding base + */ + if (ctxt->input->free != NULL) { + ctxt->input->free((xmlChar *) ctxt->input->base); + ctxt->input->free = NULL; + } + if (ctxt->input->buf != NULL) { + xmlFreeParserInputBuffer(ctxt->input->buf); + ctxt->input->buf = NULL; + } + ctxt->input->cur = BAD_CAST""; + ctxt->input->length = 0; + ctxt->input->base = ctxt->input->cur; + ctxt->input->end = ctxt->input->cur; + } +} + /** * xmlParserInputRead: * @in: an XML parser input @@ -293,8 +328,8 @@ xmlParserGrow(xmlParserCtxtPtr ctxt) { if (((curEnd > XML_MAX_LOOKUP_LIMIT) || (curBase > XML_MAX_LOOKUP_LIMIT)) && ((ctxt->options & XML_PARSE_HUGE) == 0)) { + xmlHaltParser(ctxt); xmlErrInternal(ctxt, "Huge input lookup", NULL); - ctxt->instate = XML_PARSER_EOF; return(-1); } @@ -305,9 +340,7 @@ xmlParserGrow(xmlParserCtxtPtr ctxt) { in->base = xmlBufContent(buf->buffer); if (in->base == NULL) { - in->base = BAD_CAST ""; - in->cur = in->base; - in->end = in->base; + xmlHaltParser(ctxt); xmlErrMemory(ctxt, NULL); return(-1); } @@ -316,8 +349,8 @@ xmlParserGrow(xmlParserCtxtPtr ctxt) { /* TODO: Get error code from xmlParserInputBufferGrow */ if (ret < 0) { + xmlHaltParser(ctxt); xmlErrInternal(ctxt, "Growing input buffer", NULL); - ctxt->instate = XML_PARSER_EOF; } return(ret); @@ -419,9 +452,7 @@ xmlParserShrink(xmlParserCtxtPtr ctxt) { in->base = xmlBufContent(buf->buffer); if (in->base == NULL) { - in->base = BAD_CAST ""; - in->cur = in->base; - in->end = in->base; + xmlHaltParser(ctxt); xmlErrMemory(ctxt, NULL); return(-1); } @@ -430,8 +461,8 @@ xmlParserShrink(xmlParserCtxtPtr ctxt) { /* TODO: Get error code from xmlParserInputBufferGrow */ if (ret < 0) { + xmlHaltParser(ctxt); xmlErrInternal(ctxt, "Growing input buffer", NULL); - ctxt->instate = XML_PARSER_EOF; } return(ret); -- cgit v1.2.1