2
3
mirror of https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git synced 2025-07-14 14:37:41 +00:00

Compare commits

...

19 Commits

Author SHA1 Message Date
883495c35c Merge branch 'ticket/53' 2023-10-23 15:12:43 -06:00
e1306da736 Merge branch 'ticket/52' 2023-10-23 15:12:40 -06:00
8d1d813df5 Merge branch 'ticket/51' 2023-10-23 15:12:37 -06:00
65d50895bb closes #53 2023-10-23 15:12:15 -06:00
6a41bdbee7 closes #52 2023-10-23 15:11:45 -06:00
3dcf1c2f26 closes #51 2023-10-23 15:11:03 -06:00
70449244f4 Merge branch 'ticket/53' 2023-10-02 20:13:56 -06:00
82abcb2f07 remove clearReceivers() 2023-10-02 10:34:28 -07:00
870d0534df Merge branch 'ticket/53' 2023-09-29 10:49:27 -06:00
1f09d6c48a Try without armature changes 2023-09-28 11:48:33 -07:00
66ce08ed67 Merge branch 'ticket/53' 2023-09-26 10:08:18 -06:00
1c1d3dd82e Merge branch 'ticket/52' 2023-09-26 10:08:14 -06:00
4924156ad4 Fix 3 problems with plSubWorldMsg.
Co-authored-by: Adam Johnson <AdamJohnso@gmail.com>
2023-09-18 09:50:23 -07:00
13ea0a98de Don't trust the local machine's system time.
Co-authored-by: Adam Johnson <AdamJohnso@gmail.com>
2023-09-18 09:41:33 -07:00
f9723462d7 Merge branch 'ticket/51' 2023-07-05 15:00:20 -06:00
7d3774a732 Unload all keys of all pages before deleting them
(ported from H-uru/Plasma@04d0ac94ea)
2023-06-29 22:04:17 +02:00
ea7e4b2ab5 Fix previous commits not actually nulling out the key
I goofed while porting this from H'uru, where the variable is a
reference. The previous code actually caused the keys to not get deleted
at all.
2023-06-26 00:16:24 +02:00
5d5ba00f7d Also guard against accessing plRegistryKeyList currently being deleted
Co-authored-by: Adam Johnson <AdamJohnso@gmail.com>

(ported from H-uru/Plasma@725eeaa288)
2023-06-25 16:50:10 +02:00
af38137822 Fix possible use after free in plRegistryPageNode::UnloadKeys
Short explanation: the destructor of plRegistryKeyList may indirectly
access other entries of fKeyLists where the plRegistryKeyList has
already been deleted, but not yet removed from the map.

Long explanation:
* Deleting a plRegistryKeyList also deletes all plKeys inside it, which
  decrements the reference count of the objects they point to.
* If one of the deleted keys happens to be the last reference to an
  object, this also deletes the object itself.
* The object's destructor might in turn delete another plKey, which
  calls SetKeyUnused, which tries to look up the key in its page.
* If this second plKey belongs to the page that is currently being
  unloaded, then its plRegistryKeyList may be partially or completely
  deleted, but still listed in the fKeyLists map. In this case, the key
  lookup accesses already freed memory.

(ported from H-uru/Plasma@a529e35fd9)
2023-06-25 16:44:35 +02:00
7 changed files with 37 additions and 42 deletions

View File

@ -217,6 +217,8 @@ bool plResponderModifier::IIsLocalOnlyCmd(plMessage* cmd)
return true;
if (plCameraMsg::ConvertNoRef(cmd)) // don't want to change our camera
return true;
if (plSubWorldMsg::ConvertNoRef(cmd)) // don't want to enter a subworld (changes the avatar SDL)
return true;
plSoundMsg *snd = plSoundMsg::ConvertNoRef( cmd );
if( snd != nil && snd->Cmd( plSoundMsg::kIsLocalOnly ) )

View File

@ -211,7 +211,7 @@ void plNCAgeJoiner::Start () {
plNetClientMgr * nc = plNetClientMgr::GetInstance();
nc->SetFlagsBit(plNetClientMgr::kPlayingGame, false);
nc->fServerTimeOffset = 0; // reset since we're connecting to a new server
nc->ResetServerTimeOffset();
nc->fRequiredNumInitialSDLStates = 0;
nc->fNumInitialSDLStates = 0;
nc->SetFlagsBit(plNetClientApp::kNeedInitialAgeStateCount);

View File

@ -133,9 +133,7 @@ plNetClientMgr::plNetClientMgr() :
// fProgressBar( nil ),
fTaskProgBar( nil ),
fMsgRecorder(nil),
fServerTimeOffset(0),
fTimeSamples(0),
fLastTimeUpdate(0),
fLastLocalTime(),
fListenListMode(kListenList_Distance),
fAgeSDLObjectKey(nil),
fExperimentalLevel(0),
@ -480,34 +478,23 @@ void plNetClientMgr::StartLinkInFX()
//
void plNetClientMgr::UpdateServerTimeOffset(plNetMessage* msg)
{
if ((hsTimer::GetSysSeconds() - fLastTimeUpdate) > 5)
{
fLastTimeUpdate = hsTimer::GetSysSeconds();
if (!msg->GetHasTimeSent())
return;
if (msg->GetTimeSent().AtEpoch())
return;
const plUnifiedTime& msgSentUT = msg->GetTimeSent();
if (!msgSentUT.AtEpoch())
{
double diff = plUnifiedTime::GetTimeDifference(msgSentUT, plClientUnifiedTime::GetCurrentTime());
double localTime = hsTimer::GetSeconds();
if (localTime - fLastLocalTime < 1.0)
return;
if (fServerTimeOffset == 0)
{
fServerTimeOffset = diff;
}
else
{
fServerTimeOffset = fServerTimeOffset + ((diff - fServerTimeOffset) / ++fTimeSamples);
}
DebugMsg("Setting server time offset to %f", fServerTimeOffset);
}
}
fLastServerTime = msg->GetTimeSent();
fLastLocalTime = localTime;
}
void plNetClientMgr::ResetServerTimeOffset()
{
fServerTimeOffset = 0;
fTimeSamples = 0;
fLastTimeUpdate = 0;
fLastServerTime.ToEpoch();
fLastLocalTime = 0.0;
}
//
@ -515,14 +502,12 @@ void plNetClientMgr::ResetServerTimeOffset()
//
plUnifiedTime plNetClientMgr::GetServerTime() const
{
if ( fServerTimeOffset==0 ) // offline mode or before connecting/calibrating to a server
if (fLastServerTime.AtEpoch()) {
WarningMsg("Someone asked for the server time, but we don't know it yet!");
return plUnifiedTime::GetCurrentTime();
plUnifiedTime serverUT;
if (fServerTimeOffset<0)
return plUnifiedTime::GetCurrentTime() - plUnifiedTime(fabs(fServerTimeOffset));
else
return plUnifiedTime::GetCurrentTime() + plUnifiedTime(fServerTimeOffset);
}
return fLastServerTime + plUnifiedTime(hsTimer::GetSeconds() - fLastLocalTime);
}
//

View File

@ -166,9 +166,8 @@ private:
std::string fSPDesiredPlayerName; // SP: the player we want to load from vault.
// server info
double fServerTimeOffset; // diff between our unified time and server's unified time
UInt32 fTimeSamples;
double fLastTimeUpdate;
plUnifiedTime fLastServerTime; // Last received time update from the server
double fLastLocalTime; // Last monotonic time (in seconds) when the above update was received
UInt8 fJoinOrder; // returned by the server

View File

@ -59,8 +59,10 @@ plRegistryKeyList::~plRegistryKeyList()
for (int i = 0; i < fStaticKeys.size(); i++)
{
plKeyImp* keyImp = fStaticKeys[i];
if (!keyImp->ObjectIsLoaded())
if (keyImp && !keyImp->ObjectIsLoaded()) {
fStaticKeys[i] = nullptr;
delete keyImp;
}
}
}

View File

@ -203,6 +203,7 @@ void plRegistryPageNode::UnloadKeys()
for (; it != fKeyLists.end(); it++)
{
plRegistryKeyList* keyList = it->second;
it->second = nullptr;
delete keyList;
}
fKeyLists.clear();

View File

@ -219,14 +219,20 @@ void plResManager::IShutdown()
// Shut down the registry (finally!)
ILockPages();
PageSet::const_iterator it;
for (it = fAllPages.begin(); it != fAllPages.end(); it++)
delete *it;
fAllPages.clear();
// Unload all keys before actually deleting the pages.
// When a key's refcount drops to zero, IKeyUnreffed looks up the key's page.
// If the page is already deleted at that point, this causes a use after free and potential crash.
for (PageSet::const_iterator it = fAllPages.begin(); it != fAllPages.end(); it++) {
(*it)->UnloadKeys();
}
fLoadedPages.clear();
fLastFoundPage = nil;
for (PageSet::const_iterator it = fAllPages.begin(); it != fAllPages.end(); it++) {
delete *it;
}
fAllPages.clear();
IUnlockPages();
fLastFoundPage = nil;
// Now, kill off the Dispatcher
hsRefCnt_SafeUnRef(fDispatch);