summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Robbbert <Robbbert@users.noreply.github.com>2020-10-15 22:30:31 +1100
committer Robbbert <Robbbert@users.noreply.github.com>2020-10-15 22:30:31 +1100
commitf619f2884f48964a80e8a10cad2b9d912c592b23 (patch)
tree4466510e920b61181d4703c5e6ba55a8629b9093
parent294b6f9895d74224617d4636b54ac690f90df647 (diff)
ssem: fixed regression in quickload; added protection against possible buffer overflows.
-rw-r--r--src/mame/drivers/ssem.cpp86
1 files changed, 57 insertions, 29 deletions
diff --git a/src/mame/drivers/ssem.cpp b/src/mame/drivers/ssem.cpp
index bb232317522..f89cb1c2bb1 100644
--- a/src/mame/drivers/ssem.cpp
+++ b/src/mame/drivers/ssem.cpp
@@ -537,19 +537,33 @@ void ssem_state::strlower(char *buf)
QUICKLOAD_LOAD_MEMBER(ssem_state::quickload_cb)
{
address_space &space = m_maincpu->space(AS_PROGRAM);
- char image_line[100] = { 0 };
+ char* image_line;
char token_buf[100] = { 0 };
int num_lines = 0;
+ u32 length = image.length()+1;
+ char quick_data[length];
+ image.fread( quick_data, length);
+
+ image_line = strtok(quick_data, "\n");
+ if (!image_line)
+ {
+ image.message("No data in line 1");
+ return image_init_result::FAIL;
+ }
- image.fgets(image_line, 99);
sscanf(image_line, "%d", &num_lines);
if (num_lines)
{
for (int i = 0; i < num_lines; i++)
{
- uint32_t line = 0;
- image.fgets(image_line, 99);
+ u32 line = 0, word = 0;
+ image_line = strtok(NULL, "\n");
+ if (!image_line)
+ {
+ image.message("No data in line %d",i+2);
+ return image_init_result::FAIL;
+ }
// Isolate and convert 4-digit decimal address
memcpy(token_buf, image_line, 4);
@@ -558,26 +572,30 @@ QUICKLOAD_LOAD_MEMBER(ssem_state::quickload_cb)
if (image.is_filetype("snp"))
{
- uint32_t word = 0;
+ if (strlen(image_line) < 38)
+ {
+ image.message("Bad data in line %d",i+2);
+ return image_init_result::FAIL;
+ }
// Parse a line such as: 0000:00000110101001000100000100000100
- for (int b = 0; b < 32; b++)
- {
+ for (u8 b = 0; b < 32; b++)
if (image_line[5 + b] == '1')
word |= 1 << (31 - b);
- }
-
- space.write_byte((line << 2) + 0, (word >> 24) & 0x000000ff);
- space.write_byte((line << 2) + 1, (word >> 16) & 0x000000ff);
- space.write_byte((line << 2) + 2, (word >> 8) & 0x000000ff);
- space.write_byte((line << 2) + 3, (word >> 0) & 0x000000ff);
}
- else if (image.is_filetype("asm"))
+ else
+ if (image.is_filetype("asm"))
{
+ length = strlen(image_line);
+ if (length < 9)
+ {
+ image.message("Bad data in line %d",i+2);
+ return image_init_result::FAIL;
+ }
+
char op_buf[4] = { 0 };
int32_t value = 0;
uint32_t unsigned_value = 0;
- uint32_t word = 0;
// Isolate the opcode and convert to lower-case
memcpy(op_buf, image_line + 5, 3);
@@ -585,31 +603,41 @@ QUICKLOAD_LOAD_MEMBER(ssem_state::quickload_cb)
strlower(op_buf);
// Isolate the value
- sscanf(image_line + 9, "%d", &value);
- unsigned_value = reverse((uint32_t)value);
+ if (length > 8)
+ {
+ sscanf(image_line + 9, "%d", &value);
+ unsigned_value = reverse((uint32_t)value);
+ }
if (!core_stricmp(op_buf, "num"))
word = unsigned_value;
- else if (!core_stricmp(op_buf, "jmp"))
+ else
+ if (!core_stricmp(op_buf, "jmp"))
word = 0x00000000 | unsigned_value ;
- else if (!core_stricmp(op_buf, "jrp"))
+ else
+ if (!core_stricmp(op_buf, "jrp"))
word = 0x00040000 | unsigned_value;
- else if (!core_stricmp(op_buf, "ldn"))
+ else
+ if (!core_stricmp(op_buf, "ldn"))
word = 0x00020000 | unsigned_value;
- else if (!core_stricmp(op_buf, "sto"))
+ else
+ if (!core_stricmp(op_buf, "sto"))
word = 0x00060000 | unsigned_value;
- else if (!core_stricmp(op_buf, "sub"))
+ else
+ if (!core_stricmp(op_buf, "sub"))
word = 0x00010000 | unsigned_value;
- else if (!core_stricmp(op_buf, "cmp"))
+ else
+ if (!core_stricmp(op_buf, "cmp"))
word = 0x00030000 | unsigned_value;
- else if (!core_stricmp(op_buf, "stp"))
+ else
+ if (!core_stricmp(op_buf, "stp"))
word = 0x00070000 | unsigned_value;
-
- space.write_byte((line << 2) + 0, (word >> 24) & 0x000000ff);
- space.write_byte((line << 2) + 1, (word >> 16) & 0x000000ff);
- space.write_byte((line << 2) + 2, (word >> 8) & 0x000000ff);
- space.write_byte((line << 2) + 3, (word >> 0) & 0x000000ff);
}
+
+ space.write_byte((line << 2) + 0, BIT(word, 24, 8));
+ space.write_byte((line << 2) + 1, BIT(word, 16, 8));
+ space.write_byte((line << 2) + 2, BIT(word, 8, 8));
+ space.write_byte((line << 2) + 3, BIT(word, 0, 8));
}
}