1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-07-29 11:41:22 +03:00

html: Check reallocations for overflow

This commit is contained in:
Nick Wellnhofer
2024-12-15 21:17:07 +01:00
parent 8231c03663
commit 0447275ef8

View File

@ -41,10 +41,12 @@
#include "private/error.h" #include "private/error.h"
#include "private/html.h" #include "private/html.h"
#include "private/io.h" #include "private/io.h"
#include "private/memory.h"
#include "private/parser.h" #include "private/parser.h"
#include "private/tree.h" #include "private/tree.h"
#define HTML_MAX_NAMELEN 1000 #define HTML_MAX_NAMELEN 1000
#define HTML_MAX_ATTRS 100000000 /* 100 million */
#define HTML_PARSER_BIG_BUFFER_SIZE 1000 #define HTML_PARSER_BIG_BUFFER_SIZE 1000
#define HTML_PARSER_BUFFER_SIZE 100 #define HTML_PARSER_BUFFER_SIZE 100
@ -158,15 +160,20 @@ htmlnamePush(htmlParserCtxtPtr ctxt, const xmlChar * value)
if ((ctxt->html < 10) && (xmlStrEqual(value, BAD_CAST "body"))) if ((ctxt->html < 10) && (xmlStrEqual(value, BAD_CAST "body")))
ctxt->html = 10; ctxt->html = 10;
if (ctxt->nameNr >= ctxt->nameMax) { if (ctxt->nameNr >= ctxt->nameMax) {
size_t newSize = ctxt->nameMax * 2;
const xmlChar **tmp; const xmlChar **tmp;
int newSize;
tmp = xmlRealloc((xmlChar **) ctxt->nameTab, newSize = xmlGrowCapacity(ctxt->nameMax, sizeof(tmp[0]),
newSize * sizeof(ctxt->nameTab[0])); 10, XML_MAX_ITEMS);
if (tmp == NULL) { if (newSize < 0) {
htmlErrMemory(ctxt); htmlErrMemory(ctxt);
return (-1); return (-1);
} }
tmp = xmlRealloc(ctxt->nameTab, newSize * sizeof(tmp[0]));
if (tmp == NULL) {
htmlErrMemory(ctxt);
return(-1);
}
ctxt->nameTab = tmp; ctxt->nameTab = tmp;
ctxt->nameMax = newSize; ctxt->nameMax = newSize;
} }
@ -214,17 +221,22 @@ static int
htmlNodeInfoPush(htmlParserCtxtPtr ctxt, htmlParserNodeInfo *value) htmlNodeInfoPush(htmlParserCtxtPtr ctxt, htmlParserNodeInfo *value)
{ {
if (ctxt->nodeInfoNr >= ctxt->nodeInfoMax) { if (ctxt->nodeInfoNr >= ctxt->nodeInfoMax) {
if (ctxt->nodeInfoMax == 0) xmlParserNodeInfo *tmp;
ctxt->nodeInfoMax = 5; int newSize;
ctxt->nodeInfoMax *= 2;
ctxt->nodeInfoTab = (htmlParserNodeInfo *) newSize = xmlGrowCapacity(ctxt->nodeInfoMax, sizeof(tmp[0]),
xmlRealloc((htmlParserNodeInfo *)ctxt->nodeInfoTab, 5, XML_MAX_ITEMS);
ctxt->nodeInfoMax * if (newSize < 0) {
sizeof(ctxt->nodeInfoTab[0]));
if (ctxt->nodeInfoTab == NULL) {
htmlErrMemory(ctxt); htmlErrMemory(ctxt);
return (0); return (0);
} }
tmp = xmlRealloc(ctxt->nodeInfoTab, newSize * sizeof(tmp[0]));
if (tmp == NULL) {
htmlErrMemory(ctxt);
return (0);
}
ctxt->nodeInfoTab = tmp;
ctxt->nodeInfoMax = newSize;
} }
ctxt->nodeInfoTab[ctxt->nodeInfoNr] = *value; ctxt->nodeInfoTab[ctxt->nodeInfoNr] = *value;
ctxt->nodeInfo = &ctxt->nodeInfoTab[ctxt->nodeInfoNr]; ctxt->nodeInfo = &ctxt->nodeInfoTab[ctxt->nodeInfoNr];
@ -2835,7 +2847,7 @@ next_chunk:
if (extraSize > buffer_size - used) { if (extraSize > buffer_size - used) {
size_t newSize = (used + extraSize) * 2; size_t newSize = (used + extraSize) * 2;
xmlChar *tmp = (xmlChar *) xmlRealloc(buffer, newSize + 1); xmlChar *tmp = xmlRealloc(buffer, newSize + 1);
if (tmp == NULL) { if (tmp == NULL) {
htmlErrMemory(ctxt); htmlErrMemory(ctxt);
@ -3804,47 +3816,49 @@ htmlParseStartTag(htmlParserCtxtPtr ctxt) {
if (nbatts + 4 > maxatts) { if (nbatts + 4 > maxatts) {
const xmlChar **tmp; const xmlChar **tmp;
unsigned *utmp; unsigned *utmp;
size_t newSize = maxatts ? maxatts * 2 : 22; int newSize;
tmp = xmlMalloc(newSize * sizeof(tmp[0])); newSize = xmlGrowCapacity(maxatts,
sizeof(tmp[0]) * 2 + sizeof(utmp[0]),
11, HTML_MAX_ATTRS);
if (newSize < 0) {
htmlErrMemory(ctxt);
goto failed;
}
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
if (newSize < 2)
newSize = 2;
#endif
tmp = xmlRealloc(atts, newSize * sizeof(tmp[0]) * 2);
if (tmp == NULL) { if (tmp == NULL) {
htmlErrMemory(ctxt); htmlErrMemory(ctxt);
if (attvalue != NULL)
xmlFree(attvalue);
goto failed; goto failed;
} }
atts = tmp;
ctxt->atts = tmp;
utmp = xmlRealloc(ctxt->attallocs, utmp = xmlRealloc(ctxt->attallocs, newSize * sizeof(utmp[0]));
newSize / 2 * sizeof(utmp[0]));
if (utmp == NULL) { if (utmp == NULL) {
htmlErrMemory(ctxt); htmlErrMemory(ctxt);
if (attvalue != NULL)
xmlFree(attvalue);
xmlFree(tmp);
goto failed; goto failed;
} }
if (maxatts > 0)
memcpy(tmp, atts, maxatts * sizeof(tmp[0]));
xmlFree(atts);
atts = tmp;
maxatts = newSize;
ctxt->atts = atts;
ctxt->attallocs = utmp; ctxt->attallocs = utmp;
maxatts = newSize * 2;
ctxt->maxatts = maxatts; ctxt->maxatts = maxatts;
} }
ctxt->attallocs[nbatts/2] = hattname.hashValue; ctxt->attallocs[nbatts/2] = hattname.hashValue;
atts[nbatts++] = attname; atts[nbatts++] = attname;
atts[nbatts++] = attvalue; atts[nbatts++] = attvalue;
}
else { attvalue = NULL;
if (attvalue != NULL)
xmlFree(attvalue);
} }
failed: failed:
if (attvalue != NULL)
xmlFree(attvalue);
SKIP_BLANKS; SKIP_BLANKS;
} }