153aa9179Sopenharmony_ciFrom e64653c0e7975594e27d7de2ed4be062c1e4ad03 Mon Sep 17 00:00:00 2001
253aa9179Sopenharmony_ciFrom: Nick Wellnhofer <wellnhofer@aevum.de>
353aa9179Sopenharmony_ciDate: Fri, 17 Feb 2023 15:20:33 +0100
453aa9179Sopenharmony_ciSubject: [PATCH] malloc-fail: Fix leak of xmlRegAtom
553aa9179Sopenharmony_ci
653aa9179Sopenharmony_ciFound with libFuzzer, see #344.
753aa9179Sopenharmony_ci
853aa9179Sopenharmony_ciReference:https://github.com/GNOME/libxml2/commit/e64653c0e7975594e27d7de2ed4be062c1e4ad03
953aa9179Sopenharmony_ciConflict:NA
1053aa9179Sopenharmony_ci---
1153aa9179Sopenharmony_ci xmlregexp.c | 81 ++++++++++++++++++++++++++++++++++++-----------------
1253aa9179Sopenharmony_ci 1 file changed, 55 insertions(+), 26 deletions(-)
1353aa9179Sopenharmony_ci
1453aa9179Sopenharmony_cidiff --git a/xmlregexp.c b/xmlregexp.c
1553aa9179Sopenharmony_ciindex 8c2ea81..11c684a 100644
1653aa9179Sopenharmony_ci--- a/xmlregexp.c
1753aa9179Sopenharmony_ci+++ b/xmlregexp.c
1853aa9179Sopenharmony_ci@@ -1594,9 +1594,6 @@ xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr from,
1953aa9179Sopenharmony_ci 	 * this is a subexpression handling one should not need to
2053aa9179Sopenharmony_ci 	 * create a new node except for XML_REGEXP_QUANT_RANGE.
2153aa9179Sopenharmony_ci 	 */
2253aa9179Sopenharmony_ci-	if (xmlRegAtomPush(ctxt, atom) < 0) {
2353aa9179Sopenharmony_ci-	    return(-1);
2453aa9179Sopenharmony_ci-	}
2553aa9179Sopenharmony_ci 	if ((to != NULL) && (atom->stop != to) &&
2653aa9179Sopenharmony_ci 	    (atom->quant != XML_REGEXP_QUANT_RANGE)) {
2753aa9179Sopenharmony_ci 	    /*
2853aa9179Sopenharmony_ci@@ -1678,8 +1675,10 @@ xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr from,
2953aa9179Sopenharmony_ci 		    copy->max = 0;
3053aa9179Sopenharmony_ci 
3153aa9179Sopenharmony_ci 		    if (xmlFAGenerateTransitions(ctxt, atom->start, NULL, copy)
3253aa9179Sopenharmony_ci-		        < 0)
3353aa9179Sopenharmony_ci+		        < 0) {
3453aa9179Sopenharmony_ci+                        xmlRegFreeAtom(copy);
3553aa9179Sopenharmony_ci 			return(-1);
3653aa9179Sopenharmony_ci+                    }
3753aa9179Sopenharmony_ci 		    inter = ctxt->state;
3853aa9179Sopenharmony_ci 		    counter = xmlRegGetCounter(ctxt);
3953aa9179Sopenharmony_ci 		    ctxt->counters[counter].min = atom->min - 1;
4053aa9179Sopenharmony_ci@@ -1722,6 +1721,8 @@ xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr from,
4153aa9179Sopenharmony_ci 	    default:
4253aa9179Sopenharmony_ci 		break;
4353aa9179Sopenharmony_ci 	}
4453aa9179Sopenharmony_ci+	if (xmlRegAtomPush(ctxt, atom) < 0)
4553aa9179Sopenharmony_ci+	    return(-1);
4653aa9179Sopenharmony_ci 	return(0);
4753aa9179Sopenharmony_ci     }
4853aa9179Sopenharmony_ci     if ((atom->min == 0) && (atom->max == 0) &&
4953aa9179Sopenharmony_ci@@ -1760,9 +1761,6 @@ xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr from,
5053aa9179Sopenharmony_ci 	xmlFAGenerateEpsilonTransition(ctxt, tmp, to);
5153aa9179Sopenharmony_ci 	to = tmp;
5253aa9179Sopenharmony_ci     }
5353aa9179Sopenharmony_ci-    if (xmlRegAtomPush(ctxt, atom) < 0) {
5453aa9179Sopenharmony_ci-	return(-1);
5553aa9179Sopenharmony_ci-    }
5653aa9179Sopenharmony_ci     if ((atom->quant == XML_REGEXP_QUANT_RANGE) &&
5753aa9179Sopenharmony_ci         (atom->min == 0) && (atom->max > 0)) {
5853aa9179Sopenharmony_ci 	nullable = 1;
5953aa9179Sopenharmony_ci@@ -1793,6 +1791,8 @@ xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr from,
6053aa9179Sopenharmony_ci 	default:
6153aa9179Sopenharmony_ci 	    break;
6253aa9179Sopenharmony_ci     }
6353aa9179Sopenharmony_ci+    if (xmlRegAtomPush(ctxt, atom) < 0)
6453aa9179Sopenharmony_ci+	return(-1);
6553aa9179Sopenharmony_ci     return(0);
6653aa9179Sopenharmony_ci }
6753aa9179Sopenharmony_ci 
6853aa9179Sopenharmony_ci@@ -5447,8 +5447,12 @@ xmlFAParseBranch(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr to) {
6953aa9179Sopenharmony_ci 	xmlFAGenerateEpsilonTransition(ctxt, previous, to);
7053aa9179Sopenharmony_ci     } else {
7153aa9179Sopenharmony_ci 	if (xmlFAGenerateTransitions(ctxt, previous,
7253aa9179Sopenharmony_ci-	        (CUR=='|' || CUR==')' || CUR==0) ? to : NULL, ctxt->atom) < 0)
7353aa9179Sopenharmony_ci+	        (CUR=='|' || CUR==')' || CUR==0) ? to : NULL,
7453aa9179Sopenharmony_ci+                ctxt->atom) < 0) {
7553aa9179Sopenharmony_ci+            xmlRegFreeAtom(ctxt->atom);
7653aa9179Sopenharmony_ci+            ctxt->atom = NULL;
7753aa9179Sopenharmony_ci 	    return(-1);
7853aa9179Sopenharmony_ci+        }
7953aa9179Sopenharmony_ci 	previous = ctxt->state;
8053aa9179Sopenharmony_ci 	ctxt->atom = NULL;
8153aa9179Sopenharmony_ci     }
8253aa9179Sopenharmony_ci@@ -5457,8 +5461,11 @@ xmlFAParseBranch(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr to) {
8353aa9179Sopenharmony_ci 	if (ret != 0) {
8453aa9179Sopenharmony_ci 	    if (xmlFAGenerateTransitions(ctxt, previous,
8553aa9179Sopenharmony_ci 	            (CUR=='|' || CUR==')' || CUR==0) ? to : NULL,
8653aa9179Sopenharmony_ci-                    ctxt->atom) < 0)
8753aa9179Sopenharmony_ci-		    return(-1);
8853aa9179Sopenharmony_ci+                    ctxt->atom) < 0) {
8953aa9179Sopenharmony_ci+                xmlRegFreeAtom(ctxt->atom);
9053aa9179Sopenharmony_ci+                ctxt->atom = NULL;
9153aa9179Sopenharmony_ci+                return(-1);
9253aa9179Sopenharmony_ci+            }
9353aa9179Sopenharmony_ci 	    previous = ctxt->state;
9453aa9179Sopenharmony_ci 	    ctxt->atom = NULL;
9553aa9179Sopenharmony_ci 	}
9653aa9179Sopenharmony_ci@@ -5990,6 +5997,8 @@ xmlAutomataNewCountTrans2(xmlAutomataPtr am, xmlAutomataStatePtr from,
9753aa9179Sopenharmony_ci 	return(NULL);
9853aa9179Sopenharmony_ci     if ((token2 == NULL) || (*token2 == 0)) {
9953aa9179Sopenharmony_ci 	atom->valuep = xmlStrdup(token);
10053aa9179Sopenharmony_ci+        if (atom->valuep == NULL)
10153aa9179Sopenharmony_ci+            goto error;
10253aa9179Sopenharmony_ci     } else {
10353aa9179Sopenharmony_ci 	int lenn, lenp;
10453aa9179Sopenharmony_ci 	xmlChar *str;
10553aa9179Sopenharmony_ci@@ -5998,10 +6007,8 @@ xmlAutomataNewCountTrans2(xmlAutomataPtr am, xmlAutomataStatePtr from,
10653aa9179Sopenharmony_ci 	lenp = strlen((char *) token);
10753aa9179Sopenharmony_ci 
10853aa9179Sopenharmony_ci 	str = (xmlChar *) xmlMallocAtomic(lenn + lenp + 2);
10953aa9179Sopenharmony_ci-	if (str == NULL) {
11053aa9179Sopenharmony_ci-	    xmlRegFreeAtom(atom);
11153aa9179Sopenharmony_ci-	    return(NULL);
11253aa9179Sopenharmony_ci-	}
11353aa9179Sopenharmony_ci+	if (str == NULL)
11453aa9179Sopenharmony_ci+	    goto error;
11553aa9179Sopenharmony_ci 	memcpy(&str[0], token, lenp);
11653aa9179Sopenharmony_ci 	str[lenp] = '|';
11753aa9179Sopenharmony_ci 	memcpy(&str[lenp + 1], token2, lenn);
11853aa9179Sopenharmony_ci@@ -6027,10 +6034,11 @@ xmlAutomataNewCountTrans2(xmlAutomataPtr am, xmlAutomataStatePtr from,
11953aa9179Sopenharmony_ci     if (to == NULL) {
12053aa9179Sopenharmony_ci 	to = xmlRegStatePush(am);
12153aa9179Sopenharmony_ci         if (to == NULL)
12253aa9179Sopenharmony_ci-            return(NULL);
12353aa9179Sopenharmony_ci+            goto error;
12453aa9179Sopenharmony_ci     }
12553aa9179Sopenharmony_ci     xmlRegStateAddTrans(am, from, atom, to, counter, -1);
12653aa9179Sopenharmony_ci-    xmlRegAtomPush(am, atom);
12753aa9179Sopenharmony_ci+    if (xmlRegAtomPush(am, atom) < 0)
12853aa9179Sopenharmony_ci+        goto error;
12953aa9179Sopenharmony_ci     am->state = to;
13053aa9179Sopenharmony_ci 
13153aa9179Sopenharmony_ci     if (to == NULL)
13253aa9179Sopenharmony_ci@@ -6040,6 +6048,10 @@ xmlAutomataNewCountTrans2(xmlAutomataPtr am, xmlAutomataStatePtr from,
13353aa9179Sopenharmony_ci     if (min == 0)
13453aa9179Sopenharmony_ci 	xmlFAGenerateEpsilonTransition(am, from, to);
13553aa9179Sopenharmony_ci     return(to);
13653aa9179Sopenharmony_ci+
13753aa9179Sopenharmony_ci+error:
13853aa9179Sopenharmony_ci+    xmlRegFreeAtom(atom);
13953aa9179Sopenharmony_ci+    return(NULL);
14053aa9179Sopenharmony_ci }
14153aa9179Sopenharmony_ci 
14253aa9179Sopenharmony_ci /**
14353aa9179Sopenharmony_ci@@ -6076,6 +6088,8 @@ xmlAutomataNewCountTrans(xmlAutomataPtr am, xmlAutomataStatePtr from,
14453aa9179Sopenharmony_ci     if (atom == NULL)
14553aa9179Sopenharmony_ci 	return(NULL);
14653aa9179Sopenharmony_ci     atom->valuep = xmlStrdup(token);
14753aa9179Sopenharmony_ci+    if (atom->valuep == NULL)
14853aa9179Sopenharmony_ci+        goto error;
14953aa9179Sopenharmony_ci     atom->data = data;
15053aa9179Sopenharmony_ci     if (min == 0)
15153aa9179Sopenharmony_ci 	atom->min = 1;
15253aa9179Sopenharmony_ci@@ -6094,10 +6108,11 @@ xmlAutomataNewCountTrans(xmlAutomataPtr am, xmlAutomataStatePtr from,
15353aa9179Sopenharmony_ci     if (to == NULL) {
15453aa9179Sopenharmony_ci 	to = xmlRegStatePush(am);
15553aa9179Sopenharmony_ci         if (to == NULL)
15653aa9179Sopenharmony_ci-            return(NULL);
15753aa9179Sopenharmony_ci+            goto error;
15853aa9179Sopenharmony_ci     }
15953aa9179Sopenharmony_ci     xmlRegStateAddTrans(am, from, atom, to, counter, -1);
16053aa9179Sopenharmony_ci-    xmlRegAtomPush(am, atom);
16153aa9179Sopenharmony_ci+    if (xmlRegAtomPush(am, atom) < 0)
16253aa9179Sopenharmony_ci+        goto error;
16353aa9179Sopenharmony_ci     am->state = to;
16453aa9179Sopenharmony_ci 
16553aa9179Sopenharmony_ci     if (to == NULL)
16653aa9179Sopenharmony_ci@@ -6107,6 +6122,10 @@ xmlAutomataNewCountTrans(xmlAutomataPtr am, xmlAutomataStatePtr from,
16753aa9179Sopenharmony_ci     if (min == 0)
16853aa9179Sopenharmony_ci 	xmlFAGenerateEpsilonTransition(am, from, to);
16953aa9179Sopenharmony_ci     return(to);
17053aa9179Sopenharmony_ci+
17153aa9179Sopenharmony_ci+error:
17253aa9179Sopenharmony_ci+    xmlRegFreeAtom(atom);
17353aa9179Sopenharmony_ci+    return(NULL);
17453aa9179Sopenharmony_ci }
17553aa9179Sopenharmony_ci 
17653aa9179Sopenharmony_ci /**
17753aa9179Sopenharmony_ci@@ -6147,6 +6166,8 @@ xmlAutomataNewOnceTrans2(xmlAutomataPtr am, xmlAutomataStatePtr from,
17853aa9179Sopenharmony_ci 	return(NULL);
17953aa9179Sopenharmony_ci     if ((token2 == NULL) || (*token2 == 0)) {
18053aa9179Sopenharmony_ci 	atom->valuep = xmlStrdup(token);
18153aa9179Sopenharmony_ci+        if (atom->valuep == NULL)
18253aa9179Sopenharmony_ci+            goto error;
18353aa9179Sopenharmony_ci     } else {
18453aa9179Sopenharmony_ci 	int lenn, lenp;
18553aa9179Sopenharmony_ci 	xmlChar *str;
18653aa9179Sopenharmony_ci@@ -6155,10 +6176,8 @@ xmlAutomataNewOnceTrans2(xmlAutomataPtr am, xmlAutomataStatePtr from,
18753aa9179Sopenharmony_ci 	lenp = strlen((char *) token);
18853aa9179Sopenharmony_ci 
18953aa9179Sopenharmony_ci 	str = (xmlChar *) xmlMallocAtomic(lenn + lenp + 2);
19053aa9179Sopenharmony_ci-	if (str == NULL) {
19153aa9179Sopenharmony_ci-	    xmlRegFreeAtom(atom);
19253aa9179Sopenharmony_ci-	    return(NULL);
19353aa9179Sopenharmony_ci-	}
19453aa9179Sopenharmony_ci+	if (str == NULL)
19553aa9179Sopenharmony_ci+	    goto error;
19653aa9179Sopenharmony_ci 	memcpy(&str[0], token, lenp);
19753aa9179Sopenharmony_ci 	str[lenp] = '|';
19853aa9179Sopenharmony_ci 	memcpy(&str[lenp + 1], token2, lenn);
19953aa9179Sopenharmony_ci@@ -6181,12 +6200,17 @@ xmlAutomataNewOnceTrans2(xmlAutomataPtr am, xmlAutomataStatePtr from,
20053aa9179Sopenharmony_ci     if (to == NULL) {
20153aa9179Sopenharmony_ci 	to = xmlRegStatePush(am);
20253aa9179Sopenharmony_ci         if (to == NULL)
20353aa9179Sopenharmony_ci-            return(NULL);
20453aa9179Sopenharmony_ci+            goto error;
20553aa9179Sopenharmony_ci     }
20653aa9179Sopenharmony_ci     xmlRegStateAddTrans(am, from, atom, to, counter, -1);
20753aa9179Sopenharmony_ci-    xmlRegAtomPush(am, atom);
20853aa9179Sopenharmony_ci+    if (xmlRegAtomPush(am, atom) < 0)
20953aa9179Sopenharmony_ci+        goto error;
21053aa9179Sopenharmony_ci     am->state = to;
21153aa9179Sopenharmony_ci     return(to);
21253aa9179Sopenharmony_ci+
21353aa9179Sopenharmony_ci+error:
21453aa9179Sopenharmony_ci+    xmlRegFreeAtom(atom);
21553aa9179Sopenharmony_ci+    return(NULL);
21653aa9179Sopenharmony_ci }
21753aa9179Sopenharmony_ci 
21853aa9179Sopenharmony_ci 
21953aa9179Sopenharmony_ci@@ -6241,12 +6265,17 @@ xmlAutomataNewOnceTrans(xmlAutomataPtr am, xmlAutomataStatePtr from,
22053aa9179Sopenharmony_ci     if (to == NULL) {
22153aa9179Sopenharmony_ci 	to = xmlRegStatePush(am);
22253aa9179Sopenharmony_ci         if (to == NULL)
22353aa9179Sopenharmony_ci-            return(NULL);
22453aa9179Sopenharmony_ci+            goto error;
22553aa9179Sopenharmony_ci     }
22653aa9179Sopenharmony_ci     xmlRegStateAddTrans(am, from, atom, to, counter, -1);
22753aa9179Sopenharmony_ci-    xmlRegAtomPush(am, atom);
22853aa9179Sopenharmony_ci+    if (xmlRegAtomPush(am, atom) < 0)
22953aa9179Sopenharmony_ci+        goto error;
23053aa9179Sopenharmony_ci     am->state = to;
23153aa9179Sopenharmony_ci     return(to);
23253aa9179Sopenharmony_ci+
23353aa9179Sopenharmony_ci+error:
23453aa9179Sopenharmony_ci+    xmlRegFreeAtom(atom);
23553aa9179Sopenharmony_ci+    return(NULL);
23653aa9179Sopenharmony_ci }
23753aa9179Sopenharmony_ci 
23853aa9179Sopenharmony_ci /**
23953aa9179Sopenharmony_ci-- 
24053aa9179Sopenharmony_ci2.27.0
24153aa9179Sopenharmony_ci
242