Adds integration tests that test whether a substring of a script can panic.
This commit is contained in:
parent
b1d516b268
commit
69b5d76a9b
|
@ -8,6 +8,9 @@ use crate::parsing::parser::parse;
|
||||||
use crate::parsing::parser::parsed_statement::ParsedStatement;
|
use crate::parsing::parser::parsed_statement::ParsedStatement;
|
||||||
use crate::span::Span;
|
use crate::span::Span;
|
||||||
|
|
||||||
|
fn ignore_error(_msg: Message, _: Span) {
|
||||||
|
}
|
||||||
|
|
||||||
fn panic_on_error(msg: Message, _: Span) {
|
fn panic_on_error(msg: Message, _: Span) {
|
||||||
std::panic::panic_any(msg.stringify());
|
std::panic::panic_any(msg.stringify());
|
||||||
}
|
}
|
||||||
|
@ -351,3 +354,17 @@ fn integration_add_function() {
|
||||||
}"#).unwrap();
|
}"#).unwrap();
|
||||||
assert_eq!(parsed_tree, expected_tree);
|
assert_eq!(parsed_tree, expected_tree);
|
||||||
}
|
}
|
||||||
|
// A substring of a script should never panic, even though it might be completely invalid.
|
||||||
|
#[test]
|
||||||
|
fn integration_add_function_substring() {
|
||||||
|
let mut script = "int add(int a, int b) {
|
||||||
|
return a + b;
|
||||||
|
}".to_string();
|
||||||
|
for _ in 0..script.len() {
|
||||||
|
script.pop();
|
||||||
|
let lexed_tokens = lex(script.as_str(), &mut ignore_error);
|
||||||
|
let _parsed_tree = parse(lexed_tokens, &mut ignore_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -8,6 +8,14 @@ fn main() {
|
||||||
let mod_file_path = Path::new("src/integration_tests/mod.rs");
|
let mod_file_path = Path::new("src/integration_tests/mod.rs");
|
||||||
let mut mod_file = File::create(mod_file_path).unwrap();
|
let mut mod_file = File::create(mod_file_path).unwrap();
|
||||||
|
|
||||||
|
write!(
|
||||||
|
mod_file,
|
||||||
|
r#"////////////////////////////
|
||||||
|
// Automatically Generated//
|
||||||
|
////////////////////////////"#
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
for path_opt in paths {
|
for path_opt in paths {
|
||||||
if let Err(..) = path_opt {
|
if let Err(..) = path_opt {
|
||||||
continue;
|
continue;
|
||||||
|
@ -45,6 +53,9 @@ use crate::parsing::parser::parse;
|
||||||
use crate::parsing::parser::parsed_statement::ParsedStatement;
|
use crate::parsing::parser::parsed_statement::ParsedStatement;
|
||||||
use crate::span::Span;
|
use crate::span::Span;
|
||||||
|
|
||||||
|
fn ignore_error(_msg: Message, _: Span) {{
|
||||||
|
}}
|
||||||
|
|
||||||
fn panic_on_error(msg: Message, _: Span) {{
|
fn panic_on_error(msg: Message, _: Span) {{
|
||||||
std::panic::panic_any(msg.stringify());
|
std::panic::panic_any(msg.stringify());
|
||||||
}}"#
|
}}"#
|
||||||
|
@ -104,5 +115,25 @@ fn integration_{name}() {{
|
||||||
}
|
}
|
||||||
|
|
||||||
write!(testfile, "}}").unwrap();
|
write!(testfile, "}}").unwrap();
|
||||||
|
|
||||||
|
write!(
|
||||||
|
testfile,
|
||||||
|
r##"
|
||||||
|
// A substring of a script should never panic, even though it might be completely invalid.
|
||||||
|
#[test]
|
||||||
|
fn integration_{name}_substring() {{
|
||||||
|
let mut script = "{script}".to_string();
|
||||||
|
for _ in 0..script.len() {{
|
||||||
|
script.pop();
|
||||||
|
let lexed_tokens = lex(script.as_str(), &mut ignore_error);
|
||||||
|
let _parsed_tree = parse(lexed_tokens, &mut ignore_error);
|
||||||
|
}}
|
||||||
|
|
||||||
|
}}
|
||||||
|
"##,
|
||||||
|
name = test_name,
|
||||||
|
script = script
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,9 @@ use crate::parsing::parser::parse;
|
||||||
use crate::parsing::parser::parsed_statement::ParsedStatement;
|
use crate::parsing::parser::parsed_statement::ParsedStatement;
|
||||||
use crate::span::Span;
|
use crate::span::Span;
|
||||||
|
|
||||||
|
fn ignore_error(_msg: Message, _: Span) {
|
||||||
|
}
|
||||||
|
|
||||||
fn panic_on_error(msg: Message, _: Span) {
|
fn panic_on_error(msg: Message, _: Span) {
|
||||||
std::panic::panic_any(msg.stringify());
|
std::panic::panic_any(msg.stringify());
|
||||||
}
|
}
|
||||||
|
@ -91,3 +94,15 @@ fn integration_empty_class_declaration() {
|
||||||
}"#).unwrap();
|
}"#).unwrap();
|
||||||
assert_eq!(parsed_tree, expected_tree);
|
assert_eq!(parsed_tree, expected_tree);
|
||||||
}
|
}
|
||||||
|
// A substring of a script should never panic, even though it might be completely invalid.
|
||||||
|
#[test]
|
||||||
|
fn integration_empty_class_declaration_substring() {
|
||||||
|
let mut script = "class Foo {}".to_string();
|
||||||
|
for _ in 0..script.len() {
|
||||||
|
script.pop();
|
||||||
|
let lexed_tokens = lex(script.as_str(), &mut ignore_error);
|
||||||
|
let _parsed_tree = parse(lexed_tokens, &mut ignore_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -8,6 +8,9 @@ use crate::parsing::parser::parse;
|
||||||
use crate::parsing::parser::parsed_statement::ParsedStatement;
|
use crate::parsing::parser::parsed_statement::ParsedStatement;
|
||||||
use crate::span::Span;
|
use crate::span::Span;
|
||||||
|
|
||||||
|
fn ignore_error(_msg: Message, _: Span) {
|
||||||
|
}
|
||||||
|
|
||||||
fn panic_on_error(msg: Message, _: Span) {
|
fn panic_on_error(msg: Message, _: Span) {
|
||||||
std::panic::panic_any(msg.stringify());
|
std::panic::panic_any(msg.stringify());
|
||||||
}
|
}
|
||||||
|
@ -437,3 +440,21 @@ fn integration_enum_definition() {
|
||||||
}"#).unwrap();
|
}"#).unwrap();
|
||||||
assert_eq!(parsed_tree, expected_tree);
|
assert_eq!(parsed_tree, expected_tree);
|
||||||
}
|
}
|
||||||
|
// A substring of a script should never panic, even though it might be completely invalid.
|
||||||
|
#[test]
|
||||||
|
fn integration_enum_definition_substring() {
|
||||||
|
let mut script = "enum TestEnum : uint8 {
|
||||||
|
a,
|
||||||
|
b,
|
||||||
|
c,
|
||||||
|
d = 128,
|
||||||
|
e
|
||||||
|
}".to_string();
|
||||||
|
for _ in 0..script.len() {
|
||||||
|
script.pop();
|
||||||
|
let lexed_tokens = lex(script.as_str(), &mut ignore_error);
|
||||||
|
let _parsed_tree = parse(lexed_tokens, &mut ignore_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
mod enum_definition;
|
////////////////////////////
|
||||||
|
// Automatically Generated//
|
||||||
|
////////////////////////////mod enum_definition;
|
||||||
mod multiple_inheritance_class;
|
mod multiple_inheritance_class;
|
||||||
mod empty_class_declaration;
|
mod empty_class_declaration;
|
||||||
mod add_function;
|
mod add_function;
|
||||||
|
|
|
@ -8,6 +8,9 @@ use crate::parsing::parser::parse;
|
||||||
use crate::parsing::parser::parsed_statement::ParsedStatement;
|
use crate::parsing::parser::parsed_statement::ParsedStatement;
|
||||||
use crate::span::Span;
|
use crate::span::Span;
|
||||||
|
|
||||||
|
fn ignore_error(_msg: Message, _: Span) {
|
||||||
|
}
|
||||||
|
|
||||||
fn panic_on_error(msg: Message, _: Span) {
|
fn panic_on_error(msg: Message, _: Span) {
|
||||||
std::panic::panic_any(msg.stringify());
|
std::panic::panic_any(msg.stringify());
|
||||||
}
|
}
|
||||||
|
@ -171,3 +174,15 @@ fn integration_multiple_inheritance_class() {
|
||||||
}"#).unwrap();
|
}"#).unwrap();
|
||||||
assert_eq!(parsed_tree, expected_tree);
|
assert_eq!(parsed_tree, expected_tree);
|
||||||
}
|
}
|
||||||
|
// A substring of a script should never panic, even though it might be completely invalid.
|
||||||
|
#[test]
|
||||||
|
fn integration_multiple_inheritance_class_substring() {
|
||||||
|
let mut script = "class Foo : Zom, Aar, Bar {}".to_string();
|
||||||
|
for _ in 0..script.len() {
|
||||||
|
script.pop();
|
||||||
|
let lexed_tokens = lex(script.as_str(), &mut ignore_error);
|
||||||
|
let _parsed_tree = parse(lexed_tokens, &mut ignore_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -619,6 +619,10 @@ fn parse_class(
|
||||||
}
|
}
|
||||||
reader.consume(TokenType::CloseCurlyBracket, log);
|
reader.consume(TokenType::CloseCurlyBracket, log);
|
||||||
|
|
||||||
|
if name.is_none() {
|
||||||
|
return Some(Box::new(ParsedStatement::Invalid));
|
||||||
|
}
|
||||||
|
|
||||||
Some(Box::new(ParsedStatement::ClassDeclaration {
|
Some(Box::new(ParsedStatement::ClassDeclaration {
|
||||||
modifiers,
|
modifiers,
|
||||||
name: name.unwrap(),
|
name: name.unwrap(),
|
||||||
|
@ -670,6 +674,10 @@ fn parse_funcdef(
|
||||||
|
|
||||||
outer_reader.set_from_inner(&reader);
|
outer_reader.set_from_inner(&reader);
|
||||||
|
|
||||||
|
if identifier.is_none() || param_list.is_none() {
|
||||||
|
Some(Box::new(ParsedStatement::Invalid));
|
||||||
|
}
|
||||||
|
|
||||||
Some(Box::new(ParsedStatement::FuncDefDeclaration {
|
Some(Box::new(ParsedStatement::FuncDefDeclaration {
|
||||||
modifiers,
|
modifiers,
|
||||||
returns_reference,
|
returns_reference,
|
||||||
|
@ -894,7 +902,10 @@ fn parse_paramlist(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
let param_type = parse_type(reader, log);
|
let param_type = parse_type(reader, log);
|
||||||
// FIXME: Deal with empty param_type
|
if param_type.is_none() {
|
||||||
|
// FIXME: Add logging
|
||||||
|
break;
|
||||||
|
}
|
||||||
let type_mod = parse_typemod(reader, log);
|
let type_mod = parse_typemod(reader, log);
|
||||||
let identifier = parse_identifier(reader, log, true);
|
let identifier = parse_identifier(reader, log, true);
|
||||||
let mut default = None;
|
let mut default = None;
|
||||||
|
@ -1329,9 +1340,8 @@ fn parse_expr(
|
||||||
if let Some(..) = binary_operand {
|
if let Some(..) = binary_operand {
|
||||||
let expr_term2 = parse_exprterm(reader, log);
|
let expr_term2 = parse_exprterm(reader, log);
|
||||||
if expr_term2.is_none() {
|
if expr_term2.is_none() {
|
||||||
unimplemented!()
|
return Some(Box::new(ParsedStatement::Invalid));
|
||||||
}
|
}
|
||||||
// FIXME: deal with empty expr_term2
|
|
||||||
return Some(Box::new(ParsedStatement::BinaryExpr {
|
return Some(Box::new(ParsedStatement::BinaryExpr {
|
||||||
left: expr_term.unwrap(),
|
left: expr_term.unwrap(),
|
||||||
operator: binary_operand.unwrap(),
|
operator: binary_operand.unwrap(),
|
||||||
|
@ -1556,10 +1566,13 @@ fn parse_exprvalue(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_lambda(
|
fn parse_lambda(
|
||||||
_outer_reader: &mut ParseReader,
|
reader: &mut ParseReader,
|
||||||
_log: &mut dyn FnMut(Message, Span),
|
log: &mut dyn FnMut(Message, Span),
|
||||||
) -> Option<Box<ParsedStatement>> {
|
) -> Option<Box<ParsedStatement>> {
|
||||||
// lambda ::= 'function' '(' [[type typemod] identifier {',' [type typemod] identifier}] ')' statblock;
|
// lambda ::= 'function' '(' [[type typemod] identifier {',' [type typemod] identifier}] ')' statblock;
|
||||||
|
if reader.peek().token_type != TokenType::FunctionKeyword {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue