1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-10-21 14:53:44 +03:00

malloc-fail: Fix memory leak after xmlRegNewState

Invoke xmlRegNewState from xmlRegStatePush to simplify error handling.

Found with libFuzzer, see #344.
This commit is contained in:
Nick Wellnhofer
2023-02-15 01:00:03 +01:00
parent cb4334b7ab
commit e60c9f4c4b

View File

@@ -1439,33 +1439,31 @@ xmlRegStateAddTrans(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr state,
xmlRegStateAddTransTo(ctxt, target, state->no);
}
static int
xmlRegStatePush(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr state) {
if (state == NULL) return(-1);
if (ctxt->maxStates == 0) {
ctxt->maxStates = 4;
ctxt->states = (xmlRegStatePtr *) xmlMalloc(ctxt->maxStates *
sizeof(xmlRegStatePtr));
if (ctxt->states == NULL) {
xmlRegexpErrMemory(ctxt, "adding state");
ctxt->maxStates = 0;
return(-1);
}
} else if (ctxt->nbStates >= ctxt->maxStates) {
static xmlRegStatePtr
xmlRegStatePush(xmlRegParserCtxtPtr ctxt) {
xmlRegStatePtr state;
if (ctxt->nbStates >= ctxt->maxStates) {
size_t newSize = ctxt->maxStates ? ctxt->maxStates * 2 : 4;
xmlRegStatePtr *tmp;
ctxt->maxStates *= 2;
tmp = (xmlRegStatePtr *) xmlRealloc(ctxt->states, ctxt->maxStates *
sizeof(xmlRegStatePtr));
tmp = xmlRealloc(ctxt->states, newSize * sizeof(tmp[0]));
if (tmp == NULL) {
xmlRegexpErrMemory(ctxt, "adding state");
ctxt->maxStates /= 2;
return(-1);
return(NULL);
}
ctxt->states = tmp;
ctxt->maxStates = newSize;
}
state = xmlRegNewState(ctxt);
if (state == NULL)
return(NULL);
state->no = ctxt->nbStates;
ctxt->states[ctxt->nbStates++] = state;
return(0);
return(state);
}
/**
@@ -1476,19 +1474,21 @@ xmlRegStatePush(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr state) {
* @lax:
*
*/
static void
static int
xmlFAGenerateAllTransition(xmlRegParserCtxtPtr ctxt,
xmlRegStatePtr from, xmlRegStatePtr to,
int lax) {
if (to == NULL) {
to = xmlRegNewState(ctxt);
xmlRegStatePush(ctxt, to);
to = xmlRegStatePush(ctxt);
if (to == NULL)
return(-1);
ctxt->state = to;
}
if (lax)
xmlRegStateAddTrans(ctxt, from, NULL, to, -1, REGEXP_ALL_LAX_COUNTER);
else
xmlRegStateAddTrans(ctxt, from, NULL, to, -1, REGEXP_ALL_COUNTER);
return(0);
}
/**
@@ -1498,15 +1498,17 @@ xmlFAGenerateAllTransition(xmlRegParserCtxtPtr ctxt,
* @to: the target state or NULL for building a new one
*
*/
static void
static int
xmlFAGenerateEpsilonTransition(xmlRegParserCtxtPtr ctxt,
xmlRegStatePtr from, xmlRegStatePtr to) {
if (to == NULL) {
to = xmlRegNewState(ctxt);
xmlRegStatePush(ctxt, to);
to = xmlRegStatePush(ctxt);
if (to == NULL)
return(-1);
ctxt->state = to;
}
xmlRegStateAddTrans(ctxt, from, NULL, to, -1, -1);
return(0);
}
/**
@@ -1517,15 +1519,17 @@ xmlFAGenerateEpsilonTransition(xmlRegParserCtxtPtr ctxt,
* counter: the counter for that transition
*
*/
static void
static int
xmlFAGenerateCountedEpsilonTransition(xmlRegParserCtxtPtr ctxt,
xmlRegStatePtr from, xmlRegStatePtr to, int counter) {
if (to == NULL) {
to = xmlRegNewState(ctxt);
xmlRegStatePush(ctxt, to);
to = xmlRegStatePush(ctxt);
if (to == NULL)
return(-1);
ctxt->state = to;
}
xmlRegStateAddTrans(ctxt, from, NULL, to, counter, -1);
return(0);
}
/**
@@ -1536,15 +1540,17 @@ xmlFAGenerateCountedEpsilonTransition(xmlRegParserCtxtPtr ctxt,
* counter: the counter for that transition
*
*/
static void
static int
xmlFAGenerateCountedTransition(xmlRegParserCtxtPtr ctxt,
xmlRegStatePtr from, xmlRegStatePtr to, int counter) {
if (to == NULL) {
to = xmlRegNewState(ctxt);
xmlRegStatePush(ctxt, to);
to = xmlRegStatePush(ctxt);
if (to == NULL)
return(-1);
ctxt->state = to;
}
xmlRegStateAddTrans(ctxt, from, NULL, to, -1, counter);
return(0);
}
/**
@@ -1583,8 +1589,9 @@ xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr from,
#ifdef DV
} else if ((to == NULL) && (atom->quant != XML_REGEXP_QUANT_RANGE) &&
(atom->quant != XML_REGEXP_QUANT_ONCE)) {
to = xmlRegNewState(ctxt);
xmlRegStatePush(ctxt, to);
to = xmlRegStatePush(ctxt, to);
if (to == NULL)
return(-1);
ctxt->state = to;
xmlFAGenerateEpsilonTransition(ctxt, atom->stop, to);
#endif
@@ -1624,8 +1631,9 @@ xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr from,
if (to != NULL) {
newstate = to;
} else {
newstate = xmlRegNewState(ctxt);
xmlRegStatePush(ctxt, newstate);
newstate = xmlRegStatePush(ctxt);
if (newstate == NULL)
return(-1);
}
/*
@@ -1705,12 +1713,9 @@ xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr from,
* we can discard the atom and generate an epsilon transition instead
*/
if (to == NULL) {
to = xmlRegNewState(ctxt);
if (to != NULL)
xmlRegStatePush(ctxt, to);
else {
to = xmlRegStatePush(ctxt);
if (to == NULL)
return(-1);
}
}
xmlFAGenerateEpsilonTransition(ctxt, from, to);
ctxt->state = to;
@@ -1718,12 +1723,9 @@ xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr from,
return(0);
}
if (to == NULL) {
to = xmlRegNewState(ctxt);
if (to != NULL)
xmlRegStatePush(ctxt, to);
else {
to = xmlRegStatePush(ctxt);
if (to == NULL)
return(-1);
}
}
end = to;
if ((atom->quant == XML_REGEXP_QUANT_MULT) ||
@@ -1735,12 +1737,9 @@ xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr from,
*/
xmlRegStatePtr tmp;
tmp = xmlRegNewState(ctxt);
if (tmp != NULL)
xmlRegStatePush(ctxt, tmp);
else {
tmp = xmlRegStatePush(ctxt);
if (tmp == NULL)
return(-1);
}
xmlFAGenerateEpsilonTransition(ctxt, tmp, to);
to = tmp;
}
@@ -5612,9 +5611,11 @@ xmlRegexpCompile(const xmlChar *regexp) {
return(NULL);
/* initialize the parser */
ctxt->state = xmlRegStatePush(ctxt);
if (ctxt->state == NULL)
return(NULL);
ctxt->start = ctxt->state;
ctxt->end = NULL;
ctxt->start = ctxt->state = xmlRegNewState(ctxt);
xmlRegStatePush(ctxt, ctxt->start);
/* parse the expression building an automata */
xmlFAParseRegExp(ctxt, 1);
@@ -5762,18 +5763,15 @@ xmlNewAutomata(void) {
return(NULL);
/* initialize the parser */
ctxt->state = xmlRegStatePush(ctxt);
if (ctxt->state == NULL) {
xmlFreeAutomata(ctxt);
return(NULL);
}
ctxt->start = ctxt->state;
ctxt->end = NULL;
ctxt->start = ctxt->state = xmlRegNewState(ctxt);
if (ctxt->start == NULL) {
xmlFreeAutomata(ctxt);
return(NULL);
}
ctxt->start->type = XML_REGEXP_START_STATE;
if (xmlRegStatePush(ctxt, ctxt->start) < 0) {
xmlRegFreeState(ctxt->start);
xmlFreeAutomata(ctxt);
return(NULL);
}
ctxt->flags = 0;
return(ctxt);
@@ -6071,8 +6069,9 @@ xmlAutomataNewCountTrans2(xmlAutomataPtr am, xmlAutomataStatePtr from,
/* xmlFAGenerateTransitions(am, from, to, atom); */
if (to == NULL) {
to = xmlRegNewState(am);
xmlRegStatePush(am, to);
to = xmlRegStatePush(am);
if (to == NULL)
return(NULL);
}
xmlRegStateAddTrans(am, from, atom, to, counter, -1);
xmlRegAtomPush(am, atom);
@@ -6137,8 +6136,9 @@ xmlAutomataNewCountTrans(xmlAutomataPtr am, xmlAutomataStatePtr from,
/* xmlFAGenerateTransitions(am, from, to, atom); */
if (to == NULL) {
to = xmlRegNewState(am);
xmlRegStatePush(am, to);
to = xmlRegStatePush(am);
if (to == NULL)
return(NULL);
}
xmlRegStateAddTrans(am, from, atom, to, counter, -1);
xmlRegAtomPush(am, atom);
@@ -6223,8 +6223,9 @@ xmlAutomataNewOnceTrans2(xmlAutomataPtr am, xmlAutomataStatePtr from,
/* xmlFAGenerateTransitions(am, from, to, atom); */
if (to == NULL) {
to = xmlRegNewState(am);
xmlRegStatePush(am, to);
to = xmlRegStatePush(am);
if (to == NULL)
return(NULL);
}
xmlRegStateAddTrans(am, from, atom, to, counter, -1);
xmlRegAtomPush(am, atom);
@@ -6282,8 +6283,9 @@ xmlAutomataNewOnceTrans(xmlAutomataPtr am, xmlAutomataStatePtr from,
/* xmlFAGenerateTransitions(am, from, to, atom); */
if (to == NULL) {
to = xmlRegNewState(am);
xmlRegStatePush(am, to);
to = xmlRegStatePush(am);
if (to == NULL)
return(NULL);
}
xmlRegStateAddTrans(am, from, atom, to, counter, -1);
xmlRegAtomPush(am, atom);
@@ -6301,13 +6303,9 @@ xmlAutomataNewOnceTrans(xmlAutomataPtr am, xmlAutomataStatePtr from,
*/
xmlAutomataStatePtr
xmlAutomataNewState(xmlAutomataPtr am) {
xmlAutomataStatePtr to;
if (am == NULL)
return(NULL);
to = xmlRegNewState(am);
xmlRegStatePush(am, to);
return(to);
return(xmlRegStatePush(am));
}
/**