Skip to content

Commit 0bf4831

Browse files
authored
Merge pull request odamex#1172 from electricbrass/serialize-fixes
[BUGFIX] Broken deserialization of `DPusher`s
2 parents 407fdea + 53fcab4 commit 0bf4831

File tree

2 files changed

+30
-28
lines changed

2 files changed

+30
-28
lines changed

common/p_spec.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,9 @@ void DPusher::Serialize (FArchive &arc)
467467
else
468468
{
469469
arc >> m_Type;
470-
arc.ReadObject((DObject*&)*m_Source, DPusher::StaticType());
470+
DObject* temp = nullptr;
471+
arc.ReadObject(temp, DPusher::StaticType());
472+
m_Source = temp ? static_cast<AActor*>(temp)->ptr() : AActor::AActorPtr();
471473
arc >> m_Xmag >> m_Ymag >> m_Magnitude >> m_Radius >> m_X >> m_Y >> m_Affectee;
472474
}
473475
}

common/szp.h

+27-27
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Emacs style mode select -*- C++ -*-
1+
// Emacs style mode select -*- C++ -*-
22
//-----------------------------------------------------------------------------
33
//
44
// $Id$
@@ -18,19 +18,19 @@
1818
// DESCRIPTION:
1919
//
2020
// denis - szp<T>, the self zeroing pointer
21-
//
22-
// Once upon a time, actors held raw pointers to other actors.
23-
//
24-
// To destroy an object, one cycled though all the others searching for its
25-
// pointer and resetting every copy to NULL. Then one did the cycling for
26-
// the players, then the sector sound origins, and so on; with hack upon
27-
// hack. Ironically, zero dereferencing is what often crashed the
21+
//
22+
// Once upon a time, actors held raw pointers to other actors.
23+
//
24+
// To destroy an object, one cycled though all the others searching for its
25+
// pointer and resetting every copy to NULL. Then one did the cycling for
26+
// the players, then the sector sound origins, and so on; with hack upon
27+
// hack. Ironically, zero dereferencing is what often crashed the
2828
// program altogether.
29-
//
30-
// The idea behind szp is that all copies of one szp pointer can be made
31-
// to point to the same object in O(1) time. This means that having a
32-
// single szp of an actor, you can set them all to NULL without iteration.
33-
// And, as a bonus, on every pointer access, a NULL check can throw a
29+
//
30+
// The idea behind szp is that all copies of one szp pointer can be made
31+
// to point to the same object in O(1) time. This means that having a
32+
// single szp of an actor, you can set them all to NULL without iteration.
33+
// And, as a bonus, on every pointer access, a NULL check can throw a
3434
// specific exception. Naturally, you should always be careful with pointers.
3535
//
3636
//-----------------------------------------------------------------------------
@@ -51,7 +51,7 @@ class szp
5151

5252
// this should never be used
5353
// spawn from other pointers, or use init()
54-
szp &operator =(T *other) {};
54+
szp &operator=(T *other) = delete;
5555

5656
// utility function to remove oneself from the linked list
5757
void inline unlink()
@@ -61,17 +61,17 @@ class szp
6161

6262
next->prev = prev;
6363
prev->next = next;
64-
64+
6565
if(!naive)
6666
return;
6767

6868
// last in ring?
6969
if(this == next)
7070
delete naive;
71-
71+
7272
naive = NULL;
7373
}
74-
74+
7575
public:
7676

7777
// use as pointer, checking validity
@@ -82,7 +82,7 @@ class szp
8282

8383
return *naive;
8484
}
85-
85+
8686
// use as raw pointer
8787
inline operator T*()
8888
{
@@ -97,11 +97,11 @@ class szp
9797
{
9898
if(!naive)
9999
throw CRecoverableError("szp pointer was NULL on update_all");
100-
100+
101101
// all copies already have naive, so their pointers will update too
102102
*naive = target;
103103
}
104-
104+
105105
// copy a pointer and add self to the "i have this pointer" list
106106
inline szp &operator =(szp other)
107107
{
@@ -116,31 +116,31 @@ class szp
116116
next = prev = this;
117117
return *this;
118118
}
119-
119+
120120
// link
121121
naive = other.naive;
122122
prev = other.next->prev;
123123
next = other.next;
124124
prev->next = next->prev = this;
125-
125+
126126
return *this;
127127
}
128-
128+
129129
// creates the first (original) pointer
130130
void init(T *target)
131131
{
132132
unlink();
133-
133+
134134
// first link
135135
naive = new T*(target);
136136
prev = next = this;
137137
}
138-
138+
139139
// cheap constructor
140140
inline szp()
141141
: naive(NULL), prev(NULL), next(NULL)
142142
{ }
143-
143+
144144
// copy constructor
145145
inline szp(const szp &other)
146146
: naive(NULL)
@@ -150,7 +150,7 @@ class szp
150150
prev = next = this;
151151
return;
152152
}
153-
153+
154154
// link
155155
naive = other.naive;
156156
prev = other.next->prev;

0 commit comments

Comments
 (0)