git: 9front

Download patch

ref: 00712034efcc8c962638d2ab0d2cd98e93d04aa5
parent: b145798881615106aea2f196cf69c32984c11a1c
author: cinap_lenrek <cinap_lenrek@gmx.de>
date: Wed Sep 4 17:27:15 EDT 2013

libhtml: fix memory leaks

--- a/sys/src/libhtml/build.c
+++ b/sys/src/libhtml/build.c
@@ -693,10 +693,16 @@
 				bg = makebackground(nil, acolorval(tok, Abgcolor, di->background.color));
 				bgurl = aurlval(tok, Abackground, nil, di->base);
 				if(bgurl != nil) {
-					if(di->backgrounditem != nil)
-						freeitem((Item*)di->backgrounditem);
-						// really should remove old item from di->images list,
-						// but there should only be one BODY element ...
+					if(di->backgrounditem != nil){
+						Iimage **ii;
+						for(ii=&di->images; *ii != nil; ii = &((*ii)->nextimage)){
+							if(*ii == di->backgrounditem){
+								*ii = di->backgrounditem->nextimage;
+								break;
+							}
+						}
+						freeitem(di->backgrounditem);
+					}
 					di->backgrounditem = (Iimage*)newiimage(bgurl, nil, ALnone, 0, 0, 0, 0, 0, 0, nil);
 					di->backgrounditem->nextimage = di->images;
 					di->images = di->backgrounditem;
@@ -747,8 +753,11 @@
 						fprint(2, "warning: unexpected </CAPTION>\n");
 					continue;
 				}
+				if(curtab->caption != nil)
+					freeitems(curtab->caption);
 				curtab->caption = ps->items->next;
-				free(ps);
+				ps->items->next = nil;
+				freepstate(ps);
 				ps = nextps;
 				break;
 
@@ -1694,6 +1703,7 @@
 						fprint(2, "warning: empty row\n");
 					curtab->rows = tr->next;
 					tr->next = nil;
+					free(tr);
 				}
 				else
 					tr->flags = 0;
@@ -1803,6 +1813,7 @@
 	// note: ans may be nil and di->kids not nil, if there's a frameset!
 	outerps->items = newispacer(ISPnull);
 	outerps->lastit = outerps->items;
+	outerps->prelastit = nil;
 	is->psstk = ps;
 	if(ans != nil && di->hasscripts) {
 		// TODO evalscript(nil);
@@ -1817,6 +1828,7 @@
 		else
 			printitems(ans, "getitems returning:");
 	}
+	_freetokens(toks, tokslen);
 	return ans;
 }
 
@@ -1892,7 +1904,10 @@
 					fprint(2, "warning: parse state stack is wrong\n");
 			}
 			else {
+				if(c->content != nil)
+					freeitems(c->content);
 				c->content = psstk->items->next;
+				psstk->items->next = nil;
 				c->flags &= ~TFparsing;
 				freepstate(psstk);
 				psstk = psstknext;
@@ -1977,6 +1992,7 @@
 	if(ps->skipping) {
 		if(warn)
 			fprint(2, "warning: skipping item: %I\n", it);
+		freeitem(it);
 		return;
 	}
 	it->anchorid = ps->curanchor;
@@ -2213,6 +2229,7 @@
 			// try to avoid making empty items
 			// but not crucial f the occasional one gets through
 			if(nl == 0 && ps->prelastit != nil) {
+				freeitems(ps->lastit);
 				ps->lastit = ps->prelastit;
 				ps->lastit->next = nil;
 				ps->prelastit = nil;
@@ -2474,6 +2491,7 @@
 		// copy the data from the allocated Tablerow into the array slot
 		t->rows[r] = *row;
 		rownext = row->next;
+		free(row);
 		row = &t->rows[r];
 		r--;
 		rcols = 0;
@@ -2482,7 +2500,7 @@
 		// If rowspan is > 1 but this is the last row,
 		// reset the rowspan
 		if(c != nil && c->rowspan > 1 && r == nrow-2)
-				c->rowspan = 1;
+			c->rowspan = 1;
 
 		// reverse row->cells list (along nextinrow pointers)
 		row->cells = nil;
@@ -3220,6 +3238,7 @@
 		free(ga->style);
 		free(ga->title);
 		freescriptevents(ga->events);
+		free(ga);
 	}
 	free(it);
 }
@@ -3250,6 +3269,7 @@
 
 	free(ff->name);
 	free(ff->value);
