CON: Amend retrieval of STR_*TIME for qgetsysstr, fixing LunaCON and possible oob.

- Add declarations of C functions to defs.ilua, names to dynsymlist,
  fix typo in con_lang.lua, ffi.string() calls in control.lua
- Assert that G_LastMapInfoIndex() is always called with ud.last_level >= 1.
  (A stricter requirement than necessary to prevent follow-up oob accesses, but
  logically the most meaningful.)
- In G_PrintParTime() and G_PrintDesignerTime(), return "<invalid>" if the above
  does not hold. This can happen from EVENT_NEWGAME, for example. Add a test to
  lunatic/test/qgetsysstr.con.  DONT_BUILD.

git-svn-id: https://svn.eduke32.com/eduke32@4972 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2015-02-08 18:48:28 +00:00
parent b980ca7b0b
commit 70dc2f7376
7 changed files with 52 additions and 13 deletions

View file

@ -3377,9 +3377,10 @@ void G_SetCrosshairColor(int32_t r, int32_t g, int32_t b)
invalidatetile(CROSSHAIR, -1, -1);
}
static inline size_t G_LastMapInfoIndex(void)
static inline int G_LastMapInfoIndex(void)
{
return ud.volume_number*MAXLEVELS + ud.last_level - 1;
Bassert(ud.last_level >= 1); // NOTE: last_level is 1-based
return ud.volume_number*MAXLEVELS + ud.last_level-1;
}
#define SCORESHEETOFFSET -20
@ -12502,10 +12503,14 @@ const char* G_PrintYourTime(void)
}
const char* G_PrintParTime(void)
{
if (ud.last_level < 1)
return "<invalid>";
return G_PrintTime2(MapInfo[G_LastMapInfoIndex()].partime);
}
const char* G_PrintDesignerTime(void)
{
if (ud.last_level < 1)
return "<invalid>";
return G_PrintTime2(MapInfo[G_LastMapInfoIndex()].designertime);
}
const char* G_PrintBestTime(void)

View file

@ -861,7 +861,7 @@ local UserdefLabels = {
fta_on = UD".fta_on",
god = UDRO".god",
idplayers = UDRO".idplayers",
last_level = UDRO".lastlevel",
last_level = UDRO".last_level",
level_number = { UD".level_number", UD":set_level_number(%%s)", {0, MAXLEVELS-1} },
levelstats = UD".levelstats",
lockout = UDRO".lockout",

View file

@ -939,13 +939,13 @@ function _qgetsysstr(qdst, what, pli)
bcheck.volume_idx(vol)
ffi.copy(dst, ffiC.EpisodeNames[vol], ffi.sizeof(ffiC.EpisodeNames[0]))
elseif (what == ffiC.STR_YOURTIME) then
ffi.copy(dst, ffiC.G_PrintYourTime())
ffi.copy(dst, ffi.string(ffiC.G_PrintYourTime()))
elseif (what == ffiC.STR_PARTIME) then
ffi.copy(dst, ffiC.G_PrintParTime())
ffi.copy(dst, ffi.string(ffiC.G_PrintParTime()))
elseif (what == ffiC.STR_DESIGNERTIME) then
ffi.copy(dst, ffiC.G_PrintDesignerTime())
ffi.copy(dst, ffi.string(ffiC.G_PrintDesignerTime()))
elseif (what == ffiC.STR_BESTTIME) then
ffi.copy(dst, ffiC.G_PrintBestTime())
ffi.copy(dst, ffi.string(ffiC.G_PrintBestTime()))
else
error("unknown system string ID "..what, 2)
end

View file

@ -720,6 +720,10 @@ vec2_t G_ScreenTextSize(const int32_t font,
int32_t xspace, int32_t yline, int32_t xbetween, int32_t ybetween,
const int32_t f,
int32_t x1, int32_t y1, int32_t x2, int32_t y2);
const char* G_PrintYourTime(void);
const char* G_PrintParTime(void);
const char* G_PrintDesignerTime(void);
const char* G_PrintBestTime(void);
void G_UpdateScreenArea(void);
void G_SaveMapState(void);

View file

@ -238,6 +238,10 @@ G_DrawTXDigiNumZ;
G_PrintGameText;
G_ScreenText;
G_ScreenTextSize;
G_PrintYourTime;
G_PrintParTime;
G_PrintDesignerTime;
G_PrintBestTime;
G_UpdateScreenArea;
G_SaveMapState;

View file

@ -10,17 +10,43 @@ gamevar badlev_oob 999 0
gamevar badvol_nd 3 0
gamevar badlev_nd 32 0
definequote 255 <temp>
define Q_tmp 255
definequote Q_tmp <temp>
define Q_tmp2 256
definequote Q_tmp2 <temp>
define Q_last_level 1000
definequote Q_last_level Last level (1-based): %d
define Q_dtime 1001
definequote Q_dtime Designer time for last level: %s
state print_designer_time
// This must not invoke an oob access on the C side if ud.last_level < 0!
qgetsysstr Q_tmp2 STR_DESIGNERTIME
qsprintf Q_tmp Q_dtime Q_tmp2
userquote Q_tmp
ends
onevent EVENT_NEWGAME
getuserdef .last_level lev
qsprintf Q_tmp Q_last_level lev
userquote Q_tmp
state print_designer_time
endevent
onevent EVENT_ENTERLEVEL
state print_designer_time
// must fail, since the current player is -1 in this event
qgetsysstr 255 STR_PLAYERNAME
qgetsysstr Q_tmp 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
qgetsysstr Q_tmp STR_VOLUMENAME // C-CON errors here
setuserdef .volume_number vol
endevent
@ -30,7 +56,7 @@ onevent EVENT_USEJETPACK
setuserdef .volume_number badvol_oob // LunaCON errors here
setuserdef .level_number badlev_oob
qgetsysstr 255 STR_MAPNAME // C-CON errors here
qgetsysstr Q_tmp STR_MAPNAME // C-CON errors here
setuserdef .volume_number vol
setuserdef .level_number lev
@ -42,7 +68,7 @@ onevent EVENT_JUMP
setuserdef .volume_number badvol_nd
setuserdef .level_number badlev_nd
qgetsysstr 255 STR_MAPFILENAME // LunaCON, C-CON error here
qgetsysstr Q_tmp STR_MAPFILENAME // LunaCON, C-CON error here
setuserdef .volume_number vol
setuserdef .level_number lev

View file

@ -36,7 +36,7 @@ onevent EVENT_ENTERLEVEL
redefinequote 117 %s -- %d -- %s -- %d slen=%d
// test:
// - same destination quote as on of the source quotes under %s conversion
// - same destination quote as one of the source quotes under %s conversion
qsprintf 116 /*<-*/ 117 /*args:*/ 116 9999 116 5555 slen
userquote 116 // "012345678|012345678| -- 9999 -- 012345678|012345678| -- 5555 slen=10"