diff --git a/sys/src/libhtml/build.c b/sys/src/libhtml/build.c index 62dcc14ba..50e5b1624 100644 --- a/sys/src/libhtml/build.c +++ b/sys/src/libhtml/build.c @@ -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 \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); } } diff --git a/sys/src/libhtml/lex.c b/sys/src/libhtml/lex.c index 215e45784..871c1df8e 100644 --- a/sys/src/libhtml/lex.c +++ b/sys/src/libhtml/lex.c @@ -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; } diff --git a/sys/src/libhtml/utils.c b/sys/src/libhtml/utils.c index 7b272d904..6b49209d9 100644 --- a/sys/src/libhtml/utils.c +++ b/sys/src/libhtml/utils.c @@ -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; - }