Pádraig Brady
2018-05-14 01:51:02 UTC
Hi,
I may be wrong but I suspect there is a corner case where fts_close()
will not free the FTSENT structures correctly if called immediately
after fts_open().
After fts_open(), the current entry is a dummy entry created as
if ((sp->fts_cur = fts_alloc(sp, "", 0)) == NULL)
goto mem3;
sp->fts_cur->fts_link = root;
sp->fts_cur->fts_info = FTS_INIT;
It would normally be freed during the first invocation of fts_read().
if (sp->fts_cur) {
for (p = sp->fts_cur; p->fts_level >= FTS_ROOTLEVEL;) {
freep = p;
p = p->fts_link != NULL ? p->fts_link : p->fts_parent;
free(freep);
}
free(p);
}
However, fts_alloc() does not clear or set fts_level, nor does it zero
the entire FTSENT structure.
So as far as I can figure, it is possible for the fts_level of the
dummy entry to be negative after fts_open() causing fts_close() not to
free the actual root level entries.
Yes valgrind indicates that fts_level is uninitialized if youI may be wrong but I suspect there is a corner case where fts_close()
will not free the FTSENT structures correctly if called immediately
after fts_open().
After fts_open(), the current entry is a dummy entry created as
if ((sp->fts_cur = fts_alloc(sp, "", 0)) == NULL)
goto mem3;
sp->fts_cur->fts_link = root;
sp->fts_cur->fts_info = FTS_INIT;
It would normally be freed during the first invocation of fts_read().
if (sp->fts_cur) {
for (p = sp->fts_cur; p->fts_level >= FTS_ROOTLEVEL;) {
freep = p;
p = p->fts_link != NULL ? p->fts_link : p->fts_parent;
free(freep);
}
free(p);
}
However, fts_alloc() does not clear or set fts_level, nor does it zero
the entire FTSENT structure.
So as far as I can figure, it is possible for the fts_level of the
dummy entry to be negative after fts_open() causing fts_close() not to
free the actual root level entries.
fts_close() right after fts_open().
The attached should fix it up.
thanks!
Pádraig