mirror of
https://github.com/azerothcore/mod-ale
synced 2025-11-29 15:38:17 +08:00
Add overflow checking for CHECKVAL.
This commit is contained in:
@@ -462,6 +462,47 @@ void Eluna::Push(lua_State* L, Object const* obj)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32 CheckIntegerRange(lua_State *L, int narg, int32 max, int32 min)
|
||||||
|
{
|
||||||
|
int32 value = luaL_checklong(L, narg);
|
||||||
|
char error_buffer[64];
|
||||||
|
|
||||||
|
if (value > max)
|
||||||
|
{
|
||||||
|
snprintf(error_buffer, 64, "value must be less than %u", max);
|
||||||
|
return luaL_argerror(L, narg, error_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value < min)
|
||||||
|
{
|
||||||
|
snprintf(error_buffer, 64, "value must be greater than %d", min);
|
||||||
|
return luaL_argerror(L, narg, error_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function does not work properly for anything larger than uint16.
|
||||||
|
static uint32 CheckUnsignedRange(lua_State *L, int narg, uint32 max)
|
||||||
|
{
|
||||||
|
int32 value = luaL_checklong(L, narg);
|
||||||
|
char error_buffer[64];
|
||||||
|
|
||||||
|
if (value < 0)
|
||||||
|
return luaL_argerror(L, narg, "value must be greater than 0");
|
||||||
|
|
||||||
|
// Prevent signed-unsigned mismatch.
|
||||||
|
// This cast is safe because the value is not negative.
|
||||||
|
uint32 u_value = value;
|
||||||
|
if (u_value > max)
|
||||||
|
{
|
||||||
|
snprintf(error_buffer, 64, "value must be less than %u", max);
|
||||||
|
return luaL_argerror(L, narg, error_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return u_value;
|
||||||
|
}
|
||||||
|
|
||||||
template<> bool Eluna::CHECKVAL<bool>(lua_State* L, int narg)
|
template<> bool Eluna::CHECKVAL<bool>(lua_State* L, int narg)
|
||||||
{
|
{
|
||||||
return lua_toboolean(L, narg);
|
return lua_toboolean(L, narg);
|
||||||
@@ -476,19 +517,19 @@ template<> double Eluna::CHECKVAL<double>(lua_State* L, int narg)
|
|||||||
}
|
}
|
||||||
template<> int8 Eluna::CHECKVAL<int8>(lua_State* L, int narg)
|
template<> int8 Eluna::CHECKVAL<int8>(lua_State* L, int narg)
|
||||||
{
|
{
|
||||||
return luaL_checkint(L, narg);
|
return CheckIntegerRange(L, narg, SCHAR_MAX, SCHAR_MIN);
|
||||||
}
|
}
|
||||||
template<> uint8 Eluna::CHECKVAL<uint8>(lua_State* L, int narg)
|
template<> uint8 Eluna::CHECKVAL<uint8>(lua_State* L, int narg)
|
||||||
{
|
{
|
||||||
return luaL_checkunsigned(L, narg);
|
return CheckUnsignedRange(L, narg, UCHAR_MAX);
|
||||||
}
|
}
|
||||||
template<> int16 Eluna::CHECKVAL<int16>(lua_State* L, int narg)
|
template<> int16 Eluna::CHECKVAL<int16>(lua_State* L, int narg)
|
||||||
{
|
{
|
||||||
return luaL_checkint(L, narg);
|
return CheckIntegerRange(L, narg, SHRT_MIN, SHRT_MAX);
|
||||||
}
|
}
|
||||||
template<> uint16 Eluna::CHECKVAL<uint16>(lua_State* L, int narg)
|
template<> uint16 Eluna::CHECKVAL<uint16>(lua_State* L, int narg)
|
||||||
{
|
{
|
||||||
return luaL_checkunsigned(L, narg);
|
return CheckUnsignedRange(L, narg, USHRT_MAX);
|
||||||
}
|
}
|
||||||
template<> int32 Eluna::CHECKVAL<int32>(lua_State* L, int narg)
|
template<> int32 Eluna::CHECKVAL<int32>(lua_State* L, int narg)
|
||||||
{
|
{
|
||||||
@@ -496,7 +537,9 @@ template<> int32 Eluna::CHECKVAL<int32>(lua_State* L, int narg)
|
|||||||
}
|
}
|
||||||
template<> uint32 Eluna::CHECKVAL<uint32>(lua_State* L, int narg)
|
template<> uint32 Eluna::CHECKVAL<uint32>(lua_State* L, int narg)
|
||||||
{
|
{
|
||||||
return luaL_checkunsigned(L, narg);
|
// If a negative value is passed instead, it will become a large positive value.
|
||||||
|
// There is no way to catch this.
|
||||||
|
return luaL_checklong(L, narg);
|
||||||
}
|
}
|
||||||
template<> const char* Eluna::CHECKVAL<const char*>(lua_State* L, int narg)
|
template<> const char* Eluna::CHECKVAL<const char*>(lua_State* L, int narg)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user