Skip to content

Commit fed2fde

Browse files
Ensure that duplicated CData has a valid or nil parent
Rather than inheriting the parent field for paragraphs stored in a CData object, it is replaced or explicitly set to nil. This prevents CData from carrying dangling pointers to objects which may subsequently be deleted.
1 parent 2dc5e0f commit fed2fde

File tree

2 files changed

+30
-4
lines changed

2 files changed

+30
-4
lines changed

engine/src/cdata.cpp

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,28 @@ along with LiveCode. If not see <http://www.gnu.org/licenses/>. */
2727
#include "field.h"
2828
#include "paragraf.h"
2929

30-
MCCdata::MCCdata()
30+
MCCdata::MCCdata() :
31+
id(0),
32+
data(nil)
3133
{
32-
id = 0;
33-
data = NULL;
3434
}
3535

36-
MCCdata::MCCdata(const MCCdata &cref) : MCDLlist(cref)
36+
MCCdata::MCCdata(const MCCdata &cref) :
37+
MCDLlist(cref)
38+
{
39+
// Ensure that the paragraphs of the cloned data have their parent field
40+
// set to nil - this will catch attempts to use them without properly
41+
// setting the parent first.
42+
CloneData(cref, nil);
43+
}
44+
45+
MCCdata::MCCdata(const MCCdata& cref, MCField* p_new_owner) :
46+
MCDLlist(cref)
47+
{
48+
CloneData(cref, p_new_owner);
49+
}
50+
51+
void MCCdata::CloneData(const MCCdata& cref, MCField* p_new_owner)
3752
{
3853
id = cref.id;
3954
if (cref.data != NULL && cref.data != (void *)1)
@@ -46,7 +61,10 @@ MCCdata::MCCdata(const MCCdata &cref) : MCDLlist(cref)
4661
MCParagraph *tptr = (MCParagraph *)cref.data;
4762
do
4863
{
64+
// Clone the paragraph
4965
MCParagraph *newparagraph = new MCParagraph(*tptr);
66+
newparagraph->setparent(p_new_owner);
67+
5068
newparagraph->appendto(paragraphs);
5169
tptr = (MCParagraph *)tptr->next();
5270
}

engine/src/cdata.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class MCCdata : public MCDLlist
3232
MCCdata();
3333
MCCdata(uint4 newid);
3434
MCCdata(const MCCdata &fref);
35+
MCCdata(const MCCdata &fref, MCField* p_new_owner);
3536
~MCCdata();
3637
IO_stat load(IO_handle stream, MCObject *parent, uint32_t version);
3738
IO_stat save(IO_handle stream, Object_type type, uint4 p_part, uint32_t p_version);
@@ -81,6 +82,13 @@ class MCCdata : public MCDLlist
8182
{
8283
return (MCCdata *)MCDLlist::remove((MCDLlist *&)list);
8384
}
85+
86+
private:
87+
88+
// Clones the data from the given other MCCdata object, setting the
89+
// paragraphs of the data to have the given field as the parent object
90+
// (set to nil for non-field card data).
91+
void CloneData(const MCCdata& fref, MCField* p_new_owner);
8492
};
8593

8694
#endif

0 commit comments

Comments
 (0)