From 3493302e6cd692710557c8aba0772338b76e3577 Mon Sep 17 00:00:00 2001 From: helixhorned Date: Sun, 31 Aug 2014 11:15:22 +0000 Subject: [PATCH] LunaCON: implement 'qsubstr' command. Add source/lunatic/test/qsubstr.con. In C-CON's qsubstr, error if is not in [0 .. MAXQUOTELEN-1] or is negative. git-svn-id: https://svn.eduke32.com/eduke32@4583 1a8010ca-5511-0410-912e-c29ae57300e0 --- polymer/eduke32/source/gameexec.c | 12 ++++ polymer/eduke32/source/lunatic/control.lua | 27 +++++++ polymer/eduke32/source/lunatic/lunacon.lua | 2 +- .../eduke32/source/lunatic/test/qsubstr.con | 71 +++++++++++++++++++ 4 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 polymer/eduke32/source/lunatic/test/qsubstr.con diff --git a/polymer/eduke32/source/gameexec.c b/polymer/eduke32/source/gameexec.c index 860b202d0..449348bb7 100644 --- a/polymer/eduke32/source/gameexec.c +++ b/polymer/eduke32/source/gameexec.c @@ -2083,6 +2083,18 @@ skip_check: continue; } + if ((unsigned)st >= MAXQUOTELEN) + { + CON_ERRPRINTF("invalid start position %d\n", st); + continue; + } + + if (ln < 0) + { + CON_ERRPRINTF("invalid length %d\n", ln); + continue; + } + { char *s1 = ScriptQuotes[q1]; char *s2 = ScriptQuotes[q2]; diff --git a/polymer/eduke32/source/lunatic/control.lua b/polymer/eduke32/source/lunatic/control.lua index 1523d4853..6e362329b 100644 --- a/polymer/eduke32/source/lunatic/control.lua +++ b/polymer/eduke32/source/lunatic/control.lua @@ -713,6 +713,33 @@ function _qstrlen(qnum) return strlen(bcheck.quote_idx(qnum)) end +function _qsubstr(qdst, qsrc, start, length) + local cstr_dst = bcheck.quote_idx(qdst) + local cstr_src = bcheck.quote_idx(qsrc) + + if (not (start >= 0 and start < MAXQUOTELEN)) then + error("invalid start position "..start, 2) + end + + if (not (length >= 0)) then -- NOTE: no check for start+length! + error("invalid length "..length, 2) + end + + local si = 0 + while (cstr_src[si] ~= 0 and si < start) do + si = si+1 + end + + for i=0,math.huge do + cstr_dst[i] = cstr_src[si + i] + + if (si + i == MAXQUOTELEN-1 or i==length or cstr_dst[i] == 0) then + cstr_dst[i] = 0 + break + end + end +end + function _qstrcpy(qdst, qsrc) local cstr_dst = bcheck.quote_idx(qdst) local cstr_src = bcheck.quote_idx(qsrc) diff --git a/polymer/eduke32/source/lunatic/lunacon.lua b/polymer/eduke32/source/lunatic/lunacon.lua index 5baa45393..028987681 100644 --- a/polymer/eduke32/source/lunatic/lunacon.lua +++ b/polymer/eduke32/source/lunatic/lunacon.lua @@ -2667,7 +2667,7 @@ local Cinner = { qstrncat = cmd(R,R) / handle.NYI, qsubstr = cmd(R,R,R,R) - / handle.NYI, + / "_con._qsubstr(%1,%2,%3,%4)", quote = cmd(D) / "_con._quote(_pli,%1)", userquote = cmd(R) diff --git a/polymer/eduke32/source/lunatic/test/qsubstr.con b/polymer/eduke32/source/lunatic/test/qsubstr.con new file mode 100644 index 000000000..c2fe37919 --- /dev/null +++ b/polymer/eduke32/source/lunatic/test/qsubstr.con @@ -0,0 +1,71 @@ +// Tests for the qsubstr command. +// This one should be safe to run in C-CON. + +// overlong string at definition (should warn) +define QSRC 400 +definequote QSRC -123456789-123456789-123456789-123456789-123456789-123456789-123456789-123456789-123456789-123456789-123456789-123456789=123456789 +define QSRC_SHORT 401 +definequote QSRC_SHORT -123456789 + +define QDST 500 +definequote QDST + +// for gettimedate +gamevar sec 0 0 +gamevar x 0 0 + +onevent EVENT_ENTERLEVEL + // first, a plain, non-border-case call + qsubstr QDST QSRC 10 10 // -> "-123456789" + userquote QDST + + // length zero yields the empty string + qsubstr QDST QSRC 20 0 // -> "" + userquote QDST + + // start+length > strlen of source: no error + qsubstr QDST QSRC_SHORT 8 6 // -> "89" + userquote QDST + + // start == strlen of source + qsubstr QDST QSRC_SHORT 10 1 // -> "" + userquote QDST + + // Make QDST contain + // -123456789123456789-... + qstrcpy QDST QSRC_SHORT + qstrcpy QSRC_SHORT QSRC + qstrcpy QSRC_SHORT QDST + userquote QSRC_SHORT // -> "-123456789" + + // start == strlen of source, trailing bytes after source + qsubstr QDST QSRC_SHORT 10 2 // -> "" + userquote QDST + + // start is beyond- of the source + qsubstr QDST QSRC_SHORT 11 9 // -> "" + userquote QDST + + // copy whole string (127 chars + 1 == MAXQUOTELEN) + qsubstr QDST QSRC 0 1000 // -> "-123456789-123456789-...=123456" + userquote QDST + + /** TESTS FOR source == dest **/ + + qsubstr QDST QDST 0 20 // -> "-123456789-123456789" + userquote QDST + + qsubstr QDST QDST 5 10 // -> "56789-1234" + userquote QDST + + /** TESTS FOR invalid input **/ + + gettimedate sec x x x x x x x + ifvarand sec 1 + qsubstr QDST QSRC -1 10 // invalid start + else + qsubstr QDST QSRC 0 -1 // invalid length + + // Reached only in C-CON: + qsubstr QDST QSRC 128 0 // invalid start +endevent