+	freeitem(ff->image);
 	for(o = ff->options; o != nil; o = onext) {
 		onext = o->next;
 		free(o->value);
@@ -3273,6 +3293,7 @@
 	for(c = t->cells; c != nil; c = cnext) {
 		cnext = c->next;
 		freeitems(c->content);
+		free(c);
 	}
 	if(t->grid != nil) {
 		for(i = 0; i < t->nrow; i++)
@@ -3428,7 +3449,8 @@
 		return;
 	free(d->src);
 	free(d->base);
-	freeitem((Item*)d->backgrounditem);
+	free(d->doctitle);
+	freeitem(d->backgrounditem);
 	free(d->refresh);
 	freekidinfos(d->kidinfo);
 	freeanchors(d->anchors);
@@ -3440,11 +3462,10 @@
 	free(d);
 }
 
-// Currently, someone else owns all the memory
-// pointed to by things in a Pstate.
 static void
 freepstate(Pstate* p)
 {
+	freeitems(p->items);
 	free(p);
 }
 
@@ -3456,7 +3477,7 @@
 
 	for(p = pshead; p != nil; p = pnext) {
 		pnext = p->next;
-		free(p);
+		freepstate(p);
 	}
 }
 
--- a/sys/src/libhtml/lex.c
+++ b/sys/src/libhtml/lex.c
@@ -611,6 +611,7 @@
 	a = 0;
 	if(ts->mtype == TextHtml) {
 		for(;;) {
+			assert(ai <= alen);
 			if(alen - ai < ToksChunk/32) {
 				alen += ToksChunk;
 				a = erealloc(a, alen*sizeof *a);
@@ -639,6 +640,7 @@
 	else {
 		// plain text (non-html) tokens
 		for(;;) {
+			assert(ai <= alen);
 			if(alen - ai < ToksChunk/32) {
 				alen += ToksChunk;
 				a = erealloc(a, alen*sizeof *a);
@@ -732,6 +734,7 @@
 		memcpy(&s[i], buf, j*sizeof *s);
 		s[i+j] = 0;
 	}
+	setmalloctag(s, getcallerpc(&s));
 	return s;
 }
 
@@ -900,6 +903,7 @@
 	Token*	tok;
 	Rune	buf[BIGBUFSIZE];
 
+	al = nil;
 	rbra = 0;
 	nexti = ts->i;
 	tok = &a[*pai];
@@ -948,7 +952,6 @@
 	else
 		tok->text = _Strndup(buf, i);	// for warning print, in build
 	// attribute gathering loop
-	al = nil;
 	while(1) {
 		// look for "ws name" or "ws name ws = ws val"  (ws=whitespace)
 		// skip whitespace
@@ -1113,6 +1116,7 @@
 	if(warn)
 		fprint(2, "warning: incomplete tag at end of page\n");
 	backup(ts, nexti);
+	freeattrs(al);
 	tok->tag = Data;
 	tok->text = _Strdup(L"<");
 	return Data;
@@ -1462,6 +1466,7 @@
 	ans->attid = attid;
 	ans->value = value;
 	ans->next = link;
+	setmalloctag(ans, getcallerpc(&attid));
 	return ans;
 }
 
--- a/sys/src/libhtml/utils.c
+++ b/sys/src/libhtml/utils.c
@@ -328,9 +328,12 @@
 Rune*
 _Strdup(Rune* s)
 {
+	Rune* ans;
 	if(s == nil)
 		return nil;
-	return _Strndup(s, runestrlen(s));
+	ans = _Strndup(s, runestrlen(s));
+	setmalloctag(ans, getcallerpc(&s));
+	return ans;
 }
 
 // emalloc and copy n chars of s (assume s is at least that long),
@@ -346,6 +349,7 @@
 	ans = _newstr(n);
 	memmove(ans, s, n*sizeof(Rune));
 	ans[n] = 0;
+	setmalloctag(ans, getcallerpc(&s));
 	return ans;
 }
 // emalloc enough room for n Runes, plus 1 null terminator.
@@ -353,7 +357,11 @@
 Rune*
 _newstr(int n)
 {
-	return (Rune*)emalloc((n+1)*sizeof(Rune));
+	Rune* ans;
+
+	ans = (Rune*)emalloc((n+1)*sizeof(Rune));
+	setmalloctag(ans, getcallerpc(&n));
+	return ans;
 }
 
 // emalloc and copy s+t
@@ -372,6 +380,7 @@
 	p = _Stradd(ans, s, ns);
 	p = _Stradd(p, t, nt);
 	*p = 0;
+	setmalloctag(ans, getcallerpc(&s));
 	return ans;
 }
 
@@ -384,6 +393,7 @@
 	if(start == stop)
 		return nil;
 	t = _Strndup(s+start, stop-start);
+	setmalloctag(t, getcallerpc(&s));
 	return t;
 }
 
@@ -530,6 +540,7 @@
 		ans = nil;
 		assert(0);
 	}
+	setmalloctag(ans, getcallerpc(&buf));
 	return ans;
 }
 
@@ -575,6 +586,6 @@
 	default:
 		assert(0);
 	}
+	setmalloctag(ans, getcallerpc(&buf));
 	return ans;
-
 }
--