Skip to content

Commit

Permalink
Fixed|XG|libcommon: Misuse of dummy mobj in XG leading to a crash
Browse files Browse the repository at this point in the history
p_xgsec was converted to C++ with some minimal cleanup. XG now allocates
thinkers using ThinkerT, and does not call memset on the dummy mobj
(which is a C++ instance).

IssueID #1855
  • Loading branch information
skyjake committed Aug 16, 2014
1 parent 3734a1a commit 1959d40
Show file tree
Hide file tree
Showing 6 changed files with 130 additions and 114 deletions.
3 changes: 2 additions & 1 deletion doomsday/liblegacy/src/memoryzone.c
Expand Up @@ -874,6 +874,7 @@ dd_bool Z_Contains(void *ptr)
{
memvolume_t *volume;
memblock_t *block = Z_GetBlock(ptr);
DENG_ASSERT(Z_IsInited());
if(block->id != LIBDENG_ZONEID)
{
// Could be in the zone, but does not look like an allocated block.
Expand Down Expand Up @@ -1040,7 +1041,7 @@ size_t Z_FreeMemory(void)
void Z_PrintStatus(void)
{
size_t allocated = Z_AllocatedMemory();
size_t wasted = Z_FreeMemory();
size_t wasted = Z_FreeMemory();

App_Log(DE2_LOG_DEBUG,
"Memory zone status: %u volumes, %u bytes allocated, %u bytes free (%f%% in use)",
Expand Down
2 changes: 1 addition & 1 deletion doomsday/plugins/common/common.pri
Expand Up @@ -130,7 +130,7 @@ SOURCES += \
$$common_src/p_xgfile.cpp \
$$common_src/p_xgline.cpp \
$$common_src/p_xgsave.cpp \
$$common_src/p_xgsec.c \
$$common_src/p_xgsec.cpp \
$$common_src/player.cpp \
$$common_src/polyobjs.cpp \
$$common_src/r_common.c \
Expand Down
4 changes: 2 additions & 2 deletions doomsday/plugins/common/include/p_xgline.h
Expand Up @@ -403,7 +403,7 @@ typedef int (*LineTraverserFunc)(Line *line, dd_bool ceiling/*unused*/, void *co
* @c true. Stops checking when false is returned.
*/
int XL_TraverseLines(Line *line, int reftype, int ref, void *context, void *context2,
struct mobj_s *activator, int (C_DECL *func)());
struct mobj_s *activator, LineTraverserFunc func);

/// Function pointer to an XG plane traversal function.
typedef int (*PlaneTraverserFunc)(Sector *sector, dd_bool ceiling, void *context, void *context2, mobj_t *activator);
Expand All @@ -415,7 +415,7 @@ typedef int (*PlaneTraverserFunc)(Sector *sector, dd_bool ceiling, void *context
* @return @c true iff all callbacks return @c true.
*/
int XL_TraversePlanes(Line *line, int reftype, int ref, void *context, void *context2,
dd_bool travSectors, struct mobj_s *activator, int (C_DECL *func)());
dd_bool travSectors, struct mobj_s *activator, PlaneTraverserFunc func);

// Return false if the event was processed.
int XL_CrossLine(Line *line, int sideNum, struct mobj_s *thing);
Expand Down
2 changes: 1 addition & 1 deletion doomsday/plugins/common/include/p_xgsec.h
Expand Up @@ -157,7 +157,7 @@ extern "C" {
void XS_Init(void);
void XS_Update(void);

void XS_Thinker(xsthinker_t* xs);
void XS_Thinker(void *xsThinker);

coord_t XS_Gravity(Sector *sector);
coord_t XS_Friction(Sector *sector);
Expand Down
32 changes: 15 additions & 17 deletions doomsday/plugins/common/src/p_xgline.cpp
Expand Up @@ -949,12 +949,15 @@ void XL_SetLineType(Line *line, int id)
if(!Thinker_Iterate(XL_Thinker, findXLThinker, line))
{
// Not created one yet.
xlthinker_t *xl = (xlthinker_t *)Z_Calloc(sizeof(*xl), PU_MAP, 0);
/*xlthinker_t *xl = (xlthinker_t *)Z_Calloc(sizeof(*xl), PU_MAP, 0);
xl->thinker.function = XL_Thinker;
Thinker_Add(&xl->thinker);
xl->thinker.function = XL_Thinker;*/

ThinkerT<xlthinker_t> xl(Thinker::AllocateMemoryZone);
xl.function = XL_Thinker;
xl->line = line;

Thinker_Add(xl.Thinker::take());
}
}
else if(id)
Expand All @@ -966,7 +969,7 @@ void XL_SetLineType(Line *line, int id)

void XL_Init()
{
de::zap(dummyThing);
dummyThing.Thinker::zap();

// Clients rely on the server, they don't do XG themselves.
if(IS_CLIENT) return;
Expand All @@ -981,10 +984,8 @@ void XL_Init()
}

int XL_TraversePlanes(Line *line, int refType, int ref, void *data, void *context,
dd_bool travsectors, mobj_t *activator, int (*func_)())
dd_bool travsectors, mobj_t *activator, PlaneTraverserFunc func)
{
PlaneTraverserFunc func = de::function_cast<PlaneTraverserFunc>(func_);

int tag;
mobj_t *mo;
dd_bool ok, findSecTagged;
Expand Down Expand Up @@ -1183,10 +1184,8 @@ int XL_TraversePlanes(Line *line, int refType, int ref, void *data, void *contex
}

int XL_TraverseLines(Line* line, int rtype, int ref, void* data,
void* context, mobj_t* activator, int (*func_)())
void* context, mobj_t* activator, LineTraverserFunc func)
{
LineTraverserFunc func = de::function_cast<LineTraverserFunc>(func_);

int i;
int tag;
int reftype = rtype;
Expand Down Expand Up @@ -1479,14 +1478,14 @@ void XL_DoFunction(linetype_t *info, Line *line, int sideNum, mobj_t *actThing,
case TRAV_LINES: // Traverse lines, executing doFunc for each
XL_TraverseLines(line, info->iparm[xgClass->travRef],
info->iparm[xgClass->travData], line,
info, actThing, xgClass->doFunc);
info, actThing, de::function_cast<LineTraverserFunc>(xgClass->doFunc));
break;
case TRAV_PLANES: // Traverse planes, executing doFunc for each
case TRAV_SECTORS:
XL_TraversePlanes(line, info->iparm[xgClass->travRef],
info->iparm[xgClass->travData], line,
info, xgClass->traverse == TRAV_SECTORS? true : false,
actThing, xgClass->doFunc);
actThing, de::function_cast<PlaneTraverserFunc>(xgClass->doFunc));
break;
}
}
Expand Down Expand Up @@ -2201,8 +2200,7 @@ int XLTrav_EnableLine(Line *line, dd_bool /*ceiling*/, void *context,
dd_bool XL_CheckLineStatus(Line *line, int reftype, int ref, int active,
mobj_t *activator)
{
return XL_TraverseLines(line, reftype, ref, &active, 0, activator,
de::function_cast<int (*)()>(XLTrav_CheckLine));
return XL_TraverseLines(line, reftype, ref, &active, 0, activator, XLTrav_CheckLine);
}

int XL_CheckMobjGone(thinker_t *th, void *context)
Expand Down Expand Up @@ -2391,15 +2389,15 @@ void XL_ActivateLine(dd_bool activating, linetype_t* info, Line* line,
(!activating && (info->flags2 & LTF2_GROUP_DEACT)))
{
XL_TraverseLines(line, LREF_LINE_TAGGED, true, &activating, 0, activator_thing,
de::function_cast<int (*)()>(XLTrav_SmartActivate));
XLTrav_SmartActivate);
}

// For lines flagged Multiple, quick-(de)activate other lines that have
// the same line tag.
if(info->flags2 & LTF2_MULTIPLE)
{
XL_TraverseLines(line, LREF_LINE_TAGGED, true, &activating, 0, activator_thing,
de::function_cast<int (*)()>(XLTrav_QuickActivate));
XLTrav_QuickActivate);
}

// Should we apply the function of the line? Functions are defined by
Expand Down Expand Up @@ -2921,7 +2919,7 @@ void XL_Thinker(void *xlThinkerPtr)
if(info->flags & LTF_TICKER)
{
xg->tickerTimer = 0;
XL_LineEvent(XLE_TICKER, 0, line, 0, &dummyThing);
XL_LineEvent(XLE_TICKER, 0, line, 0, XG_DummyThing());
}

// How about some forced functions?
Expand Down

0 comments on commit 1959d40

Please sign in to comment.