Fixes memory leak in KUrlComboBox::setUrl
ClosedPublic

Authored by hallas on Aug 7 2018, 7:27 AM.

Details

Summary

Subject: Fixes memory leak in KUrlComboBox::setUrl

Details:

If setUrl is called multiple times it first removes the previous item
but fails to delete the item before removing it causing a memory leak.

Test Plan

Unit test

Diff Detail

Repository
R241 KIO
Branch
master
Lint
No Linters Available
Unit
No Unit Test Coverage
Build Status
Buildable 1664
Build 1682: arc lint + arc unit
hallas created this revision.Aug 7 2018, 7:27 AM
Restricted Application added a project: Frameworks. · View Herald TranscriptAug 7 2018, 7:27 AM
Restricted Application added a subscriber: kde-frameworks-devel. · View Herald Transcript
hallas requested review of this revision.Aug 7 2018, 7:27 AM
dfaure requested changes to this revision.Aug 7 2018, 9:15 AM
dfaure added a subscriber: dfaure.
dfaure added inline comments.
src/widgets/kurlcombobox.cpp
273

This could be merged with the next line, by doing

delete d->itemList.takeLast();
356–357

Doesn't this have the same issue? delete missing

357–362

same here, right?

This revision now requires changes to proceed.Aug 7 2018, 9:15 AM
hallas added inline comments.Aug 7 2018, 9:17 AM
src/widgets/kurlcombobox.cpp
356–357

Sure has :) I was thinking if a nicer solution would be to use a smart pointer in the itemList instead? That way we wouldn't need to go hunting for this and risk introducing leaks again? Do we have any favorite smart pointer for this? Or would a std::unique_ptr be fine?

dfaure added a comment.Aug 7 2018, 9:30 AM

std::unique_ptr sounds fine indeed.

hallas updated this revision to Diff 39249.Aug 7 2018, 11:31 AM

Refactored the code to use std::shared pointers instead.

dfaure requested changes to this revision.Aug 7 2018, 11:52 AM

Why shared? I don't see any ownership sharing happening. The list owns the pointers. I'm always wary of shared_ptr because it's often overused as "we don't really know who's responsible for deleting this, so let's just refcount it". But there's no refcounting needed here. The ownership is very clear here.

This revision now requires changes to proceed.Aug 7 2018, 11:52 AM

Why shared? I don't see any ownership sharing happening. The list owns the pointers. I'm always wary of shared_ptr because it's often overused as "we don't really know who's responsible for deleting this, so let's just refcount it". But there's no refcounting needed here. The ownership is very clear here.

My first approach was to use unique_ptr, but then I realized that pointers are shared between the defaultList and the itemMapper (see for example line 164) and also between the itemList and the itemMapper (see line 278, 291 and others), but I can't see any sharing between the defaultList and itemList. I thought of using a std::weak_ptr in the itemMapper, but I am not sure that entries are always removed from itemMapper when the are removed from the defaultList or itemMapper, also if the itemMapper should be able to hold objects from both lists I think it is more sane to use a shared_ptr.

Let me know what you think

dfaure resigned from this revision.Aug 7 2018, 12:07 PM

The ownership was clear in the original code: itemList and defaultList own the items, the rest (like itemMapper) doesn't.
So unique_ptrs in itemList and defaultList, and raw pointers elsewhere, would be perfectly fine and much clearer.
Don't fall into the "no raw pointers" trap. The correct recommendation is "no raw pointers that own the object".

hallas updated this revision to Diff 39252.Aug 7 2018, 1:17 PM

Refactored to use std::vector and std::unique_ptr

dfaure requested changes to this revision.Aug 7 2018, 2:54 PM

Thanks ;)

src/widgets/kurlcombobox.cpp
359

problem: i shouldn't be in increased after this...

Maybe this should use iterators instead?

A unitttest is missing for this code path, in any case.

366

same here.

Maybe erase(remove_if()) would be best.

This revision now requires changes to proceed.Aug 7 2018, 2:54 PM
hallas updated this revision to Diff 39265.Aug 7 2018, 6:44 PM
hallas marked 2 inline comments as done.

Use remove_if for removing entries from itemList and defaultList.
Added unit test of KUrlComboBox::removeUrl.

src/widgets/kurlcombobox.cpp
359

In general this class is not covered very well by unit test, I have added a test case that covers most of the removeUrl functionality, but I think I will do a different patch with more unit test.

dfaure accepted this revision.Aug 8 2018, 7:46 AM

Very nice work, thanks!

Do you have a KDE contributor account, to push this commit?

This revision is now accepted and ready to land.Aug 8 2018, 7:46 AM
hallas added a comment.Aug 8 2018, 7:47 AM

Very nice work, thanks!

Do you have a KDE contributor account, to push this commit?

No, not yet - do you think I should apply for one? I would really like to continue posting patches :)

dfaure added a comment.Aug 8 2018, 8:02 AM

Yes, I think you should apply for one. You can quote my name when the form asks who recommended you.

hallas updated this revision to Diff 39393.Aug 10 2018, 9:44 AM

Rebased

hallas closed this revision.Aug 10 2018, 10:22 AM