]> git.lizzy.rs Git - plan9front.git/commitdiff
libhtml: fix memory leaks
authorcinap_lenrek <cinap_lenrek@gmx.de>
Wed, 4 Sep 2013 19:27:15 +0000 (21:27 +0200)
committercinap_lenrek <cinap_lenrek@gmx.de>
Wed, 4 Sep 2013 19:27:15 +0000 (21:27 +0200)
sys/src/libhtml/build.c
sys/src/libhtml/lex.c
sys/src/libhtml/utils.c

index 62dcc14ba76646c56d54cf19818fff21d76fa8ff..50e5b1624219bc5c303e92a2d31bd12d2a5b0ed5 100644 (file)
@@ -693,10 +693,16 @@ getitems(ItemSource* is, uchar* data, int datalen)
                                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 @@ getitems(ItemSource* is, uchar* data, int datalen)
                                                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 @@ getitems(ItemSource* is, uchar* data, int datalen)
                                                fprint(2, "warning: empty row\n");
                                        curtab->rows = tr->next;
                                        tr->next = nil;
+                                       free(tr);
                                }
                                else
                                        tr->flags = 0;
@@ -1803,6 +1813,7 @@ getitems(ItemSource* is, uchar* data, int datalen)
        // 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 @@ return_ans:
                else
                        printitems(ans, "getitems returning:");
        }
+       _freetokens(toks, tokslen);
        return ans;
 }
 
@@ -1892,7 +1904,10 @@ finishcell(Table* curtab, Pstate* psstk)
                                        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 @@ additem(Pstate* ps, Item* it, Token* tok)
        if(ps->skipping) {
                if(warn)
                        fprint(2, "warning: skipping item: %I\n", it);
+               freeitem(it);
                return;
        }
        it->anchorid = ps->curanchor;
@@ -2213,6 +2229,7 @@ addbrk(Pstate* ps, int sp, int clr)
                        // 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 @@ finish_table(Table* t)
                // 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 @@ finish_table(Table* t)
                // 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 @@ freeitem(Item* it)
                free(ga->style);
                free(ga->title);
                freescriptevents(ga->events);
+               free(ga);
        }
        free(it);
 }
@@ -3250,6 +3269,7 @@ freeformfield(Formfield* ff)
 
        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 @@ freetable(Table* t)
        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 @@ freedocinfo(Docinfo* d)
                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 @@ freedocinfo(Docinfo* d)
        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 @@ freepstatestack(Pstate* pshead)
 
        for(p = pshead; p != nil; p = pnext) {
                pnext = p->next;
-               free(p);
+               freepstate(p);
        }
 }
 
index 215e45784ccede50982016e6367b9d3f616ded79..871c1df8e325a48e267a74fd424f89984c350b81 100644 (file)
@@ -611,6 +611,7 @@ _gettoks(uchar* data, int datalen, int chset, int mtype, int* plen)
        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 @@ _gettoks(uchar* data, int datalen, int chset, int mtype, int* plen)
        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 @@ buftostr(Rune* s, Rune* buf, int j)
                memcpy(&s[i], buf, j*sizeof *s);
                s[i+j] = 0;
        }
+       setmalloctag(s, getcallerpc(&s));
        return s;
 }
 
@@ -900,6 +903,7 @@ gettag(TokenSource* ts, int starti, Token* a, int* pai)
        Token*  tok;
        Rune    buf[BIGBUFSIZE];
 
+       al = nil;
        rbra = 0;
        nexti = ts->i;
        tok = &a[*pai];
@@ -948,7 +952,6 @@ gettag(TokenSource* ts, int starti, Token* a, int* pai)
        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 @@ eob_done:
        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 @@ newattr(int attid, Rune* value, Attr* link)
        ans->attid = attid;
        ans->value = value;
        ans->next = link;
+       setmalloctag(ans, getcallerpc(&attid));
        return ans;
 }
 
index 7b272d904bb7b5b933fc6f38f7ea63ba286fc6cf..6b49209d99d718fb9dd9924d1ac4526ee601b028 100644 (file)
@@ -328,9 +328,12 @@ _Strncmpci(Rune *s1, int n1, Rune *s2)
 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 @@ _Strndup(Rune* s, int n)
        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 @@ _Strndup(Rune* s, int n)
 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 @@ _Strdup2(Rune* s, Rune* t)
        p = _Stradd(ans, s, ns);
        p = _Stradd(p, t, nt);
        *p = 0;
+       setmalloctag(ans, getcallerpc(&s));
        return ans;
 }
 
@@ -384,6 +393,7 @@ _Strsubstr(Rune* s, int start, int stop)
        if(start == stop)
                return nil;
        t = _Strndup(s+start, stop-start);
+       setmalloctag(t, getcallerpc(&s));
        return t;
 }
 
@@ -530,6 +540,7 @@ toStr(uchar* buf, int n, int chset)
                ans = nil;
                assert(0);
        }
+       setmalloctag(ans, getcallerpc(&buf));
        return ans;
 }
 
@@ -575,6 +586,6 @@ fromStr(Rune* buf, int n, int chset)
        default:
                assert(0);
        }
+       setmalloctag(ans, getcallerpc(&buf));
        return ans;
-
 }