Skip to content

Commit 7c6e21b

Browse files
authored
Cleo return arguments count check (#18)
1 parent 2729a3c commit 7c6e21b

File tree

2 files changed

+65
-12
lines changed

2 files changed

+65
-12
lines changed

cleo_sdk/CLEO.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ void WINAPI CLEO_SetThreadCondResult(CRunningScript* thread, BOOL result);
370370
void WINAPI CLEO_ThreadJumpAtLabelPtr(CRunningScript* thread, int labelPtr);
371371

372372
eDataType WINAPI CLEO_GetOperandType(const CRunningScript* thread); // peek parameter data type
373-
DWORD WINAPI CLEO_GetVarArgCount(CRunningScript* thread); // peek var-args count
373+
DWORD WINAPI CLEO_GetVarArgCount(CRunningScript* thread); // peek remaining var-args count
374374

375375
extern SCRIPT_VAR* opcodeParams;
376376
extern SCRIPT_VAR* missionLocals;

source/CCustomOpcodeSystem.cpp

+64-11
Original file line numberDiff line numberDiff line change
@@ -2075,7 +2075,7 @@ namespace CLEO
20752075
int label = 0;
20762076

20772077
char* moduleTxt = nullptr;
2078-
auto paramType = CLEO_GetOperandType(thread);
2078+
auto paramType = (eDataType)*thread->GetBytePointer();
20792079
switch (paramType)
20802080
{
20812081
// label of current script
@@ -2104,7 +2104,7 @@ namespace CLEO
21042104
break;
21052105

21062106
default:
2107-
SHOW_ERROR("Invalid type (%s) of the first argument in opcode [0AB1] in script %s \nScript suspended.", ToKindStr(paramType), ((CCustomScript*)thread)->GetInfoStr().c_str());
2107+
SHOW_ERROR("Invalid type (%s) of the 'input param count' argument in opcode [0AB1] in script %s \nScript suspended.", ToKindStr(paramType), ((CCustomScript*)thread)->GetInfoStr().c_str());
21082108
return CCustomOpcodeSystem::ErrorSuspendScript(thread);
21092109
}
21102110

@@ -2142,13 +2142,41 @@ namespace CLEO
21422142
label = scriptRef.offset;
21432143
}
21442144

2145-
DWORD nParams = 0;
2146-
if(*thread->GetBytePointer()) *thread >> nParams;
2147-
if(nParams > 32)
2145+
// "number of input parameters" opcode argument
2146+
DWORD nParams;
2147+
paramType = (eDataType)*thread->GetBytePointer();
2148+
switch (paramType)
21482149
{
2149-
SHOW_ERROR("Argument count (%d), out of supported range (32) of opcode [0AB1] in script %s", nParams, ((CCustomScript*)thread)->GetInfoStr().c_str());
2150+
case DT_END:
2151+
nParams = 0;
2152+
break;
21502153

2151-
return CCustomOpcodeSystem::ErrorSuspendScript(thread);
2154+
// literal integers
2155+
case DT_BYTE:
2156+
case DT_WORD:
2157+
case DT_DWORD:
2158+
*thread >> nParams;
2159+
break;
2160+
2161+
default:
2162+
SHOW_ERROR("Invalid type of first argument in opcode [0AB1], in script %s", ((CCustomScript*)thread)->GetInfoStr().c_str());
2163+
return CCustomOpcodeSystem::ErrorSuspendScript(thread);
2164+
}
2165+
if (nParams)
2166+
{
2167+
auto nVarArg = GetVarArgCount(thread);
2168+
if (nParams > nVarArg) // if less it means there are return params too
2169+
{
2170+
SHOW_ERROR("Opcode [0AB1] declared %d input args, but provided %d in script %s\nScript suspended.", nParams, nVarArg, ((CCustomScript*)thread)->GetInfoStr().c_str());
2171+
return CCustomOpcodeSystem::ErrorSuspendScript(thread);
2172+
}
2173+
2174+
if (nParams > 32)
2175+
{
2176+
SHOW_ERROR("Argument count %d is out of supported range (32) of opcode [0AB1] in script %s", nParams, ((CCustomScript*)thread)->GetInfoStr().c_str());
2177+
2178+
return CCustomOpcodeSystem::ErrorSuspendScript(thread);
2179+
}
21522180
}
21532181

21542182
static SCRIPT_VAR arguments[32];
@@ -2228,18 +2256,43 @@ namespace CLEO
22282256
{
22292257
ScmFunction *scmFunc = ScmFunction::Store[reinterpret_cast<CCustomScript*>(thread)->GetScmFunction()];
22302258

2231-
DWORD returnParamCount = 0;
2232-
if (*thread->GetBytePointer()) *thread >> returnParamCount;
2259+
DWORD returnParamCount = GetVarArgCount(thread);
2260+
if (returnParamCount)
2261+
{
2262+
DWORD declaredParamCount;
2263+
2264+
auto paramType = (eDataType)*thread->GetBytePointer();
2265+
switch (paramType)
2266+
{
2267+
// literal integers
2268+
case DT_BYTE:
2269+
case DT_WORD:
2270+
case DT_DWORD:
2271+
*thread >> declaredParamCount;
2272+
break;
2273+
2274+
default:
2275+
SHOW_ERROR("Invalid type of first argument in opcode [0AB2], in script %s", ((CCustomScript*)thread)->GetInfoStr().c_str());
2276+
return CCustomOpcodeSystem::ErrorSuspendScript(thread);
2277+
}
2278+
2279+
if(returnParamCount - 1 != declaredParamCount) // minus 'num args' itself
2280+
{
2281+
SHOW_ERROR("Opcode [0AB2] declared %d return args, but provided %d in script %s\nScript suspended.", declaredParamCount, returnParamCount - 1, ((CCustomScript*)thread)->GetInfoStr().c_str());
2282+
return CCustomOpcodeSystem::ErrorSuspendScript(thread);
2283+
}
2284+
}
22332285
if (returnParamCount) GetScriptParams(thread, returnParamCount);
22342286

22352287
scmFunc->Return(thread); // jump back to cleo_call, right after last input param. Return slot var args starts here
22362288
if (scmFunc->moduleExportRef != nullptr) GetInstance().ModuleSystem.ReleaseModuleRef((char*)scmFunc->moduleExportRef); // export - release module
22372289
delete scmFunc;
22382290

22392291
DWORD returnSlotCount = GetVarArgCount(thread);
2240-
if (returnSlotCount > returnParamCount)
2292+
if(returnParamCount) returnParamCount--; // do not count the 'num args' argument itself
2293+
if (returnSlotCount != returnParamCount)
22412294
{
2242-
SHOW_ERROR("Opcode [0AB2] returned fewer params than expected by function caller in script %s\nScript suspended.", ((CCustomScript*)thread)->GetInfoStr().c_str());
2295+
SHOW_ERROR("Opcode [0AB2] returned %d params, while function caller expected %d in script %s\nScript suspended.", returnParamCount, returnSlotCount, ((CCustomScript*)thread)->GetInfoStr().c_str());
22432296
return CCustomOpcodeSystem::ErrorSuspendScript(thread);
22442297
}
22452298

0 commit comments

Comments
 (0)