mirror of https://github.com/OpenTTD/OpenTTD
(svn r20089) -Fix [FS#3932]: Access of already freed memory, esp. due to hidden destructor call from Swap().
parent
02e4371ecb
commit
4ce5c6d93d
|
@ -27,6 +27,21 @@ ContentInfo::~ContentInfo()
|
||||||
free(this->tags);
|
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 ContentInfo::Size() const
|
||||||
{
|
{
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
|
|
|
@ -88,6 +88,8 @@ struct ContentInfo {
|
||||||
/** Free everything allocated */
|
/** Free everything allocated */
|
||||||
~ContentInfo();
|
~ContentInfo();
|
||||||
|
|
||||||
|
void TransferFrom(ContentInfo *other);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the size of the data as send over the network.
|
* Get the size of the data as send over the network.
|
||||||
* @return the size.
|
* @return the size.
|
||||||
|
|
|
@ -135,15 +135,13 @@ DEF_CONTENT_RECEIVE_COMMAND(Client, PACKET_CONTENT_SERVER_INFO)
|
||||||
/*
|
/*
|
||||||
* As ici might be selected by the content window we cannot delete that.
|
* 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
|
* 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
|
* we (just) already preserved.
|
||||||
* memory and more may be added, we cannot simply copy ci to ici as that
|
* So transfer data and ownership of allocated memory from ci to ici.
|
||||||
* might cause a leak of memory. As such we need to swap the data and
|
|
||||||
* then delete the memory we allocated here.
|
|
||||||
*/
|
*/
|
||||||
Swap(*ici, *ci);
|
ici->TransferFrom(ci);
|
||||||
delete ci;
|
delete ci;
|
||||||
|
|
||||||
this->OnReceiveContentInfo(ci);
|
this->OnReceiveContentInfo(ici);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue