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:
148
xmlregexp.c
148
xmlregexp.c
@@ -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));
|
||||
}
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user