libhtml: fix memory leaks

This commit is contained in:
cinap_lenrek 2013-09-04 21:27:15 +02:00
parent 425338fd1f
commit 32236b4957
3 changed files with 51 additions and 14 deletions

View file

@ -693,10 +693,16 @@ getitems(ItemSource* is, uchar* data, int datalen)
bg = makebackground(nil, acolorval(tok, Abgcolor, di->background.color)); bg = makebackground(nil, acolorval(tok, Abgcolor, di->background.color));
bgurl = aurlval(tok, Abackground, nil, di->base); bgurl = aurlval(tok, Abackground, nil, di->base);
if(bgurl != nil) { if(bgurl != nil) {
if(di->backgrounditem != nil) if(di->backgrounditem != nil){
freeitem((Item*)di->backgrounditem); Iimage **ii;
// really should remove old item from di->images list, for(ii=&di->images; *ii != nil; ii = &((*ii)->nextimage)){
// but there should only be one BODY element ... 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 = (Iimage*)newiimage(bgurl, nil, ALnone, 0, 0, 0, 0, 0, 0, nil);
di->backgrounditem->nextimage = di->images; di->backgrounditem->nextimage = di->images;
di->images = di->backgrounditem; di->images = di->backgrounditem;
@ -747,8 +753,11 @@ getitems(ItemSource* is, uchar* data, int datalen)
fprint(2, "warning: unexpected </CAPTION>\n"); fprint(2, "warning: unexpected </CAPTION>\n");
continue; continue;
} }
if(curtab->caption != nil)
freeitems(curtab->caption);
curtab->caption = ps->items->next; curtab->caption = ps->items->next;
free(ps); ps->items->next = nil;
freepstate(ps);
ps = nextps; ps = nextps;
break; break;
@ -1694,6 +1703,7 @@ getitems(ItemSource* is, uchar* data, int datalen)
fprint(2, "warning: empty row\n"); fprint(2, "warning: empty row\n");
curtab->rows = tr->next; curtab->rows = tr->next;
tr->next = nil; tr->next = nil;
free(tr);
} }
else else
tr->flags = 0; 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! // note: ans may be nil and di->kids not nil, if there's a frameset!
outerps->items = newispacer(ISPnull); outerps->items = newispacer(ISPnull);
outerps->lastit = outerps->items; outerps->lastit = outerps->items;
outerps->prelastit = nil;
is->psstk = ps; is->psstk = ps;
if(ans != nil && di->hasscripts) { if(ans != nil && di->hasscripts) {
// TODO evalscript(nil); // TODO evalscript(nil);
@ -1817,6 +1828,7 @@ return_ans:
else else
printitems(ans, "getitems returning:"); printitems(ans, "getitems returning:");
} }
_freetokens(toks, tokslen);
return ans; return ans;
} }
@ -1892,7 +1904,10 @@ finishcell(Table* curtab, Pstate* psstk)
fprint(2, "warning: parse state stack is wrong\n"); fprint(2, "warning: parse state stack is wrong\n");
} }
else { else {
if(c->content != nil)
freeitems(c->content);
c->content = psstk->items->next; c->content = psstk->items->next;
psstk->items->next = nil;
c->flags &= ~TFparsing; c->flags &= ~TFparsing;
freepstate(psstk); freepstate(psstk);
psstk = psstknext; psstk = psstknext;
@ -1977,6 +1992,7 @@ additem(Pstate* ps, Item* it, Token* tok)
if(ps->skipping) { if(ps->skipping) {
if(warn) if(warn)
fprint(2, "warning: skipping item: %I\n", it); fprint(2, "warning: skipping item: %I\n", it);
freeitem(it);
return; return;
} }
it->anchorid = ps->curanchor; it->anchorid = ps->curanchor;
@ -2213,6 +2229,7 @@ addbrk(Pstate* ps, int sp, int clr)
// try to avoid making empty items // try to avoid making empty items
// but not crucial f the occasional one gets through // but not crucial f the occasional one gets through
if(nl == 0 && ps->prelastit != nil) { if(nl == 0 && ps->prelastit != nil) {
freeitems(ps->lastit);
ps->lastit = ps->prelastit; ps->lastit = ps->prelastit;
ps->lastit->next = nil; ps->lastit->next = nil;
ps->prelastit = nil; ps->prelastit = nil;
@ -2474,6 +2491,7 @@ finish_table(Table* t)
// copy the data from the allocated Tablerow into the array slot // copy the data from the allocated Tablerow into the array slot
t->rows[r] = *row; t->rows[r] = *row;
rownext = row->next; rownext = row->next;
free(row);
row = &t->rows[r]; row = &t->rows[r];
r--; r--;
rcols = 0; rcols = 0;
@ -2482,7 +2500,7 @@ finish_table(Table* t)
// If rowspan is > 1 but this is the last row, // If rowspan is > 1 but this is the last row,
// reset the rowspan // reset the rowspan
if(c != nil && c->rowspan > 1 && r == nrow-2) if(c != nil && c->rowspan > 1 && r == nrow-2)
c->rowspan = 1; c->rowspan = 1;
// reverse row->cells list (along nextinrow pointers) // reverse row->cells list (along nextinrow pointers)
row->cells = nil; row->cells = nil;
@ -3220,6 +3238,7 @@ freeitem(Item* it)
free(ga->style); free(ga->style);
free(ga->title); free(ga->title);
freescriptevents(ga->events); freescriptevents(ga->events);
free(ga);
} }
free(it); free(it);
} }
@ -3250,6 +3269,7 @@ freeformfield(Formfield* ff)
free(ff->name); free(ff->name);
free(ff->value); free(ff->value);
freeitem(ff->image);
for(o = ff->options; o != nil; o = onext) { for(o = ff->options; o != nil; o = onext) {
onext = o->next; onext = o->next;
free(o->value); free(o->value);
@ -3273,6 +3293,7 @@ freetable(Table* t)
for(c = t->cells; c != nil; c = cnext) { for(c = t->cells; c != nil; c = cnext) {
cnext = c->next; cnext = c->next;
freeitems(c->content); freeitems(c->content);
free(c);
} }
if(t->grid != nil) { if(t->grid != nil) {
for(i = 0; i < t->nrow; i++) for(i = 0; i < t->nrow; i++)
@ -3428,7 +3449,8 @@ freedocinfo(Docinfo* d)
return; return;
free(d->src); free(d->src);
free(d->base); free(d->base);
freeitem((Item*)d->backgrounditem); free(d->doctitle);
freeitem(d->backgrounditem);
free(d->refresh); free(d->refresh);
freekidinfos(d->kidinfo); freekidinfos(d->kidinfo);
freeanchors(d->anchors); freeanchors(d->anchors);
@ -3440,11 +3462,10 @@ freedocinfo(Docinfo* d)
free(d); free(d);
} }
// Currently, someone else owns all the memory
// pointed to by things in a Pstate.
static void static void
freepstate(Pstate* p) freepstate(Pstate* p)
{ {
freeitems(p->items);
free(p); free(p);
} }
@ -3456,7 +3477,7 @@ freepstatestack(Pstate* pshead)
for(p = pshead; p != nil; p = pnext) { for(p = pshead; p != nil; p = pnext) {
pnext = p->next; pnext = p->next;
free(p); freepstate(p);
} }
} }

