commit 5ef2cc1cfe9201155a9843d7538a9b6bf3c3b74b from: Omar Polo via: Thomas Adam date: Fri Sep 02 15:54:01 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 - b15f45f4606f3d64aa30dac5a61c622a9b88ce09 commit + 5ef2cc1cfe9201155a9843d7538a9b6bf3c3b74b blob - e6a19a976c1d95126ca57df6db4f0259d6ecf775 blob + bde0a8005d934134366aed04ebcaaa723b627299 --- lib/repository.c +++ lib/repository.c @@ -1706,7 +1706,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; @@ -1726,9 +1726,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; @@ -1746,10 +1748,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) { @@ -1764,14 +1764,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; } } @@ -1782,6 +1780,7 @@ done: free(*unique_id); *unique_id = NULL; } + free(id_str); free(path); return err; }