LunaCON: bound-check defineprojectile tile/sound members.

Also from Lunatic, make these members read-only and provide methods that
allow setting them to either -1 or a number in [0..MAX{TILES,SOUNDS}-1].

git-svn-id: https://svn.eduke32.com/eduke32@3865 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2013-06-09 16:37:16 +00:00
parent dee8dbe092
commit 0d951f0256
3 changed files with 54 additions and 18 deletions

View file

@ -10932,11 +10932,15 @@ static int32_t check_filename_casing(void)
const char *g_sizes_of_what[] = {
"sectortype", "walltype", "spritetype", "spriteext_t",
"actor_t", "DukePlayer_t", "playerdata_t",
"user_defs", "tiledata_t", "weapondata_t" };
"user_defs", "tiledata_t", "weapondata_t",
"projectile_t",
};
int32_t g_sizes_of[] = {
sizeof(sectortype), sizeof(walltype), sizeof(spritetype), sizeof(spriteext_t),
sizeof(actor_t), sizeof(DukePlayer_t), sizeof(playerdata_t),
sizeof(user_defs), sizeof(tiledata_t), sizeof(weapondata_t) };
sizeof(user_defs), sizeof(tiledata_t), sizeof(weapondata_t),
sizeof(projectile_t)
};
DukePlayer_t *g_player_ps[MAXPLAYERS];
#endif

View file

@ -302,10 +302,12 @@ struct {
int32_t workslike, cstat;
int32_t hitradius, range, flashcolor;
const int16_t spawns;
int16_t sound, isound, vel;
const int16_t sound, isound;
int16_t vel;
const int16_t decal, trail;
int16_t tnum, drop;
int16_t offset, bounces, bsound;
int16_t offset, bounces;
const int16_t bsound;
int16_t toffset;
int16_t extra, extra_rand;
int8_t sxrepeat, syrepeat, txrepeat, tyrepeat;
@ -707,7 +709,7 @@ string.dump = nil
-- sanity-check struct type sizes
local good = true
for i=0,9 do
for i=0,10 do
local what = ffi.string(ffiC.g_sizes_of_what[i])
local fsz = ffi.sizeof(what)
local csz = ffiC.g_sizes_of[i]
@ -1203,20 +1205,24 @@ end
setmtonce(player_mt.__index, { __index = player_index_index })
ffi.metatype("DukePlayer_t", player_mt)
local function GenProjectileSetFunc(Member)
return function(self, picnum)
if (not (picnum < 0)) then
check_tile_idx(picnum)
local function GenProjectileSetFunc(Member, checkfunc)
return function(self, idx)
if (not (idx == -1)) then
checkfunc(idx)
end
ffi.cast(projectile_ptr_ct, self)[Member] = picnum
ffi.cast(projectile_ptr_ct, self)[Member] = idx
end
end
local projectile_mt = {
__index = {
set_spawns = GenProjectileSetFunc "spawns",
set_decal = GenProjectileSetFunc "decal",
set_trail = GenProjectileSetFunc "trail",
set_spawns = GenProjectileSetFunc("spawns", check_tile_idx),
set_decal = GenProjectileSetFunc("decal", check_tile_idx),
set_trail = GenProjectileSetFunc("trail", check_tile_idx),
set_sound = GenProjectileSetFunc("sound", check_sound_idx),
set_isound = GenProjectileSetFunc("isound", check_sound_idx),
set_bsound = GenProjectileSetFunc("bsound", check_sound_idx),
},
}
ffi.metatype("projectile_t", projectile_mt)

View file

@ -572,13 +572,22 @@ local function parse_number(pos, numstr)
return num
end
-- returns: OK?
local function check_tilenum(tilenum)
-- Bound checking functions that generate a compilation error on failure.
local check = {}
function check.tile_idx(tilenum)
if (not (tilenum >= 0 and tilenum < MAXTILES)) then
errprintf("invalid tile number %d", tilenum)
return false
end
return true
end
function check.sound_idx(sidx)
if (not (sidx >= 0 and sidx < conl.MAXSOUNDS)) then
errprintf("invalid sound number %d", sidx)
return false
end
return true
end
@ -1030,18 +1039,35 @@ function Cmd.definequote(qnum, quotestr)
return ""
end
local PROJ = {}
for key, val in pairs(conl.PROJ) do
-- Strip "PROJ_"
PROJ[key:sub(6)] = val
end
function Cmd.defineprojectile(tilenum, what, val)
local ok = check_tilenum(tilenum)
local ok = check.tile_idx(tilenum)
if (what==PROJ.WORKSLIKE) then
local rbits = bit.bnot(2^21-1)
if (bit.band(val, rbits) ~= 0) then
warnprintf("set one or more reserved bits (0x%s) for PROJ_WORKSLIKE",
bit.tohex(bit.band(rbits, val)))
end
elseif (what==PROJ.SOUND or what==PROJ.ISOUND or what==PROJ.BSOUND) then
ok = ok and (val==-1 or check.sound_idx(val))
elseif (what==PROJ.SPAWNS or what==PROJ.DECAL or what==PROJ.TRAIL) then
ok = ok and (val==-1 or check.tile_idx(val))
end
if (ffi and ok) then
-- TODO: potentially bound-check some members?
ffiC.C_DefineProjectile(tilenum, what, val)
end
end
-- flags: if string, look up in ffiC and OR, else set number directly.
function Cmd.xspriteflags(tilenum, flags)
local ok = check_tilenum(tilenum)
local ok = check.tile_idx(tilenum)
if (ffi and ok) then
if (type(flags)=="number") then