diff --git a/src/cali.c b/src/cali.c index 6312ecb..5f5fd5d 100644 --- a/src/cali.c +++ b/src/cali.c @@ -51,25 +51,35 @@ int *getVariable(); static int buf[CALI_DEPTH_MAX]; /* 計算式バッファ */ static int *cali = buf; /* インデックス */ -/* 変数番号を返す */ static int *getVar(int c0) { - if ((c0 & 0x40) == 0) - return v_ref(c0 & 0x3f); // 0 - 0x3f - - int c1 = sl_getc(); - if (c0 != 0xc0) - return v_ref(((c0 & 0x3f) * 256) + c1); // 0x100 - 0x3fff - - if (c1 == 1) { - c0 = sl_getc(); - c1 = sl_getc(); - int index = getCaliValue(); - return v_ref_indexed(c0 << 8 | c1, index); - } else if (c1 >= 0x40) { - return v_ref(c1); // 0x40 - 0xff + int addr = sl_getIndex(); + int var; + if ((c0 & 0x40) == 0) { + var = c0 & 0x3f; // 0 - 0x3f + } else { + int c1 = sl_getc(); + if (c0 != 0xc0) + var = (c0 & 0x3f) * 256 + c1; // 0x100 - 0x3fff + else if (c1 == 1) { + c0 = sl_getc(); + c1 = sl_getc(); + var = c0 << 8 | c1; + int index = getCaliValue(); + int *store = v_ref_indexed(var, index); + if (!store) + WARNING("%03d:%05x: Out of bounds index access: %s[%d]\n", sl_getPage(), addr, v_name(var), index); + return store; + } else if (c1 >= 0x40) { + var = c1; // 0x40 - 0xff + } else { + SYSERROR("Invalid variable reference at %d:0x%x", sl_getPage(), addr); + return NULL; + } } - SYSERROR("Invalid variable reference at %d:0x%x", sl_getPage(), sl_getIndex() - 2); - return NULL; + int *store = v_ref(var); + if (!store) + WARNING("%03d:%05x: Out of bounds array access: %s\n", sl_getPage(), addr, v_name(var)); + return store; } /* 変数番号が返る */ diff --git a/src/debugger.c b/src/debugger.c index be95e3b..4b68b5e 100644 --- a/src/debugger.c +++ b/src/debugger.c @@ -142,13 +142,17 @@ static int eval_variable(void) { int var = dbg_lookup_var(buf); if (var < 0) eval_error("unknown variable \"%s\"", buf); + int *store; if (consume('[')) { int index = eval_expr(); expect(']'); - return *v_ref_indexed(var, index);; + store = v_ref_indexed(var, index); } else { - return *v_ref(var); + store = v_ref(var); } + if (!store) + eval_error("out of bounds array access"); + return *store; } static int eval_prim(void) { diff --git a/src/debugger_dap.c b/src/debugger_dap.c index 293448a..7d7b313 100644 --- a/src/debugger_dap.c +++ b/src/debugger_dap.c @@ -374,7 +374,11 @@ static void cmd_variables(cJSON *args, cJSON *resp) { cJSON_AddItemToArray(variables, var); cJSON_AddStringToObject(var, "name", dsym_variable_name(symbols, i)); char value[20]; - sprintf(value, "%d", *v_ref(i)); + int *store = v_ref(i); + if (store) + sprintf(value, "%d", *store); + else + strcpy(value, "(Out of bounds)"); cJSON_AddStringToObject(var, "value", value); cJSON_AddNumberToObject(var, "variablesReference", 0); } @@ -426,13 +430,19 @@ static void cmd_setVariable(cJSON *args, cJSON *resp) { cJSON_AddStringToObject(resp, "message", "syntax error"); return; } - *v_ref(var) = parsed_value & 0xffff; + int *store = v_ref(var); + if (!store) { + cJSON_AddBoolToObject(resp, "success", false); + cJSON_AddStringToObject(resp, "message", "out of bounds array access"); + return; + } + *store = parsed_value & 0xffff; cJSON *body; cJSON_AddBoolToObject(resp, "success", true); cJSON_AddItemToObjectCS(resp, "body", body = cJSON_CreateObject()); char new_value[20]; - sprintf(new_value, "%d", *v_ref(var)); + sprintf(new_value, "%d", *store); cJSON_AddStringToObject(body, "value", new_value); } else if (cJSON_IsNumber(vref) && vref->valueint == VREF_STRINGS) { int idx; diff --git a/src/variable.c b/src/variable.c index fa0b351..2291b2f 100644 --- a/src/variable.c +++ b/src/variable.c @@ -28,7 +28,6 @@ #include "utfsjis.h" #include "variable.h" #include "xsystem35.h" -#include "scenario.h" typedef struct { int *pointvar; @@ -54,7 +53,7 @@ int preVarPage; /* 直前にアクセスした変数のページ */ int preVarIndex; /* 直前にアクセスした変数のINDEX */ int preVarNo; /* 直前にアクセスした変数の番号 */ -static const char *varname(int var) { +const char *v_name(int var) { if (var < nact->ain.varnum) return nact->ain.var[var]; static char buf[10]; @@ -85,10 +84,8 @@ int *v_ref(int var) { int *index = attr->pointvar; int page = attr->page; int offset = attr->offset; - if (*index + offset >= arrayVarBuffer[page - 1].size) { - WARNING("%03d:%05x: Out of bounds array access: %s\n", sl_getPage(), sl_getIndex(), varname(var)); + if (*index + offset >= arrayVarBuffer[page - 1].size) return NULL; - } preVarIndex = offset + *index; return arrayVarBuffer[page - 1].value + offset + *index; } @@ -100,10 +97,8 @@ int *v_ref_indexed(int var, int index) { if (attr->page == 0) { // If VAR_n is not an array variable, VAR_n[i] points to VAR_(n+i). - if ((var + index) >= SYSVAR_MAX) { - WARNING("%03d:%05x: Out of bounds index access: %s[%d]\n", sl_getPage(), sl_getIndex(), varname(var), index); + if ((var + index) >= SYSVAR_MAX) return NULL; - } preVarIndex = var + index; return sysVar + var + index; } @@ -111,10 +106,8 @@ int *v_ref_indexed(int var, int index) { // Indexed array access int page = attr->page; int offset = attr->offset; - if (offset + index >= arrayVarBuffer[page - 1].size) { - WARNING("%03d:%05x: Out of bounds index access: %s[%d]\n", sl_getPage(), sl_getIndex(), varname(var), index); + if (offset + index >= arrayVarBuffer[page - 1].size) return NULL; - } preVarIndex = offset + index; return arrayVarBuffer[page - 1].value + offset + index; } diff --git a/src/variable.h b/src/variable.h index a814cec..38e8d88 100644 --- a/src/variable.h +++ b/src/variable.h @@ -47,6 +47,7 @@ extern int preVarPage; extern int preVarIndex; extern int preVarNo; +const char *v_name(int var); int *v_ref(int var); int *v_ref_indexed(int var, int index); boolean v_allocateArrayBuffer(int page, int size, boolean saveflag);