CTD on ${MacroQuest.LastCommand}

A forum for reporting bugs NOT related to custom plugins.

Moderator: MacroQuest Developers

tonio
a ghoul
a ghoul
Posts: 117
Joined: Fri Apr 02, 2004 12:57 am
Contact:

CTD on ${MacroQuest.LastCommand}

Post by tonio » Fri Apr 23, 2004 5:53 pm

I /echo'ed ${MacroQuest.LastCommand} and CTD'd. I hadn't entered any commands before that one (mebbe that's the problem).

Call Stack:

Code: Select all

>	MQ2Main.dll!memmove(unsigned char * dst=0x00130005, unsigned char * src=0x0012ffff, unsigned long count=1)  Line 333	Asm
 	MQ2Main.dll!ParseMacroData(char * szOriginal=0x00130005)  Line 707	C++
 	MQ2Main.dll!ParseMacroParameter(EQData::_SPAWNINFO * pChar=0x06b222c0, char * szOriginal=0x0012ae80)  Line 434	C++
 	MQ2Main.dll!CCommandHook::Detour(EQData::_SPAWNINFO * pChar=0x00130005, char * szFullLine=0x0012ffff)  Line 177 + 0xe	C++
 	652f206f()	
Pertinent debug spew:

Code: Select all

[MQ2]CCommandHook::Detour(/echo ${MacroQuest.LastCommand})
First-chance exception at 0x030382c6 (MQ2Main.dll) in eqgame.exe: 0xC0000005: Access violation writing location 0x00130005.
Disassembly:

Code: Select all

    TrailUp1:
            mov     al,[esi]        ;U - get byte from source
    030382C4  mov         al,byte ptr [esi] 
                                    ;V - spare
            mov     [edi],al        ;U - put byte in destination
[color=yellow]-->[/color] 030382C6  mov         byte ptr [edi],al 
            mov     eax,[dst]       ;V - return pointer to destination
    030382C8  mov         eax,dword ptr [dst] 
            pop     esi             ;U - restore esi
    030382CB  pop         esi  
            pop     edi             ;V - restore edi
    030382CC  pop         edi  
            M_EXIT
    030382CD  leave            
    030382CE  ret              
    030382CF  nop 
As far as I can tell, the source file seems to be "memcpy.asm", which doesn't sound right, but that's where the disassembly code was.
Tonio

User avatar
dont_know_at_all
Developer
Developer
Posts: 5450
Joined: Sun Dec 01, 2002 4:15 am
Location: Florida, USA
Contact:

Post by dont_know_at_all » Fri Apr 23, 2004 5:58 pm

Congratulations. You are the first person to successfully follow the directions for posting all the data needed to fix a bug.

Uh, it looks like there was some data corruption somewhere unrelaed to this command. Is this problem reproducible? What was the last command?
Last edited by dont_know_at_all on Fri Apr 23, 2004 6:51 pm, edited 1 time in total.

User avatar
Imperfect
Macro Author
Macro Author
Posts: 319
Joined: Fri Jun 14, 2002 1:52 am

Post by Imperfect » Fri Apr 23, 2004 6:02 pm

dont_know_at_all wrote:Congratulations. You are the first person to successfully follow the directions for posting all the data needed to fix a bug.

This will be fixed shortly.
Second person :)

tonio
a ghoul
a ghoul
Posts: 117
Joined: Fri Apr 02, 2004 12:57 am
Contact:

Post by tonio » Fri Apr 23, 2004 7:24 pm

Ok, got more info (thanks Lax!)...

Source file: mq2dataapi.cpp
Line: 707
(Line in red)

Code: Select all

BOOL ParseMacroData(PCHAR szOriginal)
{
	// find each {}
	PCHAR pBrace=strstr(szOriginal,"${");
	if (!pBrace)
		return false;
	unsigned long NewLength;
	BOOL Changed=false;
//	PCHAR pPos;
//	PCHAR pStart;
//	PCHAR pIndex;
	CHAR szCurrent[MAX_STRING]={0};

	do
	{
		// find this brace's end
		PCHAR pEnd=&pBrace[1];
		BOOL Quote=false;

		int nBrace=1;
		while(nBrace)
		{
			++pEnd;
			if (*pEnd==0)
			{// unmatched brace or quote
				goto pmdbottom;
			}
			if (*pEnd=='}')
			{
				if (!Quote)
					nBrace--;
			}
			else if (*pEnd=='{')
			{
				if (!Quote)
					nBrace++;
			}
			else if (*pEnd=='\"')
			{
				Quote=!Quote;
			}
		}
		*pEnd=0;
		strcpy(szCurrent,&pBrace[2]);
		if (szCurrent[0]==0)
		{
			goto pmdbottom;
		}
		if (ParseMacroData(szCurrent))
		{
			unsigned long NewLength=strlen(szCurrent);
			memmove(&pBrace[NewLength+1],&pEnd[1],strlen(&pEnd[1])+1);
			strncpy(pBrace,szCurrent,NewLength);
			pEnd=&pBrace[NewLength];
			*pEnd=0;
		}

		MQ2TYPEVAR Result;
		if (ParseMQ2DataPortion(szCurrent,Result))
			Result.Type->ToString(Result.VarPtr,szCurrent);
		else
			strcpy(szCurrent,"NULL");

		NewLength=strlen(szCurrent);

		memmove(&pBrace[NewLength],&pEnd[1],strlen(&pEnd[1])+1);
		[color=red]strncpy(pBrace,szCurrent,NewLength);[/color]
		Changed=true;

pmdbottom:;
	} while (pBrace=strstr(&pBrace[1],"${"));
	return Changed;
}
Also re-tested, issuing commands before /echo'ing ${MacroQuest.LastCommand}, and still CTD'd at the same line.

Hope that helps!
Tonio

Lax
We're not worthy!
We're not worthy!
Posts: 3524
Joined: Thu Oct 17, 2002 1:01 pm
Location: ISBoxer
Contact:

Post by Lax » Fri Apr 23, 2004 7:41 pm

no worries, now that login is working again i'm testing it and getting the same output you are. i'll get it fixed ;)
Lax Lacks
Master of MQ2 Disaster
Purveyor of premium, EULA-safe MMORPG Multiboxing Software
* Multiboxing with ISBoxer: Quick Start Video
* EQPlayNice, WinEQ 2.0

Lax
We're not worthy!
We're not worthy!
Posts: 3524
Joined: Thu Oct 17, 2002 1:01 pm
Location: ISBoxer
Contact:

Post by Lax » Fri Apr 23, 2004 7:54 pm

k heres the problem

In the current zip, the "last command" gets set before you actually execute your current one. In other words, the "last command" was:
/echo ${MacroQuest.LastCommand}

Now... put that through the MQ2Data parser, you get:
/echo /echo ${MacroQuest.LastCommand}
And it doesnt stop because it sees another ${
/echo /echo /echo ${MacroQuest.LastCommand}
/echo /echo /echo /echo ${MacroQuest.LastCommand}
... continue until the buffer overflows.

Unfortunately theres no good way to remove that, so next zip it'll work correctly, but you'll have to make sure your previous command did not involve ${MacroQuest.LastCommand} :lol:
Lax Lacks
Master of MQ2 Disaster
Purveyor of premium, EULA-safe MMORPG Multiboxing Software
* Multiboxing with ISBoxer: Quick Start Video
* EQPlayNice, WinEQ 2.0