mirror of
https://github.com/brazilofmux/tinymux
synced 2026-08-13 00:23:11 -04:00
Implement NOEVAL object flag and attribute flag (#11).
Add NOEVAL object flag (FLAG_WORD3) and AF_NOEVAL attribute flag so that attribute contents can be stored as literal data without evaluation. When either flag is set, u(), ulocal(), get_eval(), @trigger, did_it() messages/actions, @function, modSpeech, check_filter, make_prefix, process_hook, sortby comparison, eval_boolexp, and format attributes (EXITFORMAT/CONFORMAT/NAMEFORMAT/DESCFORMAT) all return raw text with no function calls, %-substitutions, or escape processing. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
920b0b9417
commit
4cb904fcc2
18 changed files with 823 additions and 519 deletions
|
|
@ -4921,6 +4921,13 @@ ATTRIBUTE FLAGS (continued)
|
|||
& ATTRIBUTE FLAGS3
|
||||
ATTRIBUTE FLAGS (continued)
|
||||
|
||||
no_eval (E) - The attribute contents are not evaluated when
|
||||
retrieved via u(), ulocal(), get_eval(), @trigger,
|
||||
or other evaluation callsites. The raw text is
|
||||
returned with no function calls, no %-substitutions,
|
||||
and no escape processing. Useful for storing
|
||||
player-submitted text safely.
|
||||
|
||||
visual (V) - The attribute is visible to anyone who examines
|
||||
you. Note that the predefined attributes DESC,
|
||||
SEX, and LAST are always VISUAL
|
||||
|
|
@ -7272,7 +7279,8 @@ FLAG LIST
|
|||
t - TRANSPARENT| u - SUSPECT | v - VERBOSE | w - STAFF
|
||||
x - SLAVE | $ - SITEMON | z - OPEN_OK | ? - HEAD
|
||||
- - NOBLEED | | - VACATION | ~ - ASCII | ( - HTML
|
||||
| COLOR256 | TALKMODE | UNICODE
|
||||
| COLOR256 | NOEVAL | TALKMODE
|
||||
| UNICODE | |
|
||||
------------------------------------------------------------------------
|
||||
|
||||
(*) Note that these 'flags' are really types. Also notice that THING
|
||||
|
|
@ -10786,6 +10794,31 @@ NOBLEED
|
|||
|
||||
Related Topics:
|
||||
|
||||
& NOEVAL
|
||||
NOEVAL
|
||||
|
||||
FLAG: NOEVAL ()
|
||||
|
||||
When set on an object, all attributes on that object are treated as
|
||||
literal data: u(), ulocal(), get_eval(), @trigger, did_it() messages,
|
||||
and other evaluation callsites return the raw attribute text without
|
||||
performing function calls, %-substitutions, or escape processing.
|
||||
|
||||
This is useful for objects that store player-submitted text (such as
|
||||
job trackers, bulletin boards, or mail systems) where evaluating the
|
||||
content would be a security risk.
|
||||
|
||||
The same effect can be applied to individual attributes using the
|
||||
no_eval attribute flag (see 'help attribute flags3').
|
||||
|
||||
Example:
|
||||
@set myobj=NOEVAL
|
||||
&DATA myobj=[delete(me)]
|
||||
say u(myobj/DATA)
|
||||
You say "[delete(me)]"
|
||||
|
||||
Related Topics: ATTRIBUTE FLAGS, hasflag().
|
||||
|
||||
& NOSPOOF
|
||||
NOSPOOF
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ constexpr int AF_NOCLONE = 0x00010000; // Don't copy this attr when cloning.
|
|||
constexpr int AF_CONST = 0x00020000; // No one can change it (set by server).
|
||||
constexpr int AF_CASE = 0x00040000; // Regexp matches are case-sensitive.
|
||||
constexpr int AF_TRACE = 0x00080000; // Trace evaluation of this attribute.
|
||||
constexpr int AF_NOEVAL = 0x00100000; // Don't evaluate attribute contents.
|
||||
constexpr int AF_NONAME = 0x00400000; // Supress name in oattr cases.
|
||||
constexpr int AF_NODECOMP = 0x00800000; // Do not include in @decomp.
|
||||
constexpr int AF_ISUSED = 0x10000000; // Used to make efficient sweeps of stale
|
||||
|
|
|
|||
|
|
@ -187,20 +187,27 @@ bool eval_boolexp(dbref player, dbref thing, dbref from, BOOLEXP *b)
|
|||
|
||||
if (bCheck)
|
||||
{
|
||||
reg_ref** preserve = PushRegisters(MAX_GLOBAL_REGS);
|
||||
save_global_regs(preserve);
|
||||
if ((aflags & AF_NOEVAL) || NoEval(source))
|
||||
{
|
||||
bCheck = !string_compare(buff, reinterpret_cast<UTF8*>(b->sub1));
|
||||
}
|
||||
else
|
||||
{
|
||||
reg_ref** preserve = PushRegisters(MAX_GLOBAL_REGS);
|
||||
save_global_regs(preserve);
|
||||
|
||||
buff2 = bp = alloc_lbuf("eval_boolexp");
|
||||
mux_exec(buff, LBUF_SIZE-1, buff2, &bp, source, player, player,
|
||||
AttrTrace(aflags, EV_FIGNORE|EV_EVAL|EV_FCHECK|EV_TOP),
|
||||
nullptr, 0);
|
||||
*bp = '\0';
|
||||
buff2 = bp = alloc_lbuf("eval_boolexp");
|
||||
mux_exec(buff, LBUF_SIZE-1, buff2, &bp, source, player, player,
|
||||
AttrTrace(aflags, EV_FIGNORE|EV_EVAL|EV_FCHECK|EV_TOP),
|
||||
nullptr, 0);
|
||||
*bp = '\0';
|
||||
|
||||
restore_global_regs(preserve);
|
||||
PopRegisters(preserve, MAX_GLOBAL_REGS);
|
||||
restore_global_regs(preserve);
|
||||
PopRegisters(preserve, MAX_GLOBAL_REGS);
|
||||
|
||||
bCheck = !string_compare(buff2, reinterpret_cast<UTF8*>(b->sub1));
|
||||
free_lbuf(buff2);
|
||||
bCheck = !string_compare(buff2, reinterpret_cast<UTF8*>(b->sub1));
|
||||
free_lbuf(buff2);
|
||||
}
|
||||
}
|
||||
free_lbuf(buff);
|
||||
return bCheck;
|
||||
|
|
|
|||
|
|
@ -1193,24 +1193,31 @@ static bool process_hook(dbref executor, CMDENT *cmdp, int key, bool save_flg)
|
|||
hk_attr->number, &aowner, &aflags);
|
||||
if (atext[0] && !(aflags & AF_NOPROG))
|
||||
{
|
||||
reg_ref **preserve = nullptr;
|
||||
if (save_flg)
|
||||
if ((aflags & AF_NOEVAL) || NoEval(mudconf.hook_obj))
|
||||
{
|
||||
preserve = PushRegisters(MAX_GLOBAL_REGS);
|
||||
save_global_regs(preserve);
|
||||
// NOEVAL hook content is data, not code -- treat as true.
|
||||
}
|
||||
UTF8 *buff, *bufc;
|
||||
bufc = buff = alloc_lbuf("process_hook");
|
||||
mux_exec(atext, LBUF_SIZE-1, buff, &bufc, mudconf.hook_obj, executor,
|
||||
executor, AttrTrace(aflags, EV_FCHECK|EV_EVAL), nullptr, 0);
|
||||
*bufc = '\0';
|
||||
if (save_flg)
|
||||
else
|
||||
{
|
||||
restore_global_regs(preserve);
|
||||
PopRegisters(preserve, MAX_GLOBAL_REGS);
|
||||
reg_ref **preserve = nullptr;
|
||||
if (save_flg)
|
||||
{
|
||||
preserve = PushRegisters(MAX_GLOBAL_REGS);
|
||||
save_global_regs(preserve);
|
||||
}
|
||||
UTF8 *buff, *bufc;
|
||||
bufc = buff = alloc_lbuf("process_hook");
|
||||
mux_exec(atext, LBUF_SIZE-1, buff, &bufc, mudconf.hook_obj, executor,
|
||||
executor, AttrTrace(aflags, EV_FCHECK|EV_EVAL), nullptr, 0);
|
||||
*bufc = '\0';
|
||||
if (save_flg)
|
||||
{
|
||||
restore_global_regs(preserve);
|
||||
PopRegisters(preserve, MAX_GLOBAL_REGS);
|
||||
}
|
||||
retval = xlate(buff);
|
||||
free_lbuf(buff);
|
||||
}
|
||||
retval = xlate(buff);
|
||||
free_lbuf(buff);
|
||||
}
|
||||
free_lbuf(atext);
|
||||
}
|
||||
|
|
@ -3066,6 +3073,7 @@ NAMETAB indiv_attraccess_nametab[] =
|
|||
{T("html"), 2, CA_PUBLIC, AF_HTML},
|
||||
{T("no_command"), 4, CA_PUBLIC, AF_NOPROG},
|
||||
{T("no_inherit"), 4, CA_PUBLIC, AF_PRIVATE},
|
||||
{T("no_eval"), 4, CA_PUBLIC, AF_NOEVAL},
|
||||
{T("no_name"), 4, CA_PUBLIC, AF_NONAME},
|
||||
{T("no_parse"), 4, CA_PUBLIC, AF_NOPARSE},
|
||||
{T("regexp"), 1, CA_PUBLIC, AF_REGEXP},
|
||||
|
|
|
|||
|
|
@ -1566,6 +1566,13 @@ void mux_exec( const UTF8 *pStr, size_t nStr, UTF8 *buff, UTF8 **bufc, dbref exe
|
|||
i = executor;
|
||||
}
|
||||
|
||||
if ((aflags & AF_NOEVAL) || NoEval(ufp->obj))
|
||||
{
|
||||
size_t nLen = strlen((const char *)tbuf);
|
||||
safe_copy_buf(tbuf, nLen, buff, &oldp);
|
||||
}
|
||||
else
|
||||
{
|
||||
reg_ref **preserve = nullptr;
|
||||
|
||||
if (ufp->flags & FN_PRES)
|
||||
|
|
@ -1583,6 +1590,7 @@ void mux_exec( const UTF8 *pStr, size_t nStr, UTF8 *buff, UTF8 **bufc, dbref exe
|
|||
PopRegisters(preserve, MAX_GLOBAL_REGS);
|
||||
preserve = nullptr;
|
||||
}
|
||||
}
|
||||
free_lbuf(tbuf);
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -389,7 +389,7 @@ extern CLogFile Log;
|
|||
/* From look.cpp */
|
||||
void look_in(dbref,dbref, int);
|
||||
void show_vrml_url(dbref, dbref);
|
||||
#define NUM_ATTRIBUTE_CODES 12
|
||||
#define NUM_ATTRIBUTE_CODES 13
|
||||
size_t decode_attr_flags(int aflags, UTF8 buff[NUM_ATTRIBUTE_CODES+1]);
|
||||
void decode_attr_flag_names(int aflags, UTF8 *buf, UTF8 **bufc);
|
||||
|
||||
|
|
|
|||
|
|
@ -399,6 +399,7 @@ static FLAGBITENT fbeAlone = { ALONE, ' ', FLAG_WORD3, 0,
|
|||
static FLAGBITENT fbeNoExamine = { NOEXAMINE, 'E', FLAG_WORD3, 0, fh_wizroy};
|
||||
static FLAGBITENT fbeNoModify = { NOMODIFY, ' ', FLAG_WORD3, 0, fh_wizroy};
|
||||
static FLAGBITENT fbeIndestructible = { INDESTRUCTIBLE, ' ', FLAG_WORD3, 0, fh_wizroy};
|
||||
static FLAGBITENT fbeNoEval = { NOEVAL, ' ', FLAG_WORD3, 0, fh_any};
|
||||
static FLAGBITENT fbeSitemon = { SITEMON, '$', FLAG_WORD3, 0, fh_wiz};
|
||||
#ifdef WOD_REALMS
|
||||
static FLAGBITENT fbeFae = { FAE, '0', FLAG_WORD3, CA_STAFF, fh_wizroy};
|
||||
|
|
@ -487,6 +488,7 @@ FLAGNAMEENT gen_flag_names[] =
|
|||
{T("NO_COMMAND"), true, &fbeNoCommand },
|
||||
{T("NO_EXAMINE"), true, &fbeNoExamine },
|
||||
{T("NOBLEED"), true, &fbeNoBleed },
|
||||
{T("NOEVAL"), true, &fbeNoEval },
|
||||
{T("NOEXAMINE"), true, &fbeNoExamine },
|
||||
{T("NOMODIFY"), true, &fbeNoModify },
|
||||
{T("NO_MODIFY"), true, &fbeNoModify },
|
||||
|
|
|
|||
|
|
@ -109,6 +109,7 @@ constexpr unsigned int ALONE = 0x00002000; // Suppress inter-player
|
|||
constexpr unsigned int NOEXAMINE = 0x00004000; // Blocks examine and @decompile.
|
||||
constexpr unsigned int NOMODIFY = 0x00008000; // Blocks all modifications.
|
||||
constexpr unsigned int INDESTRUCTIBLE = 0x00010000; // Cannot be destroyed.
|
||||
constexpr unsigned int NOEVAL = 0x00020000; // Attribute contents not evaluated.
|
||||
constexpr unsigned int MARK_0 = 0x00400000; // User-defined flags.
|
||||
constexpr unsigned int MARK_1 = 0x00800000;
|
||||
constexpr unsigned int MARK_2 = 0x01000000;
|
||||
|
|
@ -345,6 +346,7 @@ UTF8 *MakeCanonicalFlagName
|
|||
#define NoExamine(x) ((Flags3(x) & NOEXAMINE) != 0)
|
||||
#define NoModify(x) ((Flags3(x) & NOMODIFY) != 0)
|
||||
#define Indestructible(x) ((Flags3(x) & INDESTRUCTIBLE) != 0)
|
||||
#define NoEval(x) ((Flags3(x) & NOEVAL) != 0)
|
||||
#define CmdCheck(x) ((Flags3(x) & CMDCHECK) != 0)
|
||||
#if defined(WOD_REALMS) || defined(REALITY_LVLS)
|
||||
#define isObfuscate(x) ((Flags3(x) & OBF) != 0)
|
||||
|
|
|
|||
|
|
@ -314,6 +314,11 @@ static int u_comp(ucomp_context *pctx, const void *s1, const void *s2)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if ((pctx->aflags & AF_NOEVAL) || NoEval(pctx->executor))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
const UTF8 *elems[2] = { T(s1), T(s2) };
|
||||
|
||||
UTF8 *tbuf = alloc_lbuf("u_comp");
|
||||
|
|
|
|||
|
|
@ -2066,8 +2066,18 @@ static void get_handler(UTF8 *buff, UTF8 **bufc, dbref executor, UTF8 *fargs[],
|
|||
if ( key == GET_EVAL
|
||||
|| key == GET_GEVAL)
|
||||
{
|
||||
mux_exec(atr_gotten, nLen, buff, bufc, thing, executor, executor,
|
||||
AttrTrace(aflags, EV_FIGNORE|EV_EVAL), nullptr, 0);
|
||||
if ((aflags & AF_NOEVAL) || NoEval(thing))
|
||||
{
|
||||
if (nLen)
|
||||
{
|
||||
safe_copy_buf(atr_gotten, nLen, buff, bufc);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mux_exec(atr_gotten, nLen, buff, bufc, thing, executor, executor,
|
||||
AttrTrace(aflags, EV_FIGNORE|EV_EVAL), nullptr, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -2186,9 +2196,17 @@ static void do_ufun(UTF8 *buff, UTF8 **bufc, dbref executor, dbref caller,
|
|||
|
||||
// Evaluate it using the rest of the passed function args.
|
||||
//
|
||||
mux_exec(atext, LBUF_SIZE-1, buff, bufc, thing, executor, enactor,
|
||||
AttrTrace(aflags, EV_FCHECK|EV_EVAL),
|
||||
(const UTF8 **)&(fargs[1]), nfargs - 1);
|
||||
if ((aflags & AF_NOEVAL) || NoEval(thing))
|
||||
{
|
||||
size_t nLen = strlen((const char *)atext);
|
||||
safe_copy_buf(atext, nLen, buff, bufc);
|
||||
}
|
||||
else
|
||||
{
|
||||
mux_exec(atext, LBUF_SIZE-1, buff, bufc, thing, executor, enactor,
|
||||
AttrTrace(aflags, EV_FCHECK|EV_EVAL),
|
||||
(const UTF8 **)&(fargs[1]), nfargs - 1);
|
||||
}
|
||||
free_lbuf(atext);
|
||||
|
||||
// If we're evaluating locally, restore the preserved registers.
|
||||
|
|
@ -4965,6 +4983,7 @@ static ATR_HAS_FLAG_ENTRY atr_has_flag_table[] =
|
|||
{ T("html"), AF_HTML },
|
||||
{ T("locked"), AF_LOCK },
|
||||
{ T("no_command"), AF_NOPROG },
|
||||
{ T("no_eval"), AF_NOEVAL },
|
||||
{ T("no_name"), AF_NONAME },
|
||||
{ T("no_parse"), AF_NOPARSE },
|
||||
{ T("regexp"), AF_REGEXP },
|
||||
|
|
|
|||
|
|
@ -454,9 +454,17 @@ static bool check_filter(dbref object, dbref player, int filter, const UTF8 *msg
|
|||
|
||||
UTF8 *nbuf = alloc_lbuf("check_filter");
|
||||
UTF8 *dp = nbuf;
|
||||
mux_exec(buf, LBUF_SIZE-1, nbuf, &dp, object, player, player,
|
||||
AttrTrace(aflags, EV_FIGNORE|EV_EVAL|EV_TOP),
|
||||
nullptr, 0);
|
||||
if ((aflags & AF_NOEVAL) || NoEval(object))
|
||||
{
|
||||
mux_strncpy(nbuf, buf, LBUF_SIZE-1);
|
||||
dp = nbuf + strlen((const char *)nbuf);
|
||||
}
|
||||
else
|
||||
{
|
||||
mux_exec(buf, LBUF_SIZE-1, nbuf, &dp, object, player, player,
|
||||
AttrTrace(aflags, EV_FIGNORE|EV_EVAL|EV_TOP),
|
||||
nullptr, 0);
|
||||
}
|
||||
*dp = '\0';
|
||||
strip_fancy_quotes(nbuf);
|
||||
dp = nbuf;
|
||||
|
|
@ -550,20 +558,27 @@ static UTF8 *make_prefix(dbref object, dbref player, int prefix, const UTF8 *dfl
|
|||
}
|
||||
else
|
||||
{
|
||||
reg_ref **preserve = nullptr;
|
||||
preserve = PushRegisters(MAX_GLOBAL_REGS);
|
||||
save_global_regs(preserve);
|
||||
if ((aflags & AF_NOEVAL) || NoEval(object))
|
||||
{
|
||||
cp = buf + strlen((const char *)buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
reg_ref **preserve = nullptr;
|
||||
preserve = PushRegisters(MAX_GLOBAL_REGS);
|
||||
save_global_regs(preserve);
|
||||
|
||||
nbuf = cp = alloc_lbuf("add_prefix");
|
||||
mux_exec(buf, LBUF_SIZE-1, nbuf, &cp, object, player, player,
|
||||
AttrTrace(aflags, EV_FIGNORE|EV_EVAL|EV_TOP),
|
||||
nullptr, 0);
|
||||
free_lbuf(buf);
|
||||
nbuf = cp = alloc_lbuf("add_prefix");
|
||||
mux_exec(buf, LBUF_SIZE-1, nbuf, &cp, object, player, player,
|
||||
AttrTrace(aflags, EV_FIGNORE|EV_EVAL|EV_TOP),
|
||||
nullptr, 0);
|
||||
free_lbuf(buf);
|
||||
|
||||
restore_global_regs(preserve);
|
||||
PopRegisters(preserve, MAX_GLOBAL_REGS);
|
||||
restore_global_regs(preserve);
|
||||
PopRegisters(preserve, MAX_GLOBAL_REGS);
|
||||
|
||||
buf = nbuf;
|
||||
buf = nbuf;
|
||||
}
|
||||
}
|
||||
if (cp != buf)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -470,9 +470,17 @@ static void look_exits(dbref player, dbref loc, const UTF8 *exit_name)
|
|||
preserve = PushRegisters(MAX_GLOBAL_REGS);
|
||||
save_and_clear_global_regs(preserve);
|
||||
|
||||
mux_exec(ExitFormat, LBUF_SIZE-1, FormatOutput, &tPtr, loc, player, player,
|
||||
AttrTrace(aflags, EV_FCHECK|EV_EVAL|EV_TOP),
|
||||
(const UTF8 **)&VisibleObjectList, 1);
|
||||
if ((aflags & AF_NOEVAL) || NoEval(loc))
|
||||
{
|
||||
mux_strncpy(FormatOutput, ExitFormat, LBUF_SIZE-1);
|
||||
tPtr = FormatOutput + strlen((const char *)FormatOutput);
|
||||
}
|
||||
else
|
||||
{
|
||||
mux_exec(ExitFormat, LBUF_SIZE-1, FormatOutput, &tPtr, loc, player, player,
|
||||
AttrTrace(aflags, EV_FCHECK|EV_EVAL|EV_TOP),
|
||||
(const UTF8 **)&VisibleObjectList, 1);
|
||||
}
|
||||
*tPtr = '\0';
|
||||
|
||||
restore_global_regs(preserve);
|
||||
|
|
@ -647,9 +655,17 @@ static void look_contents(dbref player, dbref loc, const UTF8 *contents_name, in
|
|||
preserve = PushRegisters(MAX_GLOBAL_REGS);
|
||||
save_and_clear_global_regs(preserve);
|
||||
|
||||
mux_exec(ContentsFormat, LBUF_SIZE-1, FormatOutput, &tPtr, loc, player, player,
|
||||
AttrTrace(aflags, EV_FCHECK|EV_EVAL|EV_TOP),
|
||||
ParameterList, 2);
|
||||
if ((aflags & AF_NOEVAL) || NoEval(loc))
|
||||
{
|
||||
mux_strncpy(FormatOutput, ContentsFormat, LBUF_SIZE-1);
|
||||
tPtr = FormatOutput + strlen((const char *)FormatOutput);
|
||||
}
|
||||
else
|
||||
{
|
||||
mux_exec(ContentsFormat, LBUF_SIZE-1, FormatOutput, &tPtr, loc, player, player,
|
||||
AttrTrace(aflags, EV_FCHECK|EV_EVAL|EV_TOP),
|
||||
ParameterList, 2);
|
||||
}
|
||||
*tPtr = '\0';
|
||||
|
||||
restore_global_regs(preserve);
|
||||
|
|
@ -755,6 +771,7 @@ static ATTR_DECODE_ENTRY attr_decode_table[NUM_ATTRIBUTE_CODES+1] =
|
|||
{ AF_CASE, 'C', T("CASE") },
|
||||
{ AF_HTML, 'H', T("HTML") },
|
||||
{ AF_PRIVATE, 'I', T("NO_INHERIT") },
|
||||
{ AF_NOEVAL, 'E', T("NO_EVAL") },
|
||||
{ AF_NONAME, 'N', T("NO_NAME") },
|
||||
{ AF_NOPARSE, 'P', T("NO_PARSE") },
|
||||
{ AF_REGEXP, 'R', T("REGEXP") },
|
||||
|
|
@ -1054,9 +1071,16 @@ static bool show_a_desc(dbref player, dbref loc)
|
|||
//
|
||||
mux_strncpy(temp, tbuf1, LBUF_SIZE-1);
|
||||
#else
|
||||
mux_exec(tbuf1, LBUF_SIZE-1, temp, &bp, loc, player, player,
|
||||
AttrTrace(aflags2, EV_FCHECK|EV_EVAL|EV_TOP),
|
||||
nullptr, 0);
|
||||
if ((aflags2 & AF_NOEVAL) || NoEval(loc))
|
||||
{
|
||||
mux_strncpy(temp, tbuf1, LBUF_SIZE-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
mux_exec(tbuf1, LBUF_SIZE-1, temp, &bp, loc, player, player,
|
||||
AttrTrace(aflags2, EV_FCHECK|EV_EVAL|EV_TOP),
|
||||
nullptr, 0);
|
||||
}
|
||||
*bp = '\0';
|
||||
#endif
|
||||
|
||||
|
|
@ -1068,9 +1092,17 @@ static bool show_a_desc(dbref player, dbref loc)
|
|||
const UTF8 *ParameterList[] =
|
||||
{ temp, attrname };
|
||||
|
||||
mux_exec(DescFormat, LBUF_SIZE-1, FormatOutput, &tPtr, loc, player, player,
|
||||
AttrTrace(aflags1, EV_FCHECK|EV_EVAL|EV_TOP),
|
||||
ParameterList, 2);
|
||||
if ((aflags1 & AF_NOEVAL) || NoEval(loc))
|
||||
{
|
||||
mux_strncpy(FormatOutput, DescFormat, LBUF_SIZE-1);
|
||||
tPtr = FormatOutput + strlen((const char *)FormatOutput);
|
||||
}
|
||||
else
|
||||
{
|
||||
mux_exec(DescFormat, LBUF_SIZE-1, FormatOutput, &tPtr, loc, player, player,
|
||||
AttrTrace(aflags1, EV_FCHECK|EV_EVAL|EV_TOP),
|
||||
ParameterList, 2);
|
||||
}
|
||||
*tPtr = '\0';
|
||||
|
||||
notify(player, FormatOutput);
|
||||
|
|
@ -1205,10 +1237,18 @@ static void look_simple(dbref player, dbref thing, bool obey_terse)
|
|||
preserve = PushRegisters(MAX_GLOBAL_REGS);
|
||||
save_and_clear_global_regs(preserve);
|
||||
|
||||
mux_exec(NameFormat, LBUF_SIZE-1, FormatOutput, &tPtr, thing,
|
||||
player, player,
|
||||
AttrTrace(aflags, EV_FCHECK|EV_EVAL|EV_TOP),
|
||||
0, 0);
|
||||
if ((aflags & AF_NOEVAL) || NoEval(thing))
|
||||
{
|
||||
mux_strncpy(FormatOutput, NameFormat, LBUF_SIZE-1);
|
||||
tPtr = FormatOutput + strlen((const char *)FormatOutput);
|
||||
}
|
||||
else
|
||||
{
|
||||
mux_exec(NameFormat, LBUF_SIZE-1, FormatOutput, &tPtr, thing,
|
||||
player, player,
|
||||
AttrTrace(aflags, EV_FCHECK|EV_EVAL|EV_TOP),
|
||||
0, 0);
|
||||
}
|
||||
*tPtr = '\0';
|
||||
|
||||
restore_global_regs(preserve);
|
||||
|
|
@ -1327,9 +1367,17 @@ void look_in(dbref player, dbref loc, int key)
|
|||
preserve = PushRegisters(MAX_GLOBAL_REGS);
|
||||
save_and_clear_global_regs(preserve);
|
||||
|
||||
mux_exec(NameFormat, LBUF_SIZE-1, FormatOutput, &tPtr, loc, player, player,
|
||||
AttrTrace(aflags, EV_FCHECK|EV_EVAL|EV_TOP),
|
||||
0, 0);
|
||||
if ((aflags & AF_NOEVAL) || NoEval(loc))
|
||||
{
|
||||
mux_strncpy(FormatOutput, NameFormat, LBUF_SIZE-1);
|
||||
tPtr = FormatOutput + strlen((const char *)FormatOutput);
|
||||
}
|
||||
else
|
||||
{
|
||||
mux_exec(NameFormat, LBUF_SIZE-1, FormatOutput, &tPtr, loc, player, player,
|
||||
AttrTrace(aflags, EV_FCHECK|EV_EVAL|EV_TOP),
|
||||
0, 0);
|
||||
}
|
||||
*tPtr = '\0';
|
||||
|
||||
restore_global_regs(preserve);
|
||||
|
|
|
|||
|
|
@ -2568,27 +2568,36 @@ void did_it(dbref player, dbref thing, int what, const UTF8 *def, int owhat,
|
|||
d = atr_pget(thing, what, &aowner, &aflags);
|
||||
if (*d)
|
||||
{
|
||||
need_pres = true;
|
||||
preserve = PushRegisters(MAX_GLOBAL_REGS);
|
||||
save_global_regs(preserve);
|
||||
|
||||
buff = bp = alloc_lbuf("did_it.1");
|
||||
mux_exec(d, LBUF_SIZE-1, buff, &bp, thing, player, player,
|
||||
AttrTrace(aflags, EV_EVAL|EV_FIGNORE|EV_FCHECK|EV_TOP),
|
||||
args, nargs);
|
||||
*bp = '\0';
|
||||
if ( (aflags & AF_HTML)
|
||||
&& Html(player))
|
||||
if ((aflags & AF_NOEVAL) || NoEval(thing))
|
||||
{
|
||||
safe_str(T("\r\n"), buff, &bp);
|
||||
*bp = '\0';
|
||||
notify_html(player, buff);
|
||||
// Output raw text with no substitutions.
|
||||
//
|
||||
notify(player, d);
|
||||
}
|
||||
else
|
||||
{
|
||||
notify(player, buff);
|
||||
need_pres = true;
|
||||
preserve = PushRegisters(MAX_GLOBAL_REGS);
|
||||
save_global_regs(preserve);
|
||||
|
||||
buff = bp = alloc_lbuf("did_it.1");
|
||||
mux_exec(d, LBUF_SIZE-1, buff, &bp, thing, player, player,
|
||||
AttrTrace(aflags, EV_EVAL|EV_FIGNORE|EV_FCHECK|EV_TOP),
|
||||
args, nargs);
|
||||
*bp = '\0';
|
||||
if ( (aflags & AF_HTML)
|
||||
&& Html(player))
|
||||
{
|
||||
safe_str(T("\r\n"), buff, &bp);
|
||||
*bp = '\0';
|
||||
notify_html(player, buff);
|
||||
}
|
||||
else
|
||||
{
|
||||
notify(player, buff);
|
||||
}
|
||||
free_lbuf(buff);
|
||||
}
|
||||
free_lbuf(buff);
|
||||
}
|
||||
else if (def)
|
||||
{
|
||||
|
|
@ -2610,6 +2619,34 @@ void did_it(dbref player, dbref thing, int what, const UTF8 *def, int owhat,
|
|||
d = atr_pget(thing, owhat, &aowner, &aflags);
|
||||
if (*d)
|
||||
{
|
||||
if ((aflags & AF_NOEVAL) || NoEval(thing))
|
||||
{
|
||||
// Output raw text with no substitutions.
|
||||
//
|
||||
#ifdef REALITY_LVLS
|
||||
if (aflags & AF_NONAME)
|
||||
{
|
||||
notify_except2_rlevel(loc, player, player, thing, d);
|
||||
}
|
||||
else
|
||||
{
|
||||
notify_except2_rlevel(loc, player, player, thing,
|
||||
tprintf(T("%s %s"), Moniker(player), d));
|
||||
}
|
||||
#else
|
||||
if (aflags & AF_NONAME)
|
||||
{
|
||||
notify_except2(loc, player, player, thing, d);
|
||||
}
|
||||
else
|
||||
{
|
||||
notify_except2(loc, player, player, thing,
|
||||
tprintf(T("%s %s"), Moniker(player), d));
|
||||
}
|
||||
#endif // REALITY_LVLS
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!need_pres)
|
||||
{
|
||||
need_pres = true;
|
||||
|
|
@ -2646,6 +2683,7 @@ void did_it(dbref player, dbref thing, int what, const UTF8 *def, int owhat,
|
|||
#endif // REALITY_LVLS
|
||||
}
|
||||
free_lbuf(buff);
|
||||
} // else (not NOEVAL)
|
||||
}
|
||||
else if (odef)
|
||||
{
|
||||
|
|
@ -2744,12 +2782,15 @@ void did_it(dbref player, dbref thing, int what, const UTF8 *def, int owhat,
|
|||
}
|
||||
}
|
||||
free_lbuf(charges);
|
||||
CLinearTimeAbsolute lta;
|
||||
wait_que(thing, player, player, AttrTrace(aflags, 0), false, lta,
|
||||
NOTHING, 0,
|
||||
act,
|
||||
nargs, args,
|
||||
mudstate.global_regs);
|
||||
if (!((aflags & AF_NOEVAL) || NoEval(thing)))
|
||||
{
|
||||
CLinearTimeAbsolute lta;
|
||||
wait_que(thing, player, player, AttrTrace(aflags, 0), false, lta,
|
||||
NOTHING, 0,
|
||||
act,
|
||||
nargs, args,
|
||||
mudstate.global_regs);
|
||||
}
|
||||
}
|
||||
free_lbuf(act);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2179,9 +2179,16 @@ void do_trigger(dbref executor, dbref caller, dbref enactor, int eval, int key,
|
|||
free_lbuf(charges);
|
||||
if (bRun)
|
||||
{
|
||||
process_command(thing, executor, executor,
|
||||
AttrTrace(aflags, 0), false, act,
|
||||
(const UTF8 **)argv, nargs);
|
||||
if ((aflags & AF_NOEVAL) || NoEval(thing))
|
||||
{
|
||||
// NOEVAL content is data, not code -- skip execution.
|
||||
}
|
||||
else
|
||||
{
|
||||
process_command(thing, executor, executor,
|
||||
AttrTrace(aflags, 0), false, act,
|
||||
(const UTF8 **)argv, nargs);
|
||||
}
|
||||
}
|
||||
}
|
||||
free_lbuf(act);
|
||||
|
|
|
|||
|
|
@ -24,11 +24,19 @@ UTF8 *modSpeech(dbref player, const UTF8 *message, bool bWhich, const UTF8 *comm
|
|||
|
||||
UTF8 *new_message = alloc_lbuf("modspeech");
|
||||
UTF8 *t_ptr = new_message;
|
||||
const UTF8 *args[2];
|
||||
args[0] = message;
|
||||
args[1] = command;
|
||||
mux_exec(mod, LBUF_SIZE-1, new_message, &t_ptr, player, player, player,
|
||||
AttrTrace(aflags, EV_FCHECK|EV_EVAL|EV_TOP), args, 2);
|
||||
if ((aflags & AF_NOEVAL) || NoEval(player))
|
||||
{
|
||||
mux_strncpy(new_message, mod, LBUF_SIZE-1);
|
||||
t_ptr = new_message + strlen((const char *)new_message);
|
||||
}
|
||||
else
|
||||
{
|
||||
const UTF8 *args[2];
|
||||
args[0] = message;
|
||||
args[1] = command;
|
||||
mux_exec(mod, LBUF_SIZE-1, new_message, &t_ptr, player, player, player,
|
||||
AttrTrace(aflags, EV_FCHECK|EV_EVAL|EV_TOP), args, 2);
|
||||
}
|
||||
*t_ptr = '\0';
|
||||
free_lbuf(mod);
|
||||
return new_message;
|
||||
|
|
|
|||
73
testcases/noeval_fn.mux
Normal file
73
testcases/noeval_fn.mux
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
#
|
||||
# noeval_fn.mux - Test Cases for NOEVAL flag and AF_NOEVAL attribute flag.
|
||||
#
|
||||
@create test_noeval_fn
|
||||
-
|
||||
@set test_noeval_fn=INHERIT QUIET
|
||||
-
|
||||
#
|
||||
# Beginning of Test Cases
|
||||
#
|
||||
&tr.tc000 test_noeval_fn=
|
||||
@log smoke=Beginning noeval test cases.
|
||||
-
|
||||
#
|
||||
# Test Case #1 - NOEVAL attribute flag and object flag behavior.
|
||||
#
|
||||
# Tests:
|
||||
# - AF_NOEVAL attr + u() returns literal text
|
||||
# - NOEVAL object flag + u() returns literal text
|
||||
# - get_eval() respects AF_NOEVAL
|
||||
# - get() still returns raw (it always does)
|
||||
# - hasflag() detects both flags
|
||||
# - Without NOEVAL, u() evaluates normally
|
||||
#
|
||||
&tr.tc001 test_noeval_fn=
|
||||
@pemit me=TC001: Creating test objects.;
|
||||
@create test_noeval_tgt;
|
||||
@set test_noeval_tgt=INHERIT QUIET;
|
||||
&TESTATTR test_noeval_tgt=[add(1,2)];
|
||||
@set test_noeval_tgt/TESTATTR=no_eval;
|
||||
@create test_noeval_tgt2;
|
||||
@set test_noeval_tgt2=INHERIT QUIET NOEVAL;
|
||||
&TESTATTR test_noeval_tgt2=[add(1,2)];
|
||||
@create test_noeval_tgt3;
|
||||
@set test_noeval_tgt3=INHERIT QUIET;
|
||||
&TESTATTR test_noeval_tgt3=[add(1,2)];
|
||||
@wait 0=
|
||||
{
|
||||
@if strmatch(
|
||||
setr(0,sha1(
|
||||
[u(test_noeval_tgt/TESTATTR)]
|
||||
[u(test_noeval_tgt2/TESTATTR)]
|
||||
[get_eval(test_noeval_tgt/TESTATTR)]
|
||||
[get(test_noeval_tgt/TESTATTR)]
|
||||
[hasflag(test_noeval_tgt/TESTATTR,no_eval)]
|
||||
[hasflag(test_noeval_tgt2,NOEVAL)]
|
||||
[u(test_noeval_tgt3/TESTATTR)]
|
||||
)
|
||||
),
|
||||
EDBF1A113545E1AB8AE20F6574BE7157DA8EA52D
|
||||
)=
|
||||
{
|
||||
@log smoke=TC001: noeval flag and attr flag. Succeeded.
|
||||
},
|
||||
{
|
||||
@log smoke=TC001: noeval flag and attr flag. Failed (%q0).
|
||||
};
|
||||
@destroy/override test_noeval_tgt;
|
||||
@destroy/override test_noeval_tgt2;
|
||||
@destroy/override test_noeval_tgt3;
|
||||
@trig me/tr.done
|
||||
}
|
||||
-
|
||||
&tr.done test_noeval_fn=
|
||||
@log smoke=End noeval test cases.;
|
||||
@notify smoke
|
||||
-
|
||||
drop test_noeval_fn
|
||||
-
|
||||
#
|
||||
# End of Test Cases
|
||||
#
|
||||
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -22,7 +22,7 @@
|
|||
ladd_fn land_fn last_fn lcstr_fn ldelete_fn ljust_fn lmax_fn lmin_fn
|
||||
ln_fn lnum_fn lock_fn log_fn lor_fn lpad_fn lpos_fn lt_fn lte_fn
|
||||
match_fn matchall_fn max_fn member_fn merge_fn mid_fn min_fn mod_fn mul_fn
|
||||
neq_fn not_fn objid_fn oemit_fn or_fn orbool_fn ord_fn
|
||||
neq_fn noeval_fn not_fn objid_fn oemit_fn or_fn orbool_fn ord_fn
|
||||
parenmatch_fn pi_fn pickrand_fn pos_fn power_fn
|
||||
remainder_fn remove_fn repeat_fn replace_fn rest_fn reverse_fn revwords_fn
|
||||
right_fn rjust_fn roman_fn round_fn rpad_fn
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue