Page 1 of 1
CTD using GetSpellNameByID
Posted: Fri Oct 01, 2004 3:53 am
by Zoydburg
This happens when you try to use GetSpellNameByID() with an epmty spell Gem
Output wrote:
First-chance exception at 0x01717cb7 (MQ2Main.dll) in eqgame.exe: 0xC0000005: Access violation reading location 0x4152a7d4.
Call Stack wrote:
> MQ2Main.dll!GetSpellNameByID(unsigned long dwSpellID=4294967295) Line 866 C++
Locals wrote:
dwSpellID 4294967295 unsigned long
MQ2Utilities.cpp
Code: Select all
PCHAR GetSpellNameByID(DWORD dwSpellID)
{
PSPELL pSpell = NULL;
if (ppSpellMgr == NULL) return "Unknown Spell";
pSpell = &(*((PSPELLMGR)pSpellMgr)->Spells[dwSpellID]);
if (pSpell != NULL) {
>> if (pSpell->Name != NULL) {
if (pSpell->Name[0]!='\0') {
return pSpell->Name;
}
}
}
return "Unknown Spell";
}
Posted: Fri Oct 01, 2004 4:19 am
by Zoydburg
Also get a CTD using GetSpellByID() and a blank spell slot
Output wrote:
First-chance exception at 0x0340121c in eqgame.exe: 0xC0000005: Access violation reading location 0x00000210.
Call Stack wrote:
> MQ2SpellSet.dll!0340121c()
Disasembaly wrote:
03401218 jmp 0340121C
0340121A xor eax,eax
>0340121C mov edx,dword ptr [eax+210h]
03401222 push esi
03401223 push edx
03401224 lea eax,[esp+1018h]
code that calls GetSpellByID()
Code: Select all
VOID MemSpellSet(PSPAWNINFO pChar, PCHAR szLine)
{
for (i=1; i<=9; i++)
{
PSPELL pSpell=GetSpellByID(GetCharInfo()->MemorizedSpells[i-1]);
sprintf(szMsg,"Spell %s goes in Gem %d",pSpell->Name, i);
WriteChatColor(szMsg,USERCOLOR_CHAT_CHANNEL);
}
}
Posted: Fri Oct 01, 2004 9:15 am
by Amadeus
What's the syntax of the macro you're using to get this error? I'm not sure I'm following on how you're creating this bug.
Posted: Fri Oct 01, 2004 4:38 pm
by Zoydburg
Not a macro its a plugin and anytime I use either the GetSpellByID() or GetSpellNameByID() and the spell slot I am searching is blank it CTD's
Code: Select all
GetCharInfo()->MemorizedSpells[i-1]
Returns a -1 if the spell slot it is searching is empty
I tried
Code: Select all
VOID MemSpellSet(PSPAWNINFO pChar, PCHAR szLine)
{
for (i=1; i<=9; i++)
{
PSPELL pSpell=GetSpellByID(GetCharInfo()->MemorizedSpells[i-1]);
sprintf(szMsg,"Spell %s goes in Gem %d",pSpell->Name, i);
WriteChatColor(szMsg,USERCOLOR_CHAT_CHANNEL);
}
}
and
Code: Select all
VOID MemSpellSet(PSPAWNINFO pChar, PCHAR szLine)
{
CHAR szSpellName[MAX_STRING] = {0};
for (i=1; i<=9; i++)
{
sprintf(szSpellname,"%s",GetSpellNameByID(GetCharInfo()->MemorizedSpells[i-1]));
sprintf(szMsg,"Spell %s goes in Gem %d",szSpellName, i);
WriteChatColor(szMsg,USERCOLOR_CHAT_CHANNEL);
}
}
Posible fix for GetSpellNameByID, I have not tested it but looking at the code this looks like it will fix it
Code: Select all
PCHAR GetSpellNameByID(DWORD dwSpellID)
{
if(dwSpellID == -1) return "Unknown Spell";
PSPELL pSpell = NULL;
if (ppSpellMgr == NULL) return "Unknown Spell";
pSpell = &(*((PSPELLMGR)pSpellMgr)->Spells[dwSpellID]);
if (pSpell != NULL) {
if (pSpell->Name != NULL) {
if (pSpell->Name[0]!='\0') {
return pSpell->Name;
}
}
}
return "Unknown Spell";
}
Posted: Fri Oct 01, 2004 4:40 pm
by dont_know_at_all
Zoydburg wrote:Not a macro its a plugin and anytime I use either the GetSpellByID() or GetSpellNameByID() and the spell slot I am searching is blank it CTD's
Well, duh. Check for a blank one.
Posted: Fri Oct 01, 2004 4:49 pm
by Zoydburg
Yes DKAA I did that, but it still should not CTD if someone does not do that it should return Unknown Spell or NULL or something.
Posted: Fri Oct 01, 2004 4:58 pm
by dont_know_at_all
Please use macros and not plugins.
Posted: Fri Oct 01, 2004 5:02 pm
by Zoydburg
I was trying to update Digitalxero's MQ2SpellSet when I found this BUG. Though it looks like he updated it lastnight at the same time I was playing with it.
Posted: Fri Oct 01, 2004 5:19 pm
by dont_know_at_all
Your crash is not a bug.
If you are going to call functions with the wrong data, you're going to get crashes. We have no way of determining if the spell id is valid or not. YOU have to check MemorizedSpells before you use it. It's not guarranteed to be a valid spell ID.
Posted: Fri Oct 01, 2004 6:22 pm
by Amadeus
Yes, a plugin has to be coded correctly and has to have the check in the plugin's code. The plugin should verify that the spell gem and/or the spell id is valid before it calls the function.