From c797298b6a6d3ecc9f5636ab3c5a9b7d5bd455bb Mon Sep 17 00:00:00 2001 From: helixhorned Date: Sun, 16 Mar 2014 14:37:54 +0000 Subject: [PATCH] C-CON: add safety checks for qgetsysstr/STR_{,MAP,PLAYER,VOLUME}NAME. Add test/qgetsysstr.con. BUILD_LUNATIC. git-svn-id: https://svn.eduke32.com/eduke32@4380 1a8010ca-5511-0410-912e-c29ae57300e0 --- polymer/eduke32/source/gameexec.c | 35 +++++++++++-- .../source/lunatic/test/qgetsysstr.con | 49 +++++++++++++++++++ 2 files changed, 81 insertions(+), 3 deletions(-) create mode 100644 polymer/eduke32/source/lunatic/test/qgetsysstr.con diff --git a/polymer/eduke32/source/gameexec.c b/polymer/eduke32/source/gameexec.c index 2e1a7343b..267ecb2a5 100644 --- a/polymer/eduke32/source/gameexec.c +++ b/polymer/eduke32/source/gameexec.c @@ -2131,12 +2131,36 @@ skip_check: switch (j) { case STR_MAPNAME: - Bstrcpy(ScriptQuotes[i],MapInfo[ud.volume_number*MAXLEVELS + ud.level_number].name); - break; case STR_MAPFILENAME: - Bstrcpy(ScriptQuotes[i],MapInfo[ud.volume_number*MAXLEVELS + ud.level_number].filename); + { + int32_t idx = ud.volume_number*MAXLEVELS + ud.level_number; + const char *src; + + if ((unsigned)idx >= ARRAY_SIZE(MapInfo)) + { + CON_ERRPRINTF("out of bounds map number (vol=%d, lev=%d)\n", + ud.volume_number, ud.level_number); + break; + } + + src = j==STR_MAPNAME ? MapInfo[idx].name : MapInfo[idx].filename; + if (src == NULL) + { + CON_ERRPRINTF("attempted access to %s of non-existent map (vol=%d, lev=%d)", + j==STR_MAPNAME ? "name" : "file name", + ud.volume_number, ud.level_number); + break; + } + + Bstrcpy(ScriptQuotes[i], j==STR_MAPNAME ? MapInfo[idx].name : MapInfo[idx].filename); break; + } case STR_PLAYERNAME: + if ((unsigned)vm.g_p >= (unsigned)playerswhenstarted) + { + CON_ERRPRINTF("Invalid player ID %d\n", vm.g_p); + break; + } Bstrcpy(ScriptQuotes[i],g_player[vm.g_p].user_name); break; case STR_VERSION: @@ -2147,6 +2171,11 @@ skip_check: Bstrcpy(ScriptQuotes[i],GametypeNames[ud.coop]); break; case STR_VOLUMENAME: + if ((unsigned)ud.volume_number >= MAXVOLUMES) + { + CON_ERRPRINTF("invalid volume (%d)\n", ud.volume_number); + break; + } Bstrcpy(ScriptQuotes[i],EpisodeNames[ud.volume_number]); break; default: diff --git a/polymer/eduke32/source/lunatic/test/qgetsysstr.con b/polymer/eduke32/source/lunatic/test/qgetsysstr.con new file mode 100644 index 000000000..6704af483 --- /dev/null +++ b/polymer/eduke32/source/lunatic/test/qgetsysstr.con @@ -0,0 +1,49 @@ + +gamevar vol 0 0 +gamevar lev 0 0 + +// out-of-bounds volume/level numbers +gamevar badvol_oob 99 0 +gamevar badlev_oob 999 0 + +// volume/level numbers for which no level is defined +gamevar badvol_nd 3 0 +gamevar badlev_nd 32 0 + +definequote 255 + +onevent EVENT_ENTERLEVEL + // must fail, since the current player is -1 in this event + qgetsysstr 255 STR_PLAYERNAME +endevent + +onevent EVENT_USESTEROIDS + getuserdef .volume_number vol + setuserdef .volume_number badvol_oob // LunaCON errors here + qgetsysstr 255 STR_VOLUMENAME // C-CON errors here + setuserdef .volume_number vol +endevent + +onevent EVENT_USEJETPACK + getuserdef .volume_number vol + getuserdef .level_number lev + + setuserdef .volume_number badvol_oob // LunaCON errors here + setuserdef .level_number badlev_oob + qgetsysstr 255 STR_MAPNAME // C-CON errors here + + setuserdef .volume_number vol + setuserdef .level_number lev +endevent + +onevent EVENT_JUMP + getuserdef .volume_number vol + getuserdef .level_number lev + + setuserdef .volume_number badvol_nd + setuserdef .level_number badlev_nd + qgetsysstr 255 STR_MAPFILENAME // LunaCON, C-CON error here + + setuserdef .volume_number vol + setuserdef .level_number lev +endevent