From e32af79144aa37c46b1cbdfa8d77674d8c61b080 Mon Sep 17 00:00:00 2001 From: Jeff Quast Date: Sat, 22 Aug 2026 14:06:16 +0000 Subject: [PATCH] Construct SimSprite and initialize pointer members newSprite() allocated SimSprite with newPtr (malloc) and then assigned to its std::string name member while the member held unconstructed storage, which is undefined behaviour that worked on a zero-filled heap. Construct the object in place over the existing pooled allocation. Micropolis::callback, mapBase and mopBase have the same problem: all three are read before assignment in guarded paths (setCallback deletes the previous callback; initMapArrays guards on the base pointers), so give them NULL default initializers. --- packages/micropolis-engine/src/micropolis.h | 6 +++--- packages/micropolis-engine/src/sprite.cpp | 4 ++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/micropolis-engine/src/micropolis.h b/packages/micropolis-engine/src/micropolis.h index 60141c35..676f84e2 100644 --- a/packages/micropolis-engine/src/micropolis.h +++ b/packages/micropolis-engine/src/micropolis.h @@ -968,7 +968,7 @@ class Micropolis { /** * Callback interface. */ - Callback *callback; + Callback *callback = NULL; /** @@ -1411,8 +1411,8 @@ class Micropolis { /** * Memory for map array. */ - unsigned short *mapBase; - unsigned short *mopBase; + unsigned short *mapBase = NULL; + unsigned short *mopBase = NULL; void initMapArrays(); diff --git a/packages/micropolis-engine/src/sprite.cpp b/packages/micropolis-engine/src/sprite.cpp index 5cab2c8f..2eeb884e 100644 --- a/packages/micropolis-engine/src/sprite.cpp +++ b/packages/micropolis-engine/src/sprite.cpp @@ -77,6 +77,8 @@ //////////////////////////////////////////////////////////////////////// +#include + #include "micropolis.h" #include "text.h" @@ -112,6 +114,8 @@ SimSprite *Micropolis::newSprite(const std::string &name, int type, int x, int y freeSprites = sprite->next; } else { sprite = (SimSprite *)newPtr(sizeof (SimSprite)); + // newPtr is malloc, so construct the object in place. + new (sprite) SimSprite(); } sprite->name = name;