Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion alternatives.c
Original file line number Diff line number Diff line change
Expand Up @@ -520,14 +520,20 @@ static int readConfig(struct alternativeSet *set, const char *title,
newAlt.followers[i - 1].target = (line && strlen(line)) ? strsteal(&line) : NULL;
}

for (i = 0; i < set->numAlts; i++) {
if (streq_bin(newAlt.leader.target, set->alts[i].leader.target)) {
Copy link

Copilot AI Oct 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Memory leak when skipping duplicate alternatives. The newAlt structure has allocated memory (via strdup, malloc, and strsteal on lines 461-520) that must be freed before jumping to nextalt. The memset at line 537 only zeros the pointers without freeing the memory. Call clearAlternative(&newAlt) before the goto nextalt statement.

Suggested change
if (streq_bin(newAlt.leader.target, set->alts[i].leader.target)) {
if (streq_bin(newAlt.leader.target, set->alts[i].leader.target)) {
clearAlternative(&newAlt);

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, but we don't do this in the existing loop, so I didn't think it was necessary on the short-circuit path. can somebody who knows anything about C comment? :D

goto nextalt;
}
}

set->alts = realloc(set->alts, (set->numAlts + 1) * sizeof(*set->alts));
set->alts[set->numAlts] = newAlt;

if (newAlt.priority > set->alts[set->best].priority)
set->best = set->numAlts;

set->numAlts++;

nextalt:
memset(&newAlt, 0, sizeof(struct alternative));

nextLine(&buf, &line);
Expand Down