Mercurial > hg > openttd
changeset 15446:a77b7f93cb3f draft
(svn r20089) -Fix [FS#3932]: Access of already freed memory, esp. due to hidden destructor call from Swap().
author | frosch <frosch@openttd.org> |
---|---|
date | Thu, 08 Jul 2010 18:38:38 +0000 |
parents | 6dcdc3eb8d53 |
children | 8336429b0ffb |
files | src/network/core/tcp_content.cpp src/network/core/tcp_content.h src/network/network_content.cpp |
diffstat | 3 files changed, 21 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/src/network/core/tcp_content.cpp +++ b/src/network/core/tcp_content.cpp @@ -27,6 +27,21 @@ free(this->tags); } +/** + * Copy data from other #ContentInfo and take ownership of allocated stuff. + * @param other Source to copy from. #dependencies and #tags will be NULLed. + */ +void ContentInfo::TransferFrom(ContentInfo *other) +{ + if (other != this) { + free(this->dependencies); + free(this->tags); + memcpy(this, other, sizeof(ContentInfo)); + other->dependencies = NULL; + other->tags = NULL; + } +} + size_t ContentInfo::Size() const { size_t len = 0;
--- a/src/network/core/tcp_content.h +++ b/src/network/core/tcp_content.h @@ -88,6 +88,8 @@ /** Free everything allocated */ ~ContentInfo(); + void TransferFrom(ContentInfo *other); + /** * Get the size of the data as send over the network. * @return the size.
--- a/src/network/network_content.cpp +++ b/src/network/network_content.cpp @@ -135,15 +135,13 @@ /* * As ici might be selected by the content window we cannot delete that. * However, we want to keep most of the values of ci, except the values - * we (just) already preserved. As there are already allocated blobs of - * memory and more may be added, we cannot simply copy ci to ici as that - * might cause a leak of memory. As such we need to swap the data and - * then delete the memory we allocated here. + * we (just) already preserved. + * So transfer data and ownership of allocated memory from ci to ici. */ - Swap(*ici, *ci); + ici->TransferFrom(ci); delete ci; - this->OnReceiveContentInfo(ci); + this->OnReceiveContentInfo(ici); return true; } }