Add array oob checks + improve test handling
This commit is contained in:
parent
0448b56adf
commit
34f52ae864
2
LICENSE
2
LICENSE
@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 0x4261756D
|
||||
Copyright (c) 2022-2023 0x4261756D
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
|
55
src/main.rs
55
src/main.rs
@ -167,8 +167,9 @@ fn main()
|
||||
{
|
||||
if let Some(index) = file_content.find(":END:")
|
||||
{
|
||||
let expected = &format!("//invalid,{}:END:", msg.replace("\n", "\n//"));
|
||||
let expected_output = file_content[10..index].replace("\n//", "\n");
|
||||
println!("\n\n===FAILED===\nExpected the output to be {}", expected_output);
|
||||
println!("\n===FAILED===\nExpected the output to be\n'{}'\n({})", expected_output, expected);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -269,8 +270,12 @@ fn compile(file_content: &String, intrinsics: &HashMap<&str, (Vec<Datatype>, Vec
|
||||
{
|
||||
Ok(stderr) =>
|
||||
{
|
||||
println!("{:?}", stdout.as_bytes());
|
||||
Ok(Some(format!("{}{}", stdout, stderr)))
|
||||
let text = format!("{}{}", stdout, stderr);
|
||||
match output.status.code()
|
||||
{
|
||||
Some(0) => Ok(Some(text)),
|
||||
_ => Err(text),
|
||||
}
|
||||
}
|
||||
Err(err) => Err(err.to_string()),
|
||||
}
|
||||
@ -362,10 +367,38 @@ fn generate_assembly_linux_x64(operations: &Vec<Operation>, functions: &Vec<Func
|
||||
data.code += "\tlea rax, [dynamic+rsi]\n";
|
||||
data.code += "\tret\n";
|
||||
}
|
||||
if data.code.contains("exception_array_read_out_of_bounds")
|
||||
{
|
||||
data.strings += "\texception_array_oob_msg db \"Attempted array out-of-bounds access\", 10\n";
|
||||
data.code += "exception_array_read_out_of_bounds:\n";
|
||||
//TODO: report the passed sizes
|
||||
data.code += "\tmov rax, 1\n";
|
||||
data.code += "\tmov rdi, 1\n";
|
||||
// size
|
||||
data.code += "\tmov rdx, 37\n";
|
||||
// data
|
||||
data.code += "\tmov rsi, exception_array_oob_msg\n";
|
||||
data.code += "\tsyscall\n";
|
||||
data.code += "\tmov rax, 60\n";
|
||||
data.code += "\tmov rdi, -1\n";
|
||||
data.code += "\tsyscall\n";
|
||||
}
|
||||
|
||||
return fs::write("out.asm", format!("{}{}{}{}", ASSEMBLY_LINUX_X64_HEADER, data.code, data.arrays, data.strings));
|
||||
}
|
||||
|
||||
fn generate_assembly_linux_x64_array_oob_check(length: i64) -> String
|
||||
{
|
||||
let mut data = String::new();
|
||||
data += "\t\t;;Array bounds check\n";
|
||||
data += format!("\tcmp qword rax, {}\n", length).as_str();
|
||||
data += "\tjge exception_array_read_out_of_bounds\n";
|
||||
data += "\tcmp qword rax, 0\n";
|
||||
data += "\tjl exception_array_read_out_of_bounds\n";
|
||||
data += "\t\t;;Array bounds check over\n";
|
||||
return data.clone();
|
||||
}
|
||||
|
||||
fn generate_assembly_linux_x64_block(operations: &Vec<Operation>, functions: &Vec<Function>, intrinsics: &HashMap<&str, (Vec<Datatype>, Vec<Datatype>)>, arrays: &Vec<Arr>, debug: bool) -> AssemblyData
|
||||
{
|
||||
let mut data = AssemblyData
|
||||
@ -640,12 +673,14 @@ fn generate_assembly_linux_x64_block(operations: &Vec<Operation>, functions: &Ve
|
||||
}
|
||||
Operation::Apply(name, word, line, col) =>
|
||||
{
|
||||
let array = arrays.iter().find(|x| &x.name == name).unwrap();
|
||||
data.code += format!("\t;;apply {}.{} {}:{}\n", name, word, line, col).as_str();
|
||||
match word.as_str()
|
||||
{
|
||||
"read" =>
|
||||
{
|
||||
data.code += "\tmov rax, [queue+8*r12]\n";
|
||||
data.code += generate_assembly_linux_x64_array_oob_check(array.length).as_str();
|
||||
data.code += "\tinc r12\n";
|
||||
data.code += ASSEMBLY_LINUX_X64_TRY_RESET_QUEUE;
|
||||
data.code += format!("\tmov qword rbx, [arr_{}+8*rax]\n", name).as_str();
|
||||
@ -655,6 +690,7 @@ fn generate_assembly_linux_x64_block(operations: &Vec<Operation>, functions: &Ve
|
||||
"write" =>
|
||||
{
|
||||
data.code += "\tmov rax, [queue+8*r12]\n";
|
||||
data.code += generate_assembly_linux_x64_array_oob_check(array.length).as_str();
|
||||
data.code += "\tinc r12\n";
|
||||
data.code += ASSEMBLY_LINUX_X64_TRY_RESET_QUEUE;
|
||||
data.code += "\tmov qword rbx, [queue+8*r12]\n";
|
||||
@ -664,7 +700,6 @@ fn generate_assembly_linux_x64_block(operations: &Vec<Operation>, functions: &Ve
|
||||
}
|
||||
"length" =>
|
||||
{
|
||||
let array = arrays.iter().find(|x| &x.name == name).unwrap();
|
||||
data.code += format!("\tmov qword [queue+8*r13], {}\n", array.length).as_str();
|
||||
data.code += "\tinc r13\n";
|
||||
}
|
||||
@ -896,11 +931,13 @@ fn interpret_program(operations: &Vec<Operation>, queue: &mut Vec<String>, funct
|
||||
let position: i64 = queue.remove(0).parse::<i64>().unwrap();
|
||||
if position >= arr.length
|
||||
{
|
||||
return Err(format!("Attempted an out of bounds write for array {} ({} >= {}) at {}:{}", arr.name, position, arr.length, line, col));
|
||||
//return Err(format!("Attempted an out of bounds write for array {} ({} >= {}) at {}:{}", arr.name, position, arr.length, line, col));
|
||||
return Err(String::from("Attempted array out-of-bounds access"));
|
||||
}
|
||||
if position < 0
|
||||
{
|
||||
return Err(format!("Attempted an out of bounds write for array {} ({} < 0) at {}:{}", arr.name, position, line, col));
|
||||
//return Err(format!("Attempted an out of bounds write for array {} ({} < 0) at {}:{}", arr.name, position, line, col));
|
||||
return Err(String::from("Attempted array out-of-bounds access"));
|
||||
}
|
||||
let data = queue.remove(0);
|
||||
if debug
|
||||
@ -918,11 +955,13 @@ fn interpret_program(operations: &Vec<Operation>, queue: &mut Vec<String>, funct
|
||||
let position: i64 = queue.remove(0).parse::<i64>().unwrap();
|
||||
if position >= arr.length
|
||||
{
|
||||
return Err(format!("Attempted an out of bounds read for array {} ({} >= {}) at {}:{}", arr.name, position, arr.length, line, col));
|
||||
//return Err(format!("Attempted an out of bounds read for array {} ({} >= {}) at {}:{}", arr.name, position, arr.length, line, col));
|
||||
return Err(String::from("Attempted array out-of-bounds access"));
|
||||
}
|
||||
if position < 0
|
||||
{
|
||||
return Err(format!("Attempted an out of bounds read for array {} ({} < 0) at {}:{}", arr.name, position, line, col));
|
||||
//return Err(format!("Attempted an out of bounds read for array {} ({} < 0) at {}:{}", arr.name, position, line, col));
|
||||
return Err(String::from("Attempted array out-of-bounds access"));
|
||||
}
|
||||
queue.push(arr.data[position as usize].clone());
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
//invalid,Attempted an out of bounds read for array test (5 >= 4) at 5:12:END:
|
||||
//invalid,Attempted array out-of-bounds access
|
||||
//:END:
|
||||
|
||||
arr test { bool 4 }
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
//invalid,Attempted an out of bounds write for array test (5 >= 4) at 5:19:END:
|
||||
//invalid,Attempted array out-of-bounds access
|
||||
//:END:
|
||||
|
||||
arr test { bool 4 }
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
//invalid,Attempted an out of bounds read for array test (-1 < 0) at 5:13:END:
|
||||
//invalid,Attempted array out-of-bounds access
|
||||
//:END:
|
||||
|
||||
arr test { bool 4 }
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
//invalid,Attempted an out of bounds write for array test (-1 < 0) at 5:19:END:
|
||||
//invalid,Attempted array out-of-bounds access
|
||||
//:END:
|
||||
|
||||
arr test { bool 4 }
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user