libbsd: rewrite fts.c to avoid error

With GCC13 the current code and its use of the `realloc` function triggers a
potential use after free warning. The code is most likely correct, but there
may be a bug in GCC13's use after free checking, or this is one of the cases
where it is not possible to accurately detect if there is really a chance that
it is used after free.

This rewrites the code in such a way that the warning is no longer triggered.

No functional change intended.

Change-Id: I85e145de2128d4b12a9b3016de33d9facaf0d758
Reviewed-on: https://review.haiku-os.org/c/haiku/+/6648
Reviewed-by: waddlesplash <[email protected]>
Reviewed-by: Axel Dörfler <[email protected]>
This commit is contained in:
Niels Sascha Reedijk
2023-06-28 07:11:17 +00:00
committed by Adrien Destugues
parent 5140a1bb94
commit b9a6a85bc3
+14 -10
View File
@@ -1031,7 +1031,7 @@ static FTSENT *
fts_sort(FTS *sp, FTSENT *head, size_t nitems)
{
FTSENT **ap, *p;
FTSENT **old_array;
FTSENT **new_array;
/*
* Construct an array of pointers to the structures and call qsort(3).
@@ -1042,13 +1042,14 @@ fts_sort(FTS *sp, FTSENT *head, size_t nitems)
*/
if (nitems > sp->fts_nitems) {
sp->fts_nitems = nitems + 40;
old_array = sp->fts_array;
if ((sp->fts_array = realloc(old_array,
sp->fts_nitems * sizeof(FTSENT *))) == NULL) {
free(old_array);
new_array = realloc(sp->fts_array, sp->fts_nitems * sizeof(FTSENT *));
if (new_array == NULL) {
free(sp->fts_array);
sp->fts_array = NULL;
sp->fts_nitems = 0;
return (head);
}
sp->fts_array = new_array;
}
for (ap = sp->fts_array, p = head; p; p = p->fts_link)
*ap++ = p;
@@ -1127,13 +1128,16 @@ fts_lfree(FTSENT *head)
static int
fts_palloc(FTS *sp, size_t more)
{
char *old_path;
char *new_path;
sp->fts_pathlen += more + 256;
old_path = sp->fts_path;
sp->fts_path = realloc(old_path, sp->fts_pathlen);
if (sp->fts_path == NULL)
free(old_path);
new_path = realloc(sp->fts_path, sp->fts_pathlen);
if (new_path == NULL) {
free(sp->fts_path);
sp->fts_path = NULL;
} else {
sp->fts_path = new_path;
}
return (sp->fts_path == NULL);
}