View file

@ -611,6 +611,7 @@ _gettoks(uchar* data, int datalen, int chset, int mtype, int* plen)
a = 0; a = 0;
if(ts->mtype == TextHtml) { if(ts->mtype == TextHtml) {
for(;;) { for(;;) {
assert(ai <= alen);
if(alen - ai < ToksChunk/32) { if(alen - ai < ToksChunk/32) {
alen += ToksChunk; alen += ToksChunk;
a = erealloc(a, alen*sizeof *a); a = erealloc(a, alen*sizeof *a);
@ -639,6 +640,7 @@ _gettoks(uchar* data, int datalen, int chset, int mtype, int* plen)
else { else {
// plain text (non-html) tokens // plain text (non-html) tokens
for(;;) { for(;;) {
assert(ai <= alen);
if(alen - ai < ToksChunk/32) { if(alen - ai < ToksChunk/32) {
alen += ToksChunk; alen += ToksChunk;
a = erealloc(a, alen*sizeof *a); a = erealloc(a, alen*sizeof *a);
@ -732,6 +734,7 @@ buftostr(Rune* s, Rune* buf, int j)
memcpy(&s[i], buf, j*sizeof *s); memcpy(&s[i], buf, j*sizeof *s);
s[i+j] = 0; s[i+j] = 0;
} }
setmalloctag(s, getcallerpc(&s));
return s; return s;
} }
@ -900,6 +903,7 @@ gettag(TokenSource* ts, int starti, Token* a, int* pai)
Token* tok; Token* tok;
Rune buf[BIGBUFSIZE]; Rune buf[BIGBUFSIZE];
al = nil;
rbra = 0; rbra = 0;
nexti = ts->i; nexti = ts->i;
tok = &a[*pai]; tok = &a[*pai];
@ -948,7 +952,6 @@ gettag(TokenSource* ts, int starti, Token* a, int* pai)
else else
tok->text = _Strndup(buf, i); // for warning print, in build tok->text = _Strndup(buf, i); // for warning print, in build
// attribute gathering loop // attribute gathering loop
al = nil;
while(1) { while(1) {
// look for "ws name" or "ws name ws = ws val" (ws=whitespace) // look for "ws name" or "ws name ws = ws val" (ws=whitespace)
// skip whitespace // skip whitespace
@ -1113,6 +1116,7 @@ eob_done:
if(warn) if(warn)
fprint(2, "warning: incomplete tag at end of page\n"); fprint(2, "warning: incomplete tag at end of page\n");
backup(ts, nexti); backup(ts, nexti);
freeattrs(al);
tok->tag = Data; tok->tag = Data;
tok->text = _Strdup(L"<"); tok->text = _Strdup(L"<");
return Data; return Data;
@ -1462,6 +1466,7 @@ newattr(int attid, Rune* value, Attr* link)
ans->attid = attid; ans->attid = attid;
ans->value = value; ans->value = value;
ans->next = link; ans->next = link;
setmalloctag(ans, getcallerpc(&attid));
return ans; return ans;
} }

View file

@ -328,9 +328,12 @@ _Strncmpci(Rune *s1, int n1, Rune *s2)
Rune* Rune*
_Strdup(Rune* s) _Strdup(Rune* s)
{ {
Rune* ans;
if(s == nil) if(s == nil)
return 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), // 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); ans = _newstr(n);
memmove(ans, s, n*sizeof(Rune)); memmove(ans, s, n*sizeof(Rune));
ans[n] = 0; ans[n] = 0;
setmalloctag(ans, getcallerpc(&s));
return ans; return ans;
} }
// emalloc enough room for n Runes, plus 1 null terminator. // emalloc enough room for n Runes, plus 1 null terminator.
@ -353,7 +357,11 @@ _Strndup(Rune* s, int n)
Rune* Rune*
_newstr(int n) _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 // emalloc and copy s+t
@ -372,6 +380,7 @@ _Strdup2(Rune* s, Rune* t)
p = _Stradd(ans, s, ns); p = _Stradd(ans, s, ns);
p = _Stradd(p, t, nt); p = _Stradd(p, t, nt);
*p = 0; *p = 0;
setmalloctag(ans, getcallerpc(&s));
return ans; return ans;
} }
@ -384,6 +393,7 @@ _Strsubstr(Rune* s, int start, int stop)
if(start == stop) if(start == stop)
return nil; return nil;
t = _Strndup(s+start, stop-start); t = _Strndup(s+start, stop-start);
setmalloctag(t, getcallerpc(&s));
return t; return t;
} }
@ -530,6 +540,7 @@ toStr(uchar* buf, int n, int chset)
ans = nil; ans = nil;
assert(0); assert(0);
} }
setmalloctag(ans, getcallerpc(&buf));
return ans; return ans;
} }
@ -575,6 +586,6 @@ fromStr(Rune* buf, int n, int chset)
default: default:
assert(0); assert(0);
} }
setmalloctag(ans, getcallerpc(&buf));
return ans; return ans;
} }