Fix out-of-bounds crash in PluginIterator_Next#2445
Fix out-of-bounds crash in PluginIterator_Next#2445SCP-076 wants to merge 3 commits intoalliedmodders:masterfrom
Conversation
This prevents the native from returning true when the iterator has already reached the end() of the list, which previously led to a crash when accessing the Plugin property.
Kenzzer
left a comment
There was a problem hiding this comment.
Good catch, but this is still going to create undefined behaviour/crash if the iterator is advanced again after being exhausted.
Reflect the new NativeError thrown when calling Next() on an exhausted iterator.
Kenzzer
left a comment
There was a problem hiding this comment.
This is much needed sanity around the plugin iterator, thanks for the work. Will let this sit for a few days to give the others a chance to comment if they want to.
Thanks. Just to be clear, the legacy iterator from The current mix of the Methodmap implementation and its base class is quite confusing and definitely calls for a proper refactor someday.
|
|
To prevent legacy iterator crashes without altering its expected behavior, we could add similar bounds checking to the underlying core static cell_t ReadPlugin(IPluginContext *pContext, const cell_t *params)
{
Handle_t hndl = (Handle_t)params[1];
HandleError err;
IPluginIterator *pIter;
HandleSecurity sec;
sec.pIdentity = g_pCoreIdent;
sec.pOwner = pContext->GetIdentity();
if ((err=handlesys->ReadHandle(hndl, g_PlIter, &sec, (void **)&pIter)) != HandleError_None)
{
return pContext->ThrowNativeError("Could not read Handle %x (error %d)", hndl, err);
}
// Check at the native level without modifying IPluginIterator->GetPlugin()
if(!pIter->MorePlugins())
return BAD_HANDLE;
IPlugin *pPlugin = pIter->GetPlugin();
if (!pPlugin)
{
return BAD_HANDLE;
}
pIter->NextPlugin();
return pPlugin->GetMyHandle();
}Let me know if you'd like me to include this fix to make the legacy iterator completely crash-proof from any SP calls. |
fixes #1880
Previously,
PluginIterator_NextcheckedMorePlugins()before callingNextPlugin(). This flawed logic caused the native to return true even whenNextPlugin()pushed the internal iterator to theend()of the list.This commit swaps the execution order: the iterator is now advanced first, and then validated. This ensures
Next()correctly returns false when reaching the end of the plugin list.