commit 5d22ea52df30acf1895cb703d770514a2154b5ae from: Omar Polo date: Fri Sep 02 08:05:08 2022 UTC plug a leak in match_loose_object in the loop of match_loose_object we allocate a string per directory entry that in some case it was free(3)'d before `continue' or `goto', but not always. Instead, use a more common idiom. ok stsp@ commit - 116d19d9395e2c1d7502e32441724cda7b408ad2 commit + 5d22ea52df30acf1895cb703d770514a2154b5ae blob - 87c7abb573744c7b7f9b38f35d7550229267b418 blob + 9d9dfd0586d7bfc07846c61a82e2f1778968d95c --- lib/repository.c +++ lib/repository.c @@ -1710,7 +1710,7 @@ match_loose_object(struct got_object_id **unique_id, c struct got_repository *repo) { const struct got_error *err = NULL; - char *path; + char *path, *id_str = NULL; DIR *dir = NULL; struct dirent *dent; struct got_object_id id; @@ -1730,9 +1730,11 @@ match_loose_object(struct got_object_id **unique_id, c goto done; } while ((dent = readdir(dir)) != NULL) { - char *id_str; int cmp; + free(id_str); + id_str = NULL; + if (strcmp(dent->d_name, ".") == 0 || strcmp(dent->d_name, "..") == 0) continue; @@ -1750,10 +1752,8 @@ match_loose_object(struct got_object_id **unique_id, c * sorted order, so we must iterate over all of them. */ cmp = strncmp(id_str, id_str_prefix, strlen(id_str_prefix)); - if (cmp != 0) { - free(id_str); + if (cmp != 0) continue; - } if (*unique_id == NULL) { if (obj_type != GOT_OBJ_TYPE_ANY) { @@ -1768,14 +1768,12 @@ match_loose_object(struct got_object_id **unique_id, c *unique_id = got_object_id_dup(&id); if (*unique_id == NULL) { err = got_error_from_errno("got_object_id_dup"); - free(id_str); goto done; } } else { if (got_object_id_cmp(*unique_id, &id) == 0) continue; /* both packed and loose */ err = got_error(GOT_ERR_AMBIGUOUS_ID); - free(id_str); goto done; } } @@ -1786,6 +1784,7 @@ done: free(*unique_id); *unique_id = NULL; } + free(id_str); free(path); return err; }