From c294787aedeed47ab1bcbc5c64b95e312af3eb32 Mon Sep 17 00:00:00 2001 From: Mark Pizzolato Date: Thu, 24 May 2018 12:59:23 -0700 Subject: [PATCH] SCP: Fix expression evaluation divide by zero, and avoid parameter substitution This allows bare the % character to to properly be the moduls operator and avoids potential ambiguous variable insertions. --- scp.c | 23 +++++++++++++++-------- sim_defs.h | 2 ++ 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/scp.c b/scp.c index 3b71dd5f..a3b50a7a 100644 --- a/scp.c +++ b/scp.c @@ -555,10 +555,10 @@ int32 sim_brk_lnt = 0; int32 sim_brk_ins = 0; int32 sim_quiet = 0; int32 sim_step = 0; -char *sim_sub_instr = NULL; -char *sim_sub_instr_buf = NULL; -size_t sim_sub_instr_size = 0; -size_t *sim_sub_instr_off = NULL; +char *sim_sub_instr = NULL; /* Copy of pre-substitution buffer contents */ +char *sim_sub_instr_buf = NULL; /* Buffer address that substitutions were saved in */ +size_t sim_sub_instr_size = 0; /* substitution buffer size */ +size_t *sim_sub_instr_off = NULL; /* offsets in substitution buffer where original data started */ static double sim_time; static uint32 sim_rtime; static int32 noqueue_time; @@ -4696,10 +4696,10 @@ else { cptr = get_glyph (cptr, varname, '='); /* get environment variable name */ strlcpy (cbuf, cptr, sizeof(cbuf)); sim_trim_endspc (cbuf); - cptr = cbuf; if (sim_switches & SWMASK ('S')) { /* Quote String argument? */ uint32 str_size; + cptr = cbuf; get_glyph_quoted (cptr, cbuf, 0); if (SCPE_OK != sim_decode_quoted_string (cbuf, (uint8 *)cbuf, &str_size)) return sim_messagef (SCPE_ARG, "Invalid quoted string: %s\n", cbuf); @@ -4709,8 +4709,11 @@ else { if (sim_switches & SWMASK ('A')) { /* Arithmentic Expression Evaluation argument? */ t_svalue val; t_stat stat; + const char *eptr = cptr; - cptr = sim_eval_expression (cptr, &val, FALSE, &stat); + if ((cptr > sim_sub_instr_buf) && ((size_t)(cptr - sim_sub_instr_buf) < sim_sub_instr_size)) + eptr = &sim_sub_instr[sim_sub_instr_off[cptr - sim_sub_instr_buf]]; /* get un-substituted string */ + cptr = sim_eval_expression (eptr, &val, FALSE, &stat); if (stat == SCPE_OK) { sprintf (cbuf, "%ld", (long)val); cptr = cbuf; @@ -13469,12 +13472,16 @@ return factorx * factory; static t_svalue _op_div (t_svalue divisor, t_svalue dividend) { -return dividend / divisor; +if (divisor != 0) + return dividend / divisor; +return T_SVALUE_MAX; } static t_svalue _op_mod (t_svalue divisor, t_svalue dividend) { -return dividend % divisor; +if (divisor != 0) + return dividend % divisor; +return 0; } static t_svalue _op_comp (t_svalue data, t_svalue unused) diff --git a/sim_defs.h b/sim_defs.h index b7694fe7..88cac8de 100644 --- a/sim_defs.h +++ b/sim_defs.h @@ -239,10 +239,12 @@ typedef unsigned long t_uint64; typedef t_int64 t_svalue; /* signed value */ typedef t_uint64 t_value; /* value */ #define T_VALUE_MAX 0xffffffffffffffffuLL +#define T_SVALUE_MAX 0x7fffffffffffffffLL #else /* 32b data */ typedef int32 t_svalue; typedef uint32 t_value; #define T_VALUE_MAX 0xffffffffUL +#define T_SVALUE_MAX 0x7fffffffL #endif /* end 64b data */ #if defined (USE_INT64) && defined (USE_ADDR64) /* 64b address */