Skip to content

transports: smart: fix memory leak when skipping symbolic refs#4368

Merged
ethomson merged 1 commit into
libgit2:masterfrom
pks-t:pks/smart-negotiate-revwalk-memleak
Oct 9, 2017
Merged

transports: smart: fix memory leak when skipping symbolic refs#4368
ethomson merged 1 commit into
libgit2:masterfrom
pks-t:pks/smart-negotiate-revwalk-memleak

Conversation

@pks-t
Copy link
Copy Markdown
Member

@pks-t pks-t commented Oct 6, 2017

When we setup the revision walk for negotiating references with a
remote, we iterate over all references, ignoring tags and symbolic
references. While skipping over symbolic references, we forget to free
the looked up reference, resulting in a memory leak when the next
iteration simply overwrites the variable.

Fix that issue by more clearly scoping the leaking variable to the loop
and freeing it after every iteration.

Comment thread src/transports/smart_protocol.c Outdated
goto on_error;
goto on_continue;

on_continue:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This label name is misleading, as we don't just go here during continue, but for each iteration.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yeah, I had some problems here finding a proper name

Comment thread src/transports/smart_protocol.c Outdated
git_revwalk_sorting(walk, GIT_SORT_TIME);

for (i = 0; i < refs.count; ++i) {
git_reference *ref;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is not guaranteed to be NULL so if we don't match the GIT_REFS_TAGS_DIR (or match it, whichever way around), then we call git_reference_free on an uninitialised value.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

True

@carlosmn
Copy link
Copy Markdown
Member

carlosmn commented Oct 6, 2017

How about performing a free at the beginning of the loop plus at the end of the function? That should cover both cases without the need for a hand-rolled ensure at the end of the loop.

@pks-t
Copy link
Copy Markdown
Member Author

pks-t commented Oct 9, 2017

If we do free at the beginning of the loop, we'd require three different locations where we free the reference: at the beginning of the loop, after the loop and on success. That's really painful, in my opinion, which is why I went with the thing at the end of the loop.

When we setup the revision walk for negotiating references with a
remote, we iterate over all references, ignoring tags and symbolic
references. While skipping over symbolic references, we forget to free
the looked up reference, resulting in a memory leak when the next
iteration simply overwrites the variable.

Fix that issue by freeing the reference at the beginning of each
iteration and collapsing return paths for error and success.
@pks-t pks-t force-pushed the pks/smart-negotiate-revwalk-memleak branch from 35f78b6 to 7cb705c Compare October 9, 2017 06:35
@pks-t
Copy link
Copy Markdown
Member Author

pks-t commented Oct 9, 2017

Ah, we're actually able to collapse the two different out paths. So this version looks good to me.

@ethomson
Copy link
Copy Markdown
Member

ethomson commented Oct 9, 2017

Thanks, @pks-t, this is much easier to read.

@ethomson ethomson merged commit 9840dad into libgit2:master Oct 9, 2017
@pks-t pks-t deleted the pks/smart-negotiate-revwalk-memleak branch November 11, 2017 20:31
@pks-t pks-t added the backport label Jan 11, 2018
@pks-t pks-t mentioned this pull request Jan 12, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants