mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2025-10-21 14:53:44 +03:00
regexp: Check reallocations for overflow
This commit is contained in:
174
xmlregexp.c
174
xmlregexp.c
@@ -30,6 +30,7 @@
|
|||||||
#include <libxml/xmlunicode.h>
|
#include <libxml/xmlunicode.h>
|
||||||
|
|
||||||
#include "private/error.h"
|
#include "private/error.h"
|
||||||
|
#include "private/memory.h"
|
||||||
#include "private/regexp.h"
|
#include "private/regexp.h"
|
||||||
|
|
||||||
#ifndef SIZE_MAX
|
#ifndef SIZE_MAX
|
||||||
@@ -1174,26 +1175,23 @@ xmlRegAtomAddRange(xmlRegParserCtxtPtr ctxt, xmlRegAtomPtr atom,
|
|||||||
ERROR("add range: atom is not ranges");
|
ERROR("add range: atom is not ranges");
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
if (atom->maxRanges == 0) {
|
if (atom->nbRanges >= atom->maxRanges) {
|
||||||
atom->maxRanges = 4;
|
|
||||||
atom->ranges = (xmlRegRangePtr *) xmlMalloc(atom->maxRanges *
|
|
||||||
sizeof(xmlRegRangePtr));
|
|
||||||
if (atom->ranges == NULL) {
|
|
||||||
xmlRegexpErrMemory(ctxt);
|
|
||||||
atom->maxRanges = 0;
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
} else if (atom->nbRanges >= atom->maxRanges) {
|
|
||||||
xmlRegRangePtr *tmp;
|
xmlRegRangePtr *tmp;
|
||||||
atom->maxRanges *= 2;
|
int newSize;
|
||||||
tmp = (xmlRegRangePtr *) xmlRealloc(atom->ranges, atom->maxRanges *
|
|
||||||
sizeof(xmlRegRangePtr));
|
newSize = xmlGrowCapacity(atom->maxRanges, sizeof(tmp[0]),
|
||||||
|
4, XML_MAX_ITEMS);
|
||||||
|
if (newSize < 0) {
|
||||||
|
xmlRegexpErrMemory(ctxt);
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
tmp = xmlRealloc(atom->ranges, newSize * sizeof(tmp[0]));
|
||||||
if (tmp == NULL) {
|
if (tmp == NULL) {
|
||||||
xmlRegexpErrMemory(ctxt);
|
xmlRegexpErrMemory(ctxt);
|
||||||
atom->maxRanges /= 2;
|
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
atom->ranges = tmp;
|
atom->ranges = tmp;
|
||||||
|
atom->maxRanges = newSize;
|
||||||
}
|
}
|
||||||
range = xmlRegNewRange(ctxt, neg, type, start, end);
|
range = xmlRegNewRange(ctxt, neg, type, start, end);
|
||||||
if (range == NULL)
|
if (range == NULL)
|
||||||
@@ -1206,26 +1204,23 @@ xmlRegAtomAddRange(xmlRegParserCtxtPtr ctxt, xmlRegAtomPtr atom,
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
xmlRegGetCounter(xmlRegParserCtxtPtr ctxt) {
|
xmlRegGetCounter(xmlRegParserCtxtPtr ctxt) {
|
||||||
if (ctxt->maxCounters == 0) {
|
if (ctxt->nbCounters >= ctxt->maxCounters) {
|
||||||
ctxt->maxCounters = 4;
|
xmlRegCounter *tmp;
|
||||||
ctxt->counters = (xmlRegCounter *) xmlMalloc(ctxt->maxCounters *
|
int newSize;
|
||||||
sizeof(xmlRegCounter));
|
|
||||||
if (ctxt->counters == NULL) {
|
newSize = xmlGrowCapacity(ctxt->maxCounters, sizeof(tmp[0]),
|
||||||
|
4, XML_MAX_ITEMS);
|
||||||
|
if (newSize < 0) {
|
||||||
xmlRegexpErrMemory(ctxt);
|
xmlRegexpErrMemory(ctxt);
|
||||||
ctxt->maxCounters = 0;
|
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
} else if (ctxt->nbCounters >= ctxt->maxCounters) {
|
tmp = xmlRealloc(ctxt->counters, newSize * sizeof(tmp[0]));
|
||||||
xmlRegCounter *tmp;
|
|
||||||
ctxt->maxCounters *= 2;
|
|
||||||
tmp = (xmlRegCounter *) xmlRealloc(ctxt->counters, ctxt->maxCounters *
|
|
||||||
sizeof(xmlRegCounter));
|
|
||||||
if (tmp == NULL) {
|
if (tmp == NULL) {
|
||||||
xmlRegexpErrMemory(ctxt);
|
xmlRegexpErrMemory(ctxt);
|
||||||
ctxt->maxCounters /= 2;
|
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
ctxt->counters = tmp;
|
ctxt->counters = tmp;
|
||||||
|
ctxt->maxCounters = newSize;
|
||||||
}
|
}
|
||||||
ctxt->counters[ctxt->nbCounters].min = -1;
|
ctxt->counters[ctxt->nbCounters].min = -1;
|
||||||
ctxt->counters[ctxt->nbCounters].max = -1;
|
ctxt->counters[ctxt->nbCounters].max = -1;
|
||||||
@@ -1239,10 +1234,16 @@ xmlRegAtomPush(xmlRegParserCtxtPtr ctxt, xmlRegAtomPtr atom) {
|
|||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
if (ctxt->nbAtoms >= ctxt->maxAtoms) {
|
if (ctxt->nbAtoms >= ctxt->maxAtoms) {
|
||||||
size_t newSize = ctxt->maxAtoms ? ctxt->maxAtoms * 2 : 4;
|
|
||||||
xmlRegAtomPtr *tmp;
|
xmlRegAtomPtr *tmp;
|
||||||
|
int newSize;
|
||||||
|
|
||||||
tmp = xmlRealloc(ctxt->atoms, newSize * sizeof(xmlRegAtomPtr));
|
newSize = xmlGrowCapacity(ctxt->maxAtoms, sizeof(tmp[0]),
|
||||||
|
4, XML_MAX_ITEMS);
|
||||||
|
if (newSize < 0) {
|
||||||
|
xmlRegexpErrMemory(ctxt);
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
tmp = xmlRealloc(ctxt->atoms, newSize * sizeof(tmp[0]));
|
||||||
if (tmp == NULL) {
|
if (tmp == NULL) {
|
||||||
xmlRegexpErrMemory(ctxt);
|
xmlRegexpErrMemory(ctxt);
|
||||||
return(-1);
|
return(-1);
|
||||||
@@ -1258,26 +1259,23 @@ xmlRegAtomPush(xmlRegParserCtxtPtr ctxt, xmlRegAtomPtr atom) {
|
|||||||
static void
|
static void
|
||||||
xmlRegStateAddTransTo(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr target,
|
xmlRegStateAddTransTo(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr target,
|
||||||
int from) {
|
int from) {
|
||||||
if (target->maxTransTo == 0) {
|
if (target->nbTransTo >= target->maxTransTo) {
|
||||||
target->maxTransTo = 8;
|
int *tmp;
|
||||||
target->transTo = (int *) xmlMalloc(target->maxTransTo *
|
int newSize;
|
||||||
sizeof(int));
|
|
||||||
if (target->transTo == NULL) {
|
newSize = xmlGrowCapacity(target->maxTransTo, sizeof(tmp[0]),
|
||||||
|
8, XML_MAX_ITEMS);
|
||||||
|
if (newSize < 0) {
|
||||||
xmlRegexpErrMemory(ctxt);
|
xmlRegexpErrMemory(ctxt);
|
||||||
target->maxTransTo = 0;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (target->nbTransTo >= target->maxTransTo) {
|
tmp = xmlRealloc(target->transTo, newSize * sizeof(tmp[0]));
|
||||||
int *tmp;
|
|
||||||
target->maxTransTo *= 2;
|
|
||||||
tmp = (int *) xmlRealloc(target->transTo, target->maxTransTo *
|
|
||||||
sizeof(int));
|
|
||||||
if (tmp == NULL) {
|
if (tmp == NULL) {
|
||||||
xmlRegexpErrMemory(ctxt);
|
xmlRegexpErrMemory(ctxt);
|
||||||
target->maxTransTo /= 2;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
target->transTo = tmp;
|
target->transTo = tmp;
|
||||||
|
target->maxTransTo = newSize;
|
||||||
}
|
}
|
||||||
target->transTo[target->nbTransTo] = from;
|
target->transTo[target->nbTransTo] = from;
|
||||||
target->nbTransTo++;
|
target->nbTransTo++;
|
||||||
@@ -1314,26 +1312,23 @@ xmlRegStateAddTrans(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr state,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state->maxTrans == 0) {
|
if (state->nbTrans >= state->maxTrans) {
|
||||||
state->maxTrans = 8;
|
xmlRegTrans *tmp;
|
||||||
state->trans = (xmlRegTrans *) xmlMalloc(state->maxTrans *
|
int newSize;
|
||||||
sizeof(xmlRegTrans));
|
|
||||||
if (state->trans == NULL) {
|
newSize = xmlGrowCapacity(state->maxTrans, sizeof(tmp[0]),
|
||||||
|
8, XML_MAX_ITEMS);
|
||||||
|
if (newSize < 0) {
|
||||||
xmlRegexpErrMemory(ctxt);
|
xmlRegexpErrMemory(ctxt);
|
||||||
state->maxTrans = 0;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (state->nbTrans >= state->maxTrans) {
|
tmp = xmlRealloc(state->trans, newSize * sizeof(tmp[0]));
|
||||||
xmlRegTrans *tmp;
|
|
||||||
state->maxTrans *= 2;
|
|
||||||
tmp = (xmlRegTrans *) xmlRealloc(state->trans, state->maxTrans *
|
|
||||||
sizeof(xmlRegTrans));
|
|
||||||
if (tmp == NULL) {
|
if (tmp == NULL) {
|
||||||
xmlRegexpErrMemory(ctxt);
|
xmlRegexpErrMemory(ctxt);
|
||||||
state->maxTrans /= 2;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
state->trans = tmp;
|
state->trans = tmp;
|
||||||
|
state->maxTrans = newSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
state->trans[state->nbTrans].atom = atom;
|
state->trans[state->nbTrans].atom = atom;
|
||||||
@@ -1350,9 +1345,15 @@ xmlRegStatePush(xmlRegParserCtxtPtr ctxt) {
|
|||||||
xmlRegStatePtr state;
|
xmlRegStatePtr state;
|
||||||
|
|
||||||
if (ctxt->nbStates >= ctxt->maxStates) {
|
if (ctxt->nbStates >= ctxt->maxStates) {
|
||||||
size_t newSize = ctxt->maxStates ? ctxt->maxStates * 2 : 4;
|
|
||||||
xmlRegStatePtr *tmp;
|
xmlRegStatePtr *tmp;
|
||||||
|
int newSize;
|
||||||
|
|
||||||
|
newSize = xmlGrowCapacity(ctxt->maxStates, sizeof(tmp[0]),
|
||||||
|
4, XML_MAX_ITEMS);
|
||||||
|
if (newSize < 0) {
|
||||||
|
xmlRegexpErrMemory(ctxt);
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
tmp = xmlRealloc(ctxt->states, newSize * sizeof(tmp[0]));
|
tmp = xmlRealloc(ctxt->states, newSize * sizeof(tmp[0]));
|
||||||
if (tmp == NULL) {
|
if (tmp == NULL) {
|
||||||
xmlRegexpErrMemory(ctxt);
|
xmlRegexpErrMemory(ctxt);
|
||||||
@@ -3034,30 +3035,24 @@ xmlFARegExecSave(xmlRegExecCtxtPtr exec) {
|
|||||||
exec->nbPush++;
|
exec->nbPush++;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (exec->maxRollbacks == 0) {
|
if (exec->nbRollbacks >= exec->maxRollbacks) {
|
||||||
exec->maxRollbacks = 4;
|
xmlRegExecRollback *tmp;
|
||||||
exec->rollbacks = (xmlRegExecRollback *) xmlMalloc(exec->maxRollbacks *
|
int newSize;
|
||||||
sizeof(xmlRegExecRollback));
|
int len = exec->nbRollbacks;
|
||||||
if (exec->rollbacks == NULL) {
|
|
||||||
exec->maxRollbacks = 0;
|
newSize = xmlGrowCapacity(exec->maxRollbacks, sizeof(tmp[0]),
|
||||||
|
4, XML_MAX_ITEMS);
|
||||||
|
if (newSize < 0) {
|
||||||
exec->status = XML_REGEXP_OUT_OF_MEMORY;
|
exec->status = XML_REGEXP_OUT_OF_MEMORY;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memset(exec->rollbacks, 0,
|
tmp = xmlRealloc(exec->rollbacks, newSize * sizeof(tmp[0]));
|
||||||
exec->maxRollbacks * sizeof(xmlRegExecRollback));
|
|
||||||
} else if (exec->nbRollbacks >= exec->maxRollbacks) {
|
|
||||||
xmlRegExecRollback *tmp;
|
|
||||||
int len = exec->maxRollbacks;
|
|
||||||
|
|
||||||
exec->maxRollbacks *= 2;
|
|
||||||
tmp = (xmlRegExecRollback *) xmlRealloc(exec->rollbacks,
|
|
||||||
exec->maxRollbacks * sizeof(xmlRegExecRollback));
|
|
||||||
if (tmp == NULL) {
|
if (tmp == NULL) {
|
||||||
exec->maxRollbacks /= 2;
|
|
||||||
exec->status = XML_REGEXP_OUT_OF_MEMORY;
|
exec->status = XML_REGEXP_OUT_OF_MEMORY;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
exec->rollbacks = tmp;
|
exec->rollbacks = tmp;
|
||||||
|
exec->maxRollbacks = newSize;
|
||||||
tmp = &exec->rollbacks[len];
|
tmp = &exec->rollbacks[len];
|
||||||
memset(tmp, 0, (exec->maxRollbacks - len) * sizeof(xmlRegExecRollback));
|
memset(tmp, 0, (exec->maxRollbacks - len) * sizeof(xmlRegExecRollback));
|
||||||
}
|
}
|
||||||
@@ -3512,27 +3507,27 @@ xmlRegExecSetErrString(xmlRegExecCtxtPtr exec, const xmlChar *value) {
|
|||||||
static void
|
static void
|
||||||
xmlFARegExecSaveInputString(xmlRegExecCtxtPtr exec, const xmlChar *value,
|
xmlFARegExecSaveInputString(xmlRegExecCtxtPtr exec, const xmlChar *value,
|
||||||
void *data) {
|
void *data) {
|
||||||
if (exec->inputStackMax == 0) {
|
if (exec->inputStackNr + 1 >= exec->inputStackMax) {
|
||||||
exec->inputStackMax = 4;
|
xmlRegInputTokenPtr tmp;
|
||||||
exec->inputStack = (xmlRegInputTokenPtr)
|
int newSize;
|
||||||
xmlMalloc(exec->inputStackMax * sizeof(xmlRegInputToken));
|
|
||||||
if (exec->inputStack == NULL) {
|
newSize = xmlGrowCapacity(exec->inputStackMax, sizeof(tmp[0]),
|
||||||
exec->inputStackMax = 0;
|
4, XML_MAX_ITEMS);
|
||||||
|
if (newSize < 0) {
|
||||||
exec->status = XML_REGEXP_OUT_OF_MEMORY;
|
exec->status = XML_REGEXP_OUT_OF_MEMORY;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (exec->inputStackNr + 1 >= exec->inputStackMax) {
|
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
||||||
xmlRegInputTokenPtr tmp;
|
if (newSize < 2)
|
||||||
|
newSize = 2;
|
||||||
exec->inputStackMax *= 2;
|
#endif
|
||||||
tmp = (xmlRegInputTokenPtr) xmlRealloc(exec->inputStack,
|
tmp = xmlRealloc(exec->inputStack, newSize * sizeof(tmp[0]));
|
||||||
exec->inputStackMax * sizeof(xmlRegInputToken));
|
|
||||||
if (tmp == NULL) {
|
if (tmp == NULL) {
|
||||||
exec->inputStackMax /= 2;
|
|
||||||
exec->status = XML_REGEXP_OUT_OF_MEMORY;
|
exec->status = XML_REGEXP_OUT_OF_MEMORY;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
exec->inputStack = tmp;
|
exec->inputStack = tmp;
|
||||||
|
exec->inputStackMax = newSize;
|
||||||
}
|
}
|
||||||
if (value == NULL) {
|
if (value == NULL) {
|
||||||
exec->inputStack[exec->inputStackNr].value = NULL;
|
exec->inputStack[exec->inputStackNr].value = NULL;
|
||||||
@@ -7514,14 +7509,21 @@ xmlExpExpDeriveInt(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, xmlExpNodePtr sub) {
|
|||||||
len = xmlExpGetStartInt(ctxt, sub, tab, ctxt->tabSize, 0);
|
len = xmlExpGetStartInt(ctxt, sub, tab, ctxt->tabSize, 0);
|
||||||
while (len < 0) {
|
while (len < 0) {
|
||||||
const xmlChar **temp;
|
const xmlChar **temp;
|
||||||
temp = (const xmlChar **) xmlRealloc((xmlChar **) tab, ctxt->tabSize * 2 *
|
int newSize;
|
||||||
sizeof(const xmlChar *));
|
|
||||||
|
newSize = xmlGrowCapacity(ctxt->tabSize, sizeof(temp[0]),
|
||||||
|
40, XML_MAX_ITEMS);
|
||||||
|
if (newSize < 0) {
|
||||||
|
xmlFree(tab);
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
temp = xmlRealloc(tab, newSize * sizeof(temp[0]));
|
||||||
if (temp == NULL) {
|
if (temp == NULL) {
|
||||||
xmlFree((xmlChar **) tab);
|
xmlFree(tab);
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
tab = temp;
|
tab = temp;
|
||||||
ctxt->tabSize *= 2;
|
ctxt->tabSize = newSize;
|
||||||
len = xmlExpGetStartInt(ctxt, sub, tab, ctxt->tabSize, 0);
|
len = xmlExpGetStartInt(ctxt, sub, tab, ctxt->tabSize, 0);
|
||||||
}
|
}
|
||||||
for (i = 0;i < len;i++) {
|
for (i = 0;i < len;i++) {
|
||||||
|
Reference in New Issue
Block a user