From 7259a0b49baa2404aa0fecc88a1b5b7c061ba066 Mon Sep 17 00:00:00 2001 From: Valerii Huhnin Date: Thu, 15 Aug 2024 08:25:11 +0000 Subject: [PATCH 01/52] tests for `BrTrue` instruction --- crates/move-bytecode-verifier/src/lib.rs | 3 + .../src/type_safety_tests/mod.rs | 77 +++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 crates/move-bytecode-verifier/src/type_safety_tests/mod.rs diff --git a/crates/move-bytecode-verifier/src/lib.rs b/crates/move-bytecode-verifier/src/lib.rs index feea66c545..4bb6a977e9 100644 --- a/crates/move-bytecode-verifier/src/lib.rs +++ b/crates/move-bytecode-verifier/src/lib.rs @@ -45,3 +45,6 @@ mod reference_safety; mod regression_tests; mod stack_usage_verifier; mod type_safety; + +#[cfg(test)] +mod type_safety_tests; diff --git a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs new file mode 100644 index 0000000000..acfea0e2bc --- /dev/null +++ b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs @@ -0,0 +1,77 @@ +use move_binary_format::file_format::{ + Bytecode, CodeUnit, FunctionDefinition, FunctionHandle, + IdentifierIndex, ModuleHandleIndex, SignatureIndex, + FunctionDefinitionIndex, empty_module +}; + +use move_core_types::vm_status::StatusCode; +use move_binary_format::CompiledModule; +use move_bytecode_verifier_meter::dummy::DummyMeter; +use crate::absint::FunctionContext; +use crate::type_safety; + + +fn make_module(code: Vec) -> CompiledModule { + let code_unit = CodeUnit { + code, + ..Default::default() + }; + + let fun_def = FunctionDefinition { + code: Some(code_unit.clone()), + ..Default::default() + }; + + let fun_handle = FunctionHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(0), + parameters: SignatureIndex(0), + return_: SignatureIndex(0), + type_parameters: vec![], + }; + + let mut module = empty_module(); + module.function_handles.push(fun_handle); + module.function_defs.push(fun_def); + + module +} + +fn get_fun_context(module: &CompiledModule) -> FunctionContext { + FunctionContext::new( + &module, + FunctionDefinitionIndex(0), + module.function_defs[0].code.as_ref().unwrap(), + &module.function_handles[0], + ) +} + +#[test] +fn test_br_true_bool() { + let code = vec![Bytecode::LdTrue, Bytecode::BrTrue(0)]; + let module = make_module(code); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); +} + +#[test] +fn test_br_true_u32() { + let code = vec![Bytecode::LdU32(0), Bytecode::BrTrue(0)]; + let module = make_module(code); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::BR_TYPE_MISMATCH_ERROR + ); +} + +#[test] +#[should_panic] +fn test_br_true_no_arg() { + let code = vec![Bytecode::BrTrue(0)]; + let module = make_module(code); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); +} From cc15bb38d0bf6fa5b9d6d9c31bdc088a79181599 Mon Sep 17 00:00:00 2001 From: Valerii Huhnin Date: Fri, 16 Aug 2024 05:53:14 +0000 Subject: [PATCH 02/52] add tests for `BrFalse` instruction --- .../src/type_safety_tests/mod.rs | 37 ++++++++++++++++++- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs index acfea0e2bc..255e679e97 100644 --- a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs +++ b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs @@ -46,8 +46,9 @@ fn get_fun_context(module: &CompiledModule) -> FunctionContext { ) } + #[test] -fn test_br_true_bool() { +fn test_br_true_correct_type() { let code = vec![Bytecode::LdTrue, Bytecode::BrTrue(0)]; let module = make_module(code); let fun_context = get_fun_context(&module); @@ -56,7 +57,7 @@ fn test_br_true_bool() { } #[test] -fn test_br_true_u32() { +fn test_br_true_wrong_type() { let code = vec![Bytecode::LdU32(0), Bytecode::BrTrue(0)]; let module = make_module(code); let fun_context = get_fun_context(&module); @@ -75,3 +76,35 @@ fn test_br_true_no_arg() { let fun_context = get_fun_context(&module); let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); } + + +#[test] +fn test_br_false_correct_type() { + let code = vec![Bytecode::LdTrue, Bytecode::BrFalse(0)]; + let module = make_module(code); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); +} + +#[test] +fn test_br_false_wrong_type() { + let code = vec![Bytecode::LdU32(0), Bytecode::BrFalse(0)]; + let module = make_module(code); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::BR_TYPE_MISMATCH_ERROR + ); +} + +#[test] +#[should_panic] +fn test_br_false_no_arg() { + let code = vec![Bytecode::BrFalse(0)]; + let module = make_module(code); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); +} + From 1ad0730d4ee8d213edb8fab02936419d51f809df Mon Sep 17 00:00:00 2001 From: Valerii Huhnin Date: Fri, 16 Aug 2024 05:53:36 +0000 Subject: [PATCH 03/52] tests for `Abort` instruction --- .../src/type_safety_tests/mod.rs | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs index 255e679e97..87cf5b050c 100644 --- a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs +++ b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs @@ -108,3 +108,34 @@ fn test_br_false_no_arg() { let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); } + +#[test] +fn test_abort_correct_type() { + let code = vec![Bytecode::LdU64(0), Bytecode::Abort]; + let module = make_module(code); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); +} + + +#[test] +fn test_abort_wrong_type() { + let code = vec![Bytecode::LdU32(0), Bytecode::Abort]; + let module = make_module(code); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::ABORT_TYPE_MISMATCH_ERROR + ); +} + +#[test] +#[should_panic] +fn test_abort_no_arg() { + let code = vec![Bytecode::Abort]; + let module = make_module(code); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); +} From 36466a62f8ca030ec2ab8fc8d000a5ee84ed791a Mon Sep 17 00:00:00 2001 From: Valerii Huhnin Date: Fri, 16 Aug 2024 06:03:30 +0000 Subject: [PATCH 04/52] join tests for `BrTrue` and `BrFalse` --- .../src/type_safety_tests/mod.rs | 56 +++++++------------ 1 file changed, 20 insertions(+), 36 deletions(-) diff --git a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs index 87cf5b050c..74fd181e9c 100644 --- a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs +++ b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs @@ -48,48 +48,26 @@ fn get_fun_context(module: &CompiledModule) -> FunctionContext { #[test] -fn test_br_true_correct_type() { - let code = vec![Bytecode::LdTrue, Bytecode::BrTrue(0)]; +fn test_br_true_false_correct_type() { + for instr in vec![ + Bytecode::BrTrue(0), + Bytecode::BrFalse(0), + ] { + let code = vec![Bytecode::LdTrue, instr]; let module = make_module(code); let fun_context = get_fun_context(&module); let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); assert!(result.is_ok()); } - -#[test] -fn test_br_true_wrong_type() { - let code = vec![Bytecode::LdU32(0), Bytecode::BrTrue(0)]; - let module = make_module(code); - let fun_context = get_fun_context(&module); - let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); - assert_eq!( - result.unwrap_err().major_status(), - StatusCode::BR_TYPE_MISMATCH_ERROR - ); -} - -#[test] -#[should_panic] -fn test_br_true_no_arg() { - let code = vec![Bytecode::BrTrue(0)]; - let module = make_module(code); - let fun_context = get_fun_context(&module); - let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); -} - - -#[test] -fn test_br_false_correct_type() { - let code = vec![Bytecode::LdTrue, Bytecode::BrFalse(0)]; - let module = make_module(code); - let fun_context = get_fun_context(&module); - let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); - assert!(result.is_ok()); } #[test] -fn test_br_false_wrong_type() { - let code = vec![Bytecode::LdU32(0), Bytecode::BrFalse(0)]; +fn test_br_true_false_wrong_type() { + for instr in vec![ + Bytecode::BrTrue(0), + Bytecode::BrFalse(0), + ] { + let code = vec![Bytecode::LdU32(0), instr]; let module = make_module(code); let fun_context = get_fun_context(&module); let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); @@ -97,15 +75,21 @@ fn test_br_false_wrong_type() { result.unwrap_err().major_status(), StatusCode::BR_TYPE_MISMATCH_ERROR ); + } } #[test] #[should_panic] -fn test_br_false_no_arg() { - let code = vec![Bytecode::BrFalse(0)]; +fn test_br_true_false_no_arg() { + for instr in vec![ + Bytecode::BrTrue(0), + Bytecode::BrFalse(0), + ] { + let code = vec![instr]; let module = make_module(code); let fun_context = get_fun_context(&module); let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + } } From a1466a4838fd905e1409a8c712109103d57cfd6c Mon Sep 17 00:00:00 2001 From: Valerii Huhnin Date: Fri, 16 Aug 2024 06:04:07 +0000 Subject: [PATCH 05/52] add tests for `CastU*` instructions --- .../src/type_safety_tests/mod.rs | 88 +++++++++++++++---- 1 file changed, 73 insertions(+), 15 deletions(-) diff --git a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs index 74fd181e9c..4cbbad111a 100644 --- a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs +++ b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs @@ -54,11 +54,11 @@ fn test_br_true_false_correct_type() { Bytecode::BrFalse(0), ] { let code = vec![Bytecode::LdTrue, instr]; - let module = make_module(code); - let fun_context = get_fun_context(&module); - let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); - assert!(result.is_ok()); -} + let module = make_module(code); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); + } } #[test] @@ -68,13 +68,13 @@ fn test_br_true_false_wrong_type() { Bytecode::BrFalse(0), ] { let code = vec![Bytecode::LdU32(0), instr]; - let module = make_module(code); - let fun_context = get_fun_context(&module); - let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); - assert_eq!( - result.unwrap_err().major_status(), - StatusCode::BR_TYPE_MISMATCH_ERROR - ); + let module = make_module(code); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::BR_TYPE_MISMATCH_ERROR + ); } } @@ -86,9 +86,9 @@ fn test_br_true_false_no_arg() { Bytecode::BrFalse(0), ] { let code = vec![instr]; - let module = make_module(code); - let fun_context = get_fun_context(&module); - let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + let module = make_module(code); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); } } @@ -123,3 +123,61 @@ fn test_abort_no_arg() { let fun_context = get_fun_context(&module); let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); } + + +#[test] +fn test_cast_correct_type() { + for instr in vec![ + Bytecode::CastU8, + Bytecode::CastU16, + Bytecode::CastU32, + Bytecode::CastU64, + Bytecode::CastU128, + Bytecode::CastU256, + ] { + let code = vec![Bytecode::LdU64(0), instr]; + let module = make_module(code); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); + } +} + +#[test] +fn test_cast_wrong_type() { + for instr in vec![ + Bytecode::CastU8, + Bytecode::CastU16, + Bytecode::CastU32, + Bytecode::CastU64, + Bytecode::CastU128, + Bytecode::CastU256, + ] { + let code = vec![Bytecode::LdTrue, instr]; + let module = make_module(code); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::INTEGER_OP_TYPE_MISMATCH_ERROR + ); + } +} + +#[test] +#[should_panic] +fn test_cast_no_arg() { + for instr in vec![ + Bytecode::CastU8, + Bytecode::CastU16, + Bytecode::CastU32, + Bytecode::CastU64, + Bytecode::CastU128, + Bytecode::CastU256, + ] { + let code = vec![instr]; + let module = make_module(code); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + } +} From c3e00cc88e7010cda92fd8ed3824f445cd689f7b Mon Sep 17 00:00:00 2001 From: Valerii Huhnin Date: Fri, 16 Aug 2024 06:29:07 +0000 Subject: [PATCH 06/52] tests for arithmetic operations --- .../src/type_safety_tests/mod.rs | 113 ++++++++++++++++++ 1 file changed, 113 insertions(+) diff --git a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs index 4cbbad111a..66f33a53ca 100644 --- a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs +++ b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs @@ -4,6 +4,7 @@ use move_binary_format::file_format::{ FunctionDefinitionIndex, empty_module }; +use move_core_types::u256::U256; use move_core_types::vm_status::StatusCode; use move_binary_format::CompiledModule; use move_bytecode_verifier_meter::dummy::DummyMeter; @@ -181,3 +182,115 @@ fn test_cast_no_arg() { let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); } } + + + +#[test] +fn test_arithmetic_correct_types() { + for instr in vec![ + Bytecode::Add, + Bytecode::Sub, + Bytecode::Mul, + Bytecode::Mod, + Bytecode::Div, + Bytecode::BitOr, + Bytecode::BitAnd, + Bytecode::Xor, + ] { + for push_ty_instr in vec![ + Bytecode::LdU8(42), + Bytecode::LdU16(257), + Bytecode::LdU32(89), + Bytecode::LdU64(94), + Bytecode::LdU128(Box::new(9999)), + Bytecode::LdU256(Box::new(U256::from(745_u32))), + ] { + let code = vec![push_ty_instr.clone(), push_ty_instr.clone(), instr.clone()]; + let module = make_module(code); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); + } + } +} + +#[test] +fn test_arithmetic_mismatched_types() { + for instr in vec![ + Bytecode::Add, + Bytecode::Sub, + Bytecode::Mul, + Bytecode::Mod, + Bytecode::Div, + Bytecode::BitOr, + Bytecode::BitAnd, + Bytecode::Xor, + ] { + let code = vec![Bytecode::LdU8(42), Bytecode::LdU64(94), instr]; + let module = make_module(code); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::INTEGER_OP_TYPE_MISMATCH_ERROR + ); + } +} + +#[test] +fn test_arithmetic_wrong_type() { + for instr in vec![ + Bytecode::Add, + Bytecode::Sub, + Bytecode::Mul, + Bytecode::Mod, + Bytecode::Div, + Bytecode::BitOr, + Bytecode::BitAnd, + Bytecode::Xor, + ] { + let code = vec![Bytecode::LdTrue, Bytecode::LdU64(94), instr.clone()]; + let module = make_module(code); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::INTEGER_OP_TYPE_MISMATCH_ERROR + ); + + let code = vec![Bytecode::LdU32(94), Bytecode::LdFalse, instr.clone()]; + let module = make_module(code); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::INTEGER_OP_TYPE_MISMATCH_ERROR + ); + } +} + + +#[test] +#[should_panic] +fn test_arithmetic_too_few_args() { + for instr in vec![ + Bytecode::Add, + Bytecode::Sub, + Bytecode::Mul, + Bytecode::Mod, + Bytecode::Div, + Bytecode::BitOr, + Bytecode::BitAnd, + Bytecode::Xor, + ] { + let code = vec![Bytecode::LdU16(42), instr.clone()]; + let module = make_module(code); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + + let code = vec![instr.clone()]; + let module = make_module(code); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + } +} From 1ea1ccb774f59a876391cedf90a35f8c7a915aa4 Mon Sep 17 00:00:00 2001 From: Valerii Huhnin Date: Fri, 16 Aug 2024 06:41:16 +0000 Subject: [PATCH 07/52] tests for `Shl` and `Shr` instructions --- .../src/type_safety_tests/mod.rs | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs index 66f33a53ca..44d5cdef5c 100644 --- a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs +++ b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs @@ -294,3 +294,80 @@ fn test_arithmetic_too_few_args() { let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); } } + + +#[test] +fn test_shl_shr_correct_types() { + for instr in vec![ + Bytecode::Shl, + Bytecode::Shr, + ] { + for push_ty_instr in vec![ + Bytecode::LdU8(42), + Bytecode::LdU16(257), + Bytecode::LdU32(89), + Bytecode::LdU64(94), + Bytecode::LdU128(Box::new(9999)), + Bytecode::LdU256(Box::new(U256::from(745_u32))), + ] { + let code = vec![push_ty_instr.clone(), Bytecode::LdU8(2), instr.clone()]; + let module = make_module(code); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); + } + } +} + +#[test] +fn test_shl_shr_first_operand_wrong_type() { + for instr in vec![ + Bytecode::Shl, + Bytecode::Shr, + ] { + let code = vec![Bytecode::LdTrue, Bytecode::LdU8(2), instr.clone()]; + let module = make_module(code); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::INTEGER_OP_TYPE_MISMATCH_ERROR + ); + } +} + +#[test] +fn test_shl_shr_second_operand_wrong_type() { + for instr in vec![ + Bytecode::Shl, + Bytecode::Shr, + ] { + let code = vec![Bytecode::LdU32(42), Bytecode::LdU16(2), instr.clone()]; + let module = make_module(code); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::INTEGER_OP_TYPE_MISMATCH_ERROR + ); + } +} + +#[test] +#[should_panic] +fn test_shl_shr_too_few_args() { + for instr in vec![ + Bytecode::Shl, + Bytecode::Shr, + ] { + let code = vec![Bytecode::LdU16(42), instr.clone()]; + let module = make_module(code); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + + let code = vec![instr.clone()]; + let module = make_module(code); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + } +} From 8cd8658be22bbafdbda9e53801d020fdb4105cec Mon Sep 17 00:00:00 2001 From: Valerii Huhnin Date: Fri, 16 Aug 2024 06:47:50 +0000 Subject: [PATCH 08/52] tests for `Or` and `And` operations --- .../src/type_safety_tests/mod.rs | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs index 44d5cdef5c..2d47aec29d 100644 --- a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs +++ b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs @@ -371,3 +371,63 @@ fn test_shl_shr_too_few_args() { let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); } } + + +#[test] +fn test_or_and_correct_types() { + for instr in vec![ + Bytecode::Or, + Bytecode::And, + ] { + let code = vec![Bytecode::LdFalse, Bytecode::LdTrue, instr.clone()]; + let module = make_module(code); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); + } +} + +#[test] +fn test_or_and_wrong_types() { + for instr in vec![ + Bytecode::Or, + Bytecode::And, + ] { + let code = vec![Bytecode::LdU32(42), Bytecode::LdTrue, instr.clone()]; + let module = make_module(code); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::BOOLEAN_OP_TYPE_MISMATCH_ERROR + ); + + let code = vec![Bytecode::LdTrue, Bytecode::LdU64(42), instr.clone()]; + let module = make_module(code); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::BOOLEAN_OP_TYPE_MISMATCH_ERROR + ); + } +} + +#[test] +#[should_panic] +fn test_or_and_too_few_args() { + for instr in vec![ + Bytecode::Or, + Bytecode::And, + ] { + let code = vec![Bytecode::LdTrue, instr.clone()]; + let module = make_module(code); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + + let code = vec![instr.clone()]; + let module = make_module(code); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + } +} From 05034b3c8d2c0e7e6349eb67852dfc4273e12319 Mon Sep 17 00:00:00 2001 From: Valerii Huhnin Date: Fri, 16 Aug 2024 06:49:15 +0000 Subject: [PATCH 09/52] tests for `Not` operation --- .../src/type_safety_tests/mod.rs | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs index 2d47aec29d..787aac19df 100644 --- a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs +++ b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs @@ -431,3 +431,34 @@ fn test_or_and_too_few_args() { let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); } } + + +#[test] +fn test_not_correct_type() { + let code = vec![Bytecode::LdFalse, Bytecode::Not]; + let module = make_module(code); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); +} + +#[test] +fn test_not_wrong_type() { + let code = vec![Bytecode::LdU32(42), Bytecode::Not]; + let module = make_module(code); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::BOOLEAN_OP_TYPE_MISMATCH_ERROR + ); +} + +#[test] +#[should_panic] +fn test_not_no_arg() { + let code = vec![Bytecode::Not]; + let module = make_module(code); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); +} From 97bf7284507bcede896b729867e941d49f7826d1 Mon Sep 17 00:00:00 2001 From: Valerii Huhnin Date: Fri, 16 Aug 2024 06:55:23 +0000 Subject: [PATCH 10/52] test comparison operations --- .../src/type_safety_tests/mod.rs | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs index 787aac19df..fd6ba2b1c6 100644 --- a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs +++ b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs @@ -462,3 +462,99 @@ fn test_not_no_arg() { let fun_context = get_fun_context(&module); let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); } + + +#[test] +fn test_comparison_correct_types() { + for instr in vec![ + Bytecode::Lt, + Bytecode::Gt, + Bytecode::Le, + Bytecode::Ge, + Bytecode::Eq, + Bytecode::Neq, + ] { + for push_ty_instr in vec![ + Bytecode::LdU8(42), + Bytecode::LdU16(257), + Bytecode::LdU32(89), + Bytecode::LdU64(94), + Bytecode::LdU128(Box::new(9999)), + Bytecode::LdU256(Box::new(U256::from(745_u32))), + ] { + let code = vec![push_ty_instr.clone(), push_ty_instr.clone(), instr.clone()]; + let module = make_module(code); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); + } + } +} + +#[test] +fn test_comparison_mismatched_types() { + for instr in vec![ + Bytecode::Lt, + Bytecode::Gt, + Bytecode::Le, + Bytecode::Ge, + ] { + let code = vec![Bytecode::LdU8(42), Bytecode::LdU64(94), instr.clone()]; + let module = make_module(code); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::INTEGER_OP_TYPE_MISMATCH_ERROR + ); + } +} + +#[test] +fn test_comparison_wrong_type() { + for instr in vec![ + Bytecode::Lt, + Bytecode::Gt, + Bytecode::Le, + Bytecode::Ge, + ] { + let code = vec![Bytecode::LdTrue, Bytecode::LdU64(94), instr.clone()]; + let module = make_module(code); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::INTEGER_OP_TYPE_MISMATCH_ERROR + ); + + let code = vec![Bytecode::LdU32(94), Bytecode::LdFalse, instr.clone()]; + let module = make_module(code); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::INTEGER_OP_TYPE_MISMATCH_ERROR + ); + } +} + +#[test] +#[should_panic] +fn test_comparison_too_few_args() { + for instr in vec![ + Bytecode::Lt, + Bytecode::Gt, + Bytecode::Le, + Bytecode::Ge, + ] { + let code = vec![Bytecode::LdU16(42), instr.clone()]; + let module = make_module(code); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + + let code = vec![instr.clone()]; + let module = make_module(code); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + } +} From 135631dc64795f1a22604c8ffdc9583c9171d847 Mon Sep 17 00:00:00 2001 From: Valerii Huhnin Date: Thu, 22 Aug 2024 06:42:44 +0000 Subject: [PATCH 11/52] tests for `Branch` and `Nop` instructions --- .../src/type_safety_tests/mod.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs index fd6ba2b1c6..a32fc922f1 100644 --- a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs +++ b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs @@ -558,3 +558,19 @@ fn test_comparison_too_few_args() { let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); } } + + +// these operation does not produce errors in verify_instr() +#[test] +fn test_branch_nop_ok() { + for instr in vec![ + Bytecode::Branch(0), + Bytecode::Nop, + ] { + let code = vec![instr]; + let module = make_module(code); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); + } +} From cc4c43eea2ae82a3d096ee8c663906a641728ddb Mon Sep 17 00:00:00 2001 From: Valerii Huhnin Date: Thu, 22 Aug 2024 06:43:08 +0000 Subject: [PATCH 12/52] tests for `LdU*` instructions --- .../src/type_safety_tests/mod.rs | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs index a32fc922f1..795100fa1d 100644 --- a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs +++ b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs @@ -574,3 +574,23 @@ fn test_branch_nop_ok() { assert!(result.is_ok()); } } + + +#[test] +fn test_ld_integers_ok() { + for instr in vec![ + Bytecode::LdU8(42), + Bytecode::LdU16(257), + Bytecode::LdU32(89), + Bytecode::LdU64(94), + Bytecode::LdU128(Box::new(9999)), + Bytecode::LdU256(Box::new(U256::from(745_u32))), + ] { + let code = vec![instr]; + let module = make_module(code); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); + } +} + From 88a92735858c82e3cd4d97d4f8b2feb50a10816f Mon Sep 17 00:00:00 2001 From: Valerii Huhnin Date: Thu, 22 Aug 2024 06:43:34 +0000 Subject: [PATCH 13/52] tests for `LdTrue` and `LdFalse` instructions --- .../src/type_safety_tests/mod.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs index 795100fa1d..223d754dbc 100644 --- a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs +++ b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs @@ -594,3 +594,18 @@ fn test_ld_integers_ok() { } } + +#[test] +fn test_ld_true_false_ok() { + for instr in vec![ + Bytecode::LdTrue, + Bytecode::LdFalse, + ] { + let code = vec![instr]; + let module = make_module(code); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); + } +} + From 54993197391bf1a70596cbcafec1c1a1964f5e9f Mon Sep 17 00:00:00 2001 From: Valerii Huhnin Date: Thu, 22 Aug 2024 06:43:57 +0000 Subject: [PATCH 14/52] tests for `LdConst` instruction --- .../src/type_safety_tests/mod.rs | 28 +++++++++++++++++-- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs index 223d754dbc..48c2b107af 100644 --- a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs +++ b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs @@ -4,11 +4,18 @@ use move_binary_format::file_format::{ FunctionDefinitionIndex, empty_module }; -use move_core_types::u256::U256; -use move_core_types::vm_status::StatusCode; -use move_binary_format::CompiledModule; +use move_core_types::{ + u256::U256, vm_status::StatusCode, +}; + +use move_binary_format::{ + CompiledModule, + file_format::{ConstantPoolIndex, Constant, SignatureToken}, +}; + use move_bytecode_verifier_meter::dummy::DummyMeter; use crate::absint::FunctionContext; +use crate::constants; use crate::type_safety; @@ -609,3 +616,18 @@ fn test_ld_true_false_ok() { } } + +#[test] +fn test_ld_const_ok() { + let code = vec![Bytecode::LdConst(ConstantPoolIndex(0))]; + let constant = Constant { + type_: SignatureToken::U32, + data: vec![42, 15, 17, 51], + }; + let mut module: CompiledModule = make_module(code); + module.constant_pool.push(constant); + assert!(constants::verify_module(&module).is_ok()); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); +} From 1483afa28024d8ff6b57bdab607f456d157197f0 Mon Sep 17 00:00:00 2001 From: Valerii Huhnin Date: Tue, 27 Aug 2024 00:55:28 +0000 Subject: [PATCH 15/52] tests for `Pack` operation --- .../src/type_safety_tests/mod.rs | 68 +++++++++++++++++-- 1 file changed, 64 insertions(+), 4 deletions(-) diff --git a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs index 48c2b107af..182ea3782c 100644 --- a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs +++ b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs @@ -1,7 +1,5 @@ use move_binary_format::file_format::{ - Bytecode, CodeUnit, FunctionDefinition, FunctionHandle, - IdentifierIndex, ModuleHandleIndex, SignatureIndex, - FunctionDefinitionIndex, empty_module + empty_module, Bytecode, CodeUnit, FunctionDefinition, FunctionDefinitionIndex, FunctionHandle, IdentifierIndex, ModuleHandleIndex, SignatureIndex, StructDefinitionIndex }; use move_core_types::{ @@ -10,7 +8,9 @@ use move_core_types::{ use move_binary_format::{ CompiledModule, - file_format::{ConstantPoolIndex, Constant, SignatureToken}, + file_format::{ + ConstantPoolIndex, Constant, SignatureToken, AbilitySet, StructHandle, TypeSignature, FieldDefinition, StructHandleIndex, StructFieldInformation, StructDefinition + }, }; use move_bytecode_verifier_meter::dummy::DummyMeter; @@ -45,6 +45,32 @@ fn make_module(code: Vec) -> CompiledModule { module } +fn add_simple_struct(module: &mut CompiledModule) { + let struct_def = StructDefinition { + struct_handle: StructHandleIndex(0), + field_information: StructFieldInformation::Declared(vec![ + FieldDefinition { + name: IdentifierIndex(5), + signature: TypeSignature(SignatureToken::U32), + }, + FieldDefinition { + name: IdentifierIndex(6), + signature: TypeSignature(SignatureToken::Bool), + }, + ]), + }; + + let struct_handle = StructHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(0), + abilities: AbilitySet::EMPTY, + type_parameters: vec![], + }; + + module.struct_defs.push(struct_def); + module.struct_handles.push(struct_handle); +} + fn get_fun_context(module: &CompiledModule) -> FunctionContext { FunctionContext::new( &module, @@ -631,3 +657,37 @@ fn test_ld_const_ok() { let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); assert!(result.is_ok()); } + + +#[test] +fn test_pack_correct_types() { + let code = vec![Bytecode::LdU32(42), Bytecode::LdTrue, Bytecode::Pack(StructDefinitionIndex(0))]; + let mut module: CompiledModule = make_module(code); + add_simple_struct(&mut module); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); +} + +#[test] +fn test_pack_mismatched_types() { + let code = vec![Bytecode::LdTrue, Bytecode::LdU32(42), Bytecode::Pack(StructDefinitionIndex(0))]; + let mut module: CompiledModule = make_module(code); + add_simple_struct(&mut module); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::PACK_TYPE_MISMATCH_ERROR + ); +} + +#[test] +#[should_panic] +fn test_pack_too_few_args() { + let code = vec![Bytecode::LdTrue, Bytecode::Pack(StructDefinitionIndex(0))]; + let mut module: CompiledModule = make_module(code); + add_simple_struct(&mut module); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); +} From 7420fe7f8853d6e12c7dd626431bac63e66c6dec Mon Sep 17 00:00:00 2001 From: Valerii Huhnin Date: Tue, 27 Aug 2024 01:03:45 +0000 Subject: [PATCH 16/52] tests for `Unpack` operation --- .../src/type_safety_tests/mod.rs | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs index 182ea3782c..82c66398d0 100644 --- a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs +++ b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs @@ -691,3 +691,41 @@ fn test_pack_too_few_args() { let fun_context = get_fun_context(&module); let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); } + + +#[test] +fn test_unpack_correct_types() { + let code = vec![ + Bytecode::LdU32(42), Bytecode::LdTrue, + Bytecode::Pack(StructDefinitionIndex(0)), + Bytecode::Unpack(StructDefinitionIndex(0)), + ]; + let mut module: CompiledModule = make_module(code); + add_simple_struct(&mut module); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); +} + +#[test] +fn test_unpack_wrong_type() { + let code = vec![Bytecode::LdU32(42), Bytecode::Unpack(StructDefinitionIndex(0))]; + let mut module: CompiledModule = make_module(code); + add_simple_struct(&mut module); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::UNPACK_TYPE_MISMATCH_ERROR + ); +} + +#[test] +#[should_panic] +fn test_unpack_no_arg() { + let code = vec![Bytecode::Unpack(StructDefinitionIndex(0))]; + let mut module: CompiledModule = make_module(code); + add_simple_struct(&mut module); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); +} From 248111e81b00c4165b8e53793f694d19b4c03bd7 Mon Sep 17 00:00:00 2001 From: Valerii Huhnin Date: Tue, 27 Aug 2024 02:11:07 +0000 Subject: [PATCH 17/52] add tests for `Eq` and `Neq` operations --- .../src/type_safety_tests/mod.rs | 112 ++++++++++++++++++ 1 file changed, 112 insertions(+) diff --git a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs index 82c66398d0..13c139e137 100644 --- a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs +++ b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs @@ -71,6 +71,29 @@ fn add_simple_struct(module: &mut CompiledModule) { module.struct_handles.push(struct_handle); } +fn add_simple_struct_with_abilities(module: &mut CompiledModule, abilities: AbilitySet) { + let struct_def = StructDefinition { + struct_handle: StructHandleIndex(0), + field_information: StructFieldInformation::Declared(vec![ + FieldDefinition { + name: IdentifierIndex(5), + signature: TypeSignature(SignatureToken::U32), + }, + ]), + }; + + let struct_handle = StructHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(0), + abilities: abilities, + type_parameters: vec![], + }; + + module.struct_defs.push(struct_def); + module.struct_handles.push(struct_handle); +} + + fn get_fun_context(module: &CompiledModule) -> FunctionContext { FunctionContext::new( &module, @@ -729,3 +752,92 @@ fn test_unpack_no_arg() { let fun_context = get_fun_context(&module); let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); } + + +#[test] +fn test_eq_neq_correct_types() { + for instr in vec![ + Bytecode::Eq, + Bytecode::Neq, + ] { + let code = vec![Bytecode::LdU32(42), Bytecode::LdU32(42), instr.clone()]; + let module = make_module(code); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); + + let code = vec![ + Bytecode::LdU32(42), + Bytecode::Pack(StructDefinitionIndex(0)), + Bytecode::LdU32(51), + Bytecode::Pack(StructDefinitionIndex(0)), + instr.clone() + ]; + let mut module = make_module(code); + add_simple_struct_with_abilities(&mut module, AbilitySet::PRIMITIVES); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); + } +} + +#[test] +fn test_eq_neq_mismatched_types() { + for instr in vec![ + Bytecode::Eq, + Bytecode::Neq, + ] { + let code = vec![Bytecode::LdU32(42), Bytecode::LdU64(42), instr.clone()]; + let module = make_module(code); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::EQUALITY_OP_TYPE_MISMATCH_ERROR + ); + } +} + +#[test] +fn test_eq_neq_no_drop() { + for instr in vec![ + Bytecode::Eq, + Bytecode::Neq, + ] { + let code = vec![ + Bytecode::LdU32(42), + Bytecode::Pack(StructDefinitionIndex(0)), + Bytecode::LdU32(51), + Bytecode::Pack(StructDefinitionIndex(0)), + instr.clone() + ]; + + let mut module = make_module(code); + add_simple_struct_with_abilities(&mut module, AbilitySet::EMPTY); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::EQUALITY_OP_TYPE_MISMATCH_ERROR + ); + } +} + +#[test] +#[should_panic] +fn test_eq_neq_too_few_args() { + for instr in vec![ + Bytecode::Eq, + Bytecode::Neq, + ] { + let code = vec![Bytecode::LdU32(42), instr.clone()]; + let module = make_module(code); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + + let code = vec![instr.clone()]; + let module = make_module(code); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + } +} From 1615c4993882ea2e0ea66aff48eeeeb328f3f98b Mon Sep 17 00:00:00 2001 From: Valerii Huhnin Date: Tue, 27 Aug 2024 02:17:56 +0000 Subject: [PATCH 18/52] split "too few args" and "no args" tests --- .../src/type_safety_tests/mod.rs | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs index 13c139e137..492c8dd326 100644 --- a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs +++ b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs @@ -343,7 +343,22 @@ fn test_arithmetic_too_few_args() { let module = make_module(code); let fun_context = get_fun_context(&module); let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + } +} +#[test] +#[should_panic] +fn test_arithmetic_no_args() { + for instr in vec![ + Bytecode::Add, + Bytecode::Sub, + Bytecode::Mul, + Bytecode::Mod, + Bytecode::Div, + Bytecode::BitOr, + Bytecode::BitAnd, + Bytecode::Xor, + ] { let code = vec![instr.clone()]; let module = make_module(code); let fun_context = get_fun_context(&module); @@ -421,6 +436,16 @@ fn test_shl_shr_too_few_args() { let fun_context = get_fun_context(&module); let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + } +} + +#[test] +#[should_panic] +fn test_shl_shr_no_args() { + for instr in vec![ + Bytecode::Shl, + Bytecode::Shr, + ] { let code = vec![instr.clone()]; let module = make_module(code); let fun_context = get_fun_context(&module); @@ -480,7 +505,16 @@ fn test_or_and_too_few_args() { let module = make_module(code); let fun_context = get_fun_context(&module); let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + } +} +#[test] +#[should_panic] +fn test_or_and_no_args() { + for instr in vec![ + Bytecode::Or, + Bytecode::And, + ] { let code = vec![instr.clone()]; let module = make_module(code); let fun_context = get_fun_context(&module); @@ -607,7 +641,18 @@ fn test_comparison_too_few_args() { let module = make_module(code); let fun_context = get_fun_context(&module); let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + } +} +#[test] +#[should_panic] +fn test_comparison_no_args() { + for instr in vec![ + Bytecode::Lt, + Bytecode::Gt, + Bytecode::Le, + Bytecode::Ge, + ] { let code = vec![instr.clone()]; let module = make_module(code); let fun_context = get_fun_context(&module); @@ -834,7 +879,16 @@ fn test_eq_neq_too_few_args() { let module = make_module(code); let fun_context = get_fun_context(&module); let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + } +} +#[test] +#[should_panic] +fn test_eq_neq_no_args() { + for instr in vec![ + Bytecode::Eq, + Bytecode::Neq, + ] { let code = vec![instr.clone()]; let module = make_module(code); let fun_context = get_fun_context(&module); From d4fd2eeb5d59608722582de8b53234440fd4e39d Mon Sep 17 00:00:00 2001 From: Valerii Huhnin Date: Tue, 27 Aug 2024 02:23:19 +0000 Subject: [PATCH 19/52] tests for the `Pop` operation --- .../src/type_safety_tests/mod.rs | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs index 492c8dd326..4aeca51224 100644 --- a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs +++ b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs @@ -895,3 +895,35 @@ fn test_eq_neq_no_args() { let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); } } + + +#[test] +fn test_pop_ok() { + let code = vec![Bytecode::LdU32(42), Bytecode::Pop]; + let module = make_module(code); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); +} + +#[test] +fn test_pop_no_drop() { + let code = vec![Bytecode::LdU32(42), Bytecode::Pack(StructDefinitionIndex(0)), Bytecode::Pop]; + let mut module = make_module(code); + add_simple_struct_with_abilities(&mut module, AbilitySet::EMPTY); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::POP_WITHOUT_DROP_ABILITY + ); +} + +#[test] +#[should_panic] +fn test_pop_no_arg() { + let code = vec![Bytecode::Pop]; + let module = make_module(code); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); +} From 11ad166d3042d7308964132448e0baf937ecce53 Mon Sep 17 00:00:00 2001 From: Valerii Huhnin Date: Tue, 27 Aug 2024 21:03:18 +0000 Subject: [PATCH 20/52] tests for `ImmBorrowLoc` and `MutBorrowLoc` instructions --- .../src/type_safety_tests/mod.rs | 70 ++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) diff --git a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs index 4aeca51224..d503ed7f53 100644 --- a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs +++ b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs @@ -9,7 +9,7 @@ use move_core_types::{ use move_binary_format::{ CompiledModule, file_format::{ - ConstantPoolIndex, Constant, SignatureToken, AbilitySet, StructHandle, TypeSignature, FieldDefinition, StructHandleIndex, StructFieldInformation, StructDefinition + ConstantPoolIndex, Constant, SignatureToken, AbilitySet, StructHandle, TypeSignature, FieldDefinition, StructHandleIndex, StructFieldInformation, StructDefinition, Signature }, }; @@ -45,6 +45,37 @@ fn make_module(code: Vec) -> CompiledModule { module } + +fn make_module_with_local(code: Vec, signature: SignatureToken) -> CompiledModule { + let code_unit = CodeUnit { + code, + locals: SignatureIndex(0), + }; + + let fun_def = FunctionDefinition { + code: Some(code_unit.clone()), + ..Default::default() + }; + + let fun_handle = FunctionHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(0), + parameters: SignatureIndex(0), + return_: SignatureIndex(0), + type_parameters: vec![], + }; + + let mut module = empty_module(); + module.function_handles.push(fun_handle); + module.function_defs.push(fun_def); + module.signatures = vec![ + Signature(vec![signature]), + ]; + + module +} + + fn add_simple_struct(module: &mut CompiledModule) { let struct_def = StructDefinition { struct_handle: StructHandleIndex(0), @@ -927,3 +958,40 @@ fn test_pop_no_arg() { let fun_context = get_fun_context(&module); let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); } + + +#[test] +fn test_borrow_loc_ok() { + for instr in vec![ + Bytecode::ImmBorrowLoc(1), + Bytecode::MutBorrowLoc(0), + ] { + let code = vec![instr]; + let module = make_module_with_local(code, SignatureToken::U64); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); + } +} + +#[test] +fn test_borrow_loc_reference() { + for instr in vec![ + Bytecode::ImmBorrowLoc(1), + Bytecode::MutBorrowLoc(0), + ] { + for reference in vec![ + SignatureToken::Reference(Box::new(SignatureToken::U64)), + SignatureToken::MutableReference(Box::new(SignatureToken::U32)), + ] { + let code = vec![instr.clone()]; + let module = make_module_with_local(code, reference.clone()); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::BORROWLOC_REFERENCE_ERROR + ); + } + } +} From e5550acac1ef3bf0bc72c6ae3038e349a441fefa Mon Sep 17 00:00:00 2001 From: Valerii Huhnin Date: Wed, 28 Aug 2024 14:52:44 +0000 Subject: [PATCH 21/52] tests for `CopyLoc` and `MoveLoc` instructions --- .../src/type_safety_tests/mod.rs | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs index d503ed7f53..6acb65c338 100644 --- a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs +++ b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs @@ -995,3 +995,36 @@ fn test_borrow_loc_reference() { } } } + + +#[test] +fn test_copy_loc_ok() { + let code = vec![Bytecode::CopyLoc(0)]; + let module = make_module_with_local(code, SignatureToken::U64); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); +} + +#[test] +fn test_copy_loc_no_copy() { + let code = vec![Bytecode::CopyLoc(0)]; + let mut module = make_module_with_local(code, SignatureToken::Struct(StructHandleIndex(0))); + add_simple_struct_with_abilities(&mut module, AbilitySet::EMPTY); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::COPYLOC_WITHOUT_COPY_ABILITY + ); +} + + +#[test] +fn test_move_loc_ok() { + let code = vec![Bytecode::MoveLoc(0)]; + let module = make_module_with_local(code, SignatureToken::U64); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); +} From ca491ed9bb5f84155ad354bf4fec3390a282c21f Mon Sep 17 00:00:00 2001 From: Valerii Huhnin Date: Wed, 28 Aug 2024 14:58:28 +0000 Subject: [PATCH 22/52] tests for `FreezeRef` operation --- .../src/type_safety_tests/mod.rs | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs index 6acb65c338..c5a207d033 100644 --- a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs +++ b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs @@ -1028,3 +1028,43 @@ fn test_move_loc_ok() { let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); assert!(result.is_ok()); } + + +#[test] +fn test_freeze_ref_correct_type() { + let code = vec![Bytecode::MutBorrowLoc(0), Bytecode::FreezeRef]; + let module = make_module_with_local(code, SignatureToken::U64); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); +} + +#[test] +fn test_freeze_ref_wrong_type() { + let code = vec![Bytecode::ImmBorrowLoc(0), Bytecode::FreezeRef]; + let module = make_module_with_local(code, SignatureToken::U64); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::FREEZEREF_TYPE_MISMATCH_ERROR + ); + + let code = vec![Bytecode::LdTrue, Bytecode::FreezeRef]; + let module = make_module_with_local(code, SignatureToken::U64); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::FREEZEREF_TYPE_MISMATCH_ERROR + ); +} + +#[test] +#[should_panic] +fn test_freeze_ref_no_arg() { + let code = vec![Bytecode::FreezeRef]; + let module = make_module_with_local(code, SignatureToken::U64); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); +} From f0190d7f76ea701e377c68cf0714ec17f3a89cab Mon Sep 17 00:00:00 2001 From: Valerii Huhnin Date: Wed, 28 Aug 2024 16:26:55 +0000 Subject: [PATCH 23/52] tests for `ReadRef` instruction --- .../src/type_safety_tests/mod.rs | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs index c5a207d033..16115c42e7 100644 --- a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs +++ b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs @@ -1068,3 +1068,57 @@ fn test_freeze_ref_no_arg() { let fun_context = get_fun_context(&module); let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); } + + +#[test] +fn test_read_ref_correct_type() { + for instr in vec![ + Bytecode::ImmBorrowLoc(0), + Bytecode::MutBorrowLoc(0), + ] { + let code = vec![instr, Bytecode::ReadRef]; + let module = make_module_with_local(code, SignatureToken::U64); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); + } +} + +#[test] +fn test_read_ref_wrong_type() { +let code = vec![Bytecode::LdU64(42), Bytecode::ReadRef]; + let module = make_module_with_local(code, SignatureToken::U64); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::READREF_TYPE_MISMATCH_ERROR + ); +} + +#[test] +fn test_read_ref_no_copy() { + for instr in vec![ + Bytecode::ImmBorrowLoc(0), + Bytecode::MutBorrowLoc(0), + ] { + let code = vec![instr, Bytecode::ReadRef]; + let mut module = make_module_with_local(code, SignatureToken::Struct(StructHandleIndex(0))); + add_simple_struct_with_abilities(&mut module, AbilitySet::EMPTY); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::READREF_WITHOUT_COPY_ABILITY + ); + } +} + +#[test] +#[should_panic] +fn test_read_ref_no_arg() { + let code = vec![Bytecode::ReadRef]; + let module = make_module_with_local(code, SignatureToken::U64); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); +} From 53afabab47f13b05481727db3329673d1b07e6b2 Mon Sep 17 00:00:00 2001 From: Valerii Huhnin Date: Wed, 28 Aug 2024 16:42:55 +0000 Subject: [PATCH 24/52] tests for `WriteRef` operation --- .../src/type_safety_tests/mod.rs | 83 +++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs index 16115c42e7..5b0590693d 100644 --- a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs +++ b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs @@ -1122,3 +1122,86 @@ fn test_read_ref_no_arg() { let fun_context = get_fun_context(&module); let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); } + + +#[test] +fn test_write_ref_correct_type() { + let code = vec![Bytecode::LdU64(42), Bytecode::MutBorrowLoc(0), Bytecode::WriteRef]; + let module = make_module_with_local(code, SignatureToken::U64); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); + + let code = vec![ + Bytecode::LdU32(42), + Bytecode::Pack(StructDefinitionIndex(0)), + Bytecode::MutBorrowLoc(0), + Bytecode::WriteRef + ]; + let mut module = make_module_with_local(code, SignatureToken::Struct(StructHandleIndex(0))); + add_simple_struct_with_abilities(&mut module, AbilitySet::PRIMITIVES); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); + +} + +#[test] +fn test_write_ref_wrong_type() { + let code = vec![Bytecode::LdU64(42), Bytecode::ImmBorrowLoc(0), Bytecode::WriteRef]; + let module = make_module_with_local(code, SignatureToken::U64); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::WRITEREF_NO_MUTABLE_REFERENCE_ERROR + ); +} + +#[test] +fn test_write_ref_mismatched_types() { + let code = vec![Bytecode::LdU32(42), Bytecode::MutBorrowLoc(0), Bytecode::WriteRef]; + let module = make_module_with_local(code, SignatureToken::U64); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::WRITEREF_TYPE_MISMATCH_ERROR + ); +} + +#[test] +fn test_write_ref_no_drop() { + let code = vec![ + Bytecode::LdU32(42), + Bytecode::Pack(StructDefinitionIndex(0)), + Bytecode::MutBorrowLoc(0), + Bytecode::WriteRef + ]; + let mut module = make_module_with_local(code, SignatureToken::Struct(StructHandleIndex(0))); + add_simple_struct_with_abilities(&mut module, AbilitySet::EMPTY); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::WRITEREF_WITHOUT_DROP_ABILITY + ); +} + +#[test] +#[should_panic] +fn test_write_ref_too_few_args() { + let code = vec![Bytecode::MutBorrowLoc(0), Bytecode::WriteRef]; + let module = make_module_with_local(code, SignatureToken::U32); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); +} + +#[test] +#[should_panic] +fn test_write_ref_no_args() { + let code = vec![Bytecode::WriteRef]; + let module = make_module_with_local(code, SignatureToken::U64); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); +} From 5da187d5ed1876e1e6a1ac100300c75b0c99f32e Mon Sep 17 00:00:00 2001 From: Valerii Huhnin Date: Wed, 28 Aug 2024 16:48:44 +0000 Subject: [PATCH 25/52] tests for `StLoc` instruction --- .../src/type_safety_tests/mod.rs | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs index 5b0590693d..41f1063a0d 100644 --- a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs +++ b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs @@ -997,6 +997,37 @@ fn test_borrow_loc_reference() { } +#[test] +fn test_st_lock_correct_type() { + let code = vec![Bytecode::LdU32(51), Bytecode::StLoc(0)]; + let module = make_module_with_local(code, SignatureToken::U32); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); +} + +#[test] +fn test_st_lock_mismatched_types() { + let code = vec![Bytecode::LdU64(51), Bytecode::StLoc(0)]; + let module = make_module_with_local(code, SignatureToken::U32); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::STLOC_TYPE_MISMATCH_ERROR + ); +} + +#[test] +#[should_panic] +fn test_st_lock_no_arg() { + let code = vec![Bytecode::StLoc(0)]; + let module = make_module_with_local(code, SignatureToken::U32); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); +} + + #[test] fn test_copy_loc_ok() { let code = vec![Bytecode::CopyLoc(0)]; From a6600848f41a52de01dc76a675efc6369a49783f Mon Sep 17 00:00:00 2001 From: Valerii Huhnin Date: Thu, 29 Aug 2024 05:12:19 +0000 Subject: [PATCH 26/52] tests for `ImmBorrowField` operation --- .../src/type_safety_tests/mod.rs | 99 ++++++++++++++++++- 1 file changed, 98 insertions(+), 1 deletion(-) diff --git a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs index 41f1063a0d..f46d0ece3f 100644 --- a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs +++ b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs @@ -9,7 +9,7 @@ use move_core_types::{ use move_binary_format::{ CompiledModule, file_format::{ - ConstantPoolIndex, Constant, SignatureToken, AbilitySet, StructHandle, TypeSignature, FieldDefinition, StructHandleIndex, StructFieldInformation, StructDefinition, Signature + ConstantPoolIndex, Constant, SignatureToken, AbilitySet, StructHandle, TypeSignature, FieldDefinition, StructHandleIndex, StructFieldInformation, StructDefinition, Signature, FieldHandleIndex, FieldHandle }, }; @@ -76,6 +76,30 @@ fn make_module_with_local(code: Vec, signature: SignatureToken) -> Com } +fn add_native_struct(module: &mut CompiledModule) { + let struct_def = StructDefinition { + struct_handle: StructHandleIndex(0), + field_information: StructFieldInformation::Native, + }; + + let struct_handle = StructHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(0), + abilities: AbilitySet::EMPTY, + type_parameters: vec![], + }; + + module.struct_defs.push(struct_def); + module.struct_handles.push(struct_handle); + + module.field_handles = vec![ + FieldHandle { + owner: StructDefinitionIndex(0), + field: 0, + }, + ]; +} + fn add_simple_struct(module: &mut CompiledModule) { let struct_def = StructDefinition { struct_handle: StructHandleIndex(0), @@ -100,8 +124,20 @@ fn add_simple_struct(module: &mut CompiledModule) { module.struct_defs.push(struct_def); module.struct_handles.push(struct_handle); + + module.field_handles = vec![ + FieldHandle { + owner: StructDefinitionIndex(0), + field: 0, + }, + FieldHandle { + owner: StructDefinitionIndex(0), + field: 1, + } + ]; } + fn add_simple_struct_with_abilities(module: &mut CompiledModule, abilities: AbilitySet) { let struct_def = StructDefinition { struct_handle: StructHandleIndex(0), @@ -1236,3 +1272,64 @@ fn test_write_ref_no_args() { let fun_context = get_fun_context(&module); let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); } + + +#[test] +fn test_imm_borrow_field_correct_type() { + let code = vec![Bytecode::ImmBorrowLoc(0), Bytecode::ImmBorrowField(FieldHandleIndex(0))]; + let mut module = make_module_with_local(code, SignatureToken::Struct(StructHandleIndex(0))); + add_simple_struct(&mut module); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); +} + +#[test] +fn test_imm_borrow_field_wrong_type() { + let code = vec![Bytecode::LdTrue, Bytecode::ImmBorrowField(FieldHandleIndex(0))]; + let mut module = make_module_with_local(code, SignatureToken::Struct(StructHandleIndex(0))); + add_simple_struct(&mut module); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::BORROWFIELD_TYPE_MISMATCH_ERROR + ); +} + +#[test] +fn test_imm_borrow_field_mismatched_types() { + let code = vec![Bytecode::ImmBorrowLoc(0), Bytecode::ImmBorrowField(FieldHandleIndex(0))]; + let mut module = make_module_with_local(code, SignatureToken::U64); + add_simple_struct(&mut module); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::BORROWFIELD_TYPE_MISMATCH_ERROR + ); +} + +#[test] +fn test_imm_borrow_field_bad_field() { + let code = vec![Bytecode::ImmBorrowLoc(0), Bytecode::ImmBorrowField(FieldHandleIndex(0))]; + let mut module = make_module_with_local(code, SignatureToken::Struct(StructHandleIndex(0))); + add_native_struct(&mut module); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::BORROWFIELD_BAD_FIELD_ERROR + ); +} + +#[test] +#[should_panic] +fn test_imm_borrow_field_no_arg() { + let code = vec![Bytecode::ImmBorrowField(FieldHandleIndex(0))]; + let mut module = make_module_with_local(code, SignatureToken::Struct(StructHandleIndex(0))); + add_simple_struct(&mut module); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); +} + From f438c4a81eb7a85ab0c58deb33b0721922ec9750 Mon Sep 17 00:00:00 2001 From: Valerii Huhnin Date: Thu, 29 Aug 2024 05:12:36 +0000 Subject: [PATCH 27/52] tests for `MutBorrowField` operation --- .../src/type_safety_tests/mod.rs | 72 ++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) diff --git a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs index f46d0ece3f..23804bc9fc 100644 --- a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs +++ b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs @@ -121,7 +121,7 @@ fn add_simple_struct(module: &mut CompiledModule) { abilities: AbilitySet::EMPTY, type_parameters: vec![], }; - + module.struct_defs.push(struct_def); module.struct_handles.push(struct_handle); @@ -1333,3 +1333,73 @@ fn test_imm_borrow_field_no_arg() { let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); } + +#[test] +fn test_mut_borrow_field_correct_type() { + let code = vec![Bytecode::MutBorrowLoc(0), Bytecode::MutBorrowField(FieldHandleIndex(0))]; + let mut module = make_module_with_local(code, SignatureToken::Struct(StructHandleIndex(0))); + add_simple_struct(&mut module); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); +} + +#[test] +fn test_mut_borrow_field_wrong_type() { + let code = vec![Bytecode::LdTrue, Bytecode::MutBorrowField(FieldHandleIndex(0))]; + let mut module = make_module_with_local(code, SignatureToken::Struct(StructHandleIndex(0))); + add_simple_struct(&mut module); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::BORROWFIELD_TYPE_MISMATCH_ERROR + ); + + let code = vec![Bytecode::ImmBorrowLoc(0), Bytecode::MutBorrowField(FieldHandleIndex(0))]; + let mut module = make_module_with_local(code, SignatureToken::Struct(StructHandleIndex(0))); + add_simple_struct(&mut module); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::BORROWFIELD_TYPE_MISMATCH_ERROR + ); + +} + +#[test] +fn test_mut_borrow_field_mismatched_types() { + let code = vec![Bytecode::MutBorrowLoc(0), Bytecode::MutBorrowField(FieldHandleIndex(0))]; + let mut module = make_module_with_local(code, SignatureToken::U64); + add_simple_struct(&mut module); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::BORROWFIELD_TYPE_MISMATCH_ERROR + ); +} + +#[test] +fn test_mut_borrow_field_bad_field() { + let code = vec![Bytecode::MutBorrowLoc(0), Bytecode::MutBorrowField(FieldHandleIndex(0))]; + let mut module = make_module_with_local(code, SignatureToken::Struct(StructHandleIndex(0))); + add_native_struct(&mut module); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::BORROWFIELD_BAD_FIELD_ERROR + ); +} + +#[test] +#[should_panic] +fn test_mut_borrow_field_no_arg() { + let code = vec![Bytecode::MutBorrowField(FieldHandleIndex(0))]; + let mut module = make_module_with_local(code, SignatureToken::Struct(StructHandleIndex(0))); + add_simple_struct(&mut module); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); +} From 61df51d20717f6b6cc539994388ba9e46e5a44e4 Mon Sep 17 00:00:00 2001 From: Valerii Huhnin Date: Fri, 30 Aug 2024 05:48:41 +0000 Subject: [PATCH 28/52] tests for `Ret` instruction --- .../src/type_safety_tests/mod.rs | 43 ++++++++++++++++++- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs index 23804bc9fc..8b484fbb58 100644 --- a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs +++ b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs @@ -20,6 +20,10 @@ use crate::type_safety; fn make_module(code: Vec) -> CompiledModule { + make_module_with_ret(code, SignatureToken::U32) +} + +fn make_module_with_ret(code: Vec, return_: SignatureToken) -> CompiledModule { let code_unit = CodeUnit { code, ..Default::default() @@ -34,18 +38,21 @@ fn make_module(code: Vec) -> CompiledModule { module: ModuleHandleIndex(0), name: IdentifierIndex(0), parameters: SignatureIndex(0), - return_: SignatureIndex(0), + return_: SignatureIndex(1), type_parameters: vec![], }; let mut module = empty_module(); module.function_handles.push(fun_handle); module.function_defs.push(fun_def); + module.signatures = vec![ + Signature(vec![]), + Signature(vec![return_]), + ]; module } - fn make_module_with_local(code: Vec, signature: SignatureToken) -> CompiledModule { let code_unit = CodeUnit { code, @@ -1403,3 +1410,35 @@ fn test_mut_borrow_field_no_arg() { let fun_context = get_fun_context(&module); let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); } + + +#[test] +fn test_ret_correct_type() { + let code = vec![Bytecode::LdU32(42), Bytecode::Ret]; + let module = make_module_with_ret(code, SignatureToken::U32); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); +} + +#[test] +fn test_ret_wrong_type() { + let code = vec![Bytecode::LdU64(42), Bytecode::Ret]; + let module = make_module_with_ret(code, SignatureToken::U32); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::RET_TYPE_MISMATCH_ERROR + ); +} + +#[test] +#[should_panic] +fn test_ret_no_arg() { + let code = vec![Bytecode::Ret]; + let module = make_module_with_ret(code, SignatureToken::U32); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); +} + From 449b1ae0f2e7bca7a364c68c51058f5a987ec218 Mon Sep 17 00:00:00 2001 From: Valerii Huhnin Date: Fri, 30 Aug 2024 05:49:16 +0000 Subject: [PATCH 29/52] tests for `Call` instruction --- .../src/type_safety_tests/mod.rs | 58 ++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs index 8b484fbb58..72d1a79fbf 100644 --- a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs +++ b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs @@ -9,7 +9,7 @@ use move_core_types::{ use move_binary_format::{ CompiledModule, file_format::{ - ConstantPoolIndex, Constant, SignatureToken, AbilitySet, StructHandle, TypeSignature, FieldDefinition, StructHandleIndex, StructFieldInformation, StructDefinition, Signature, FieldHandleIndex, FieldHandle + ConstantPoolIndex, Constant, SignatureToken, AbilitySet, StructHandle, TypeSignature, FieldDefinition, StructHandleIndex, StructFieldInformation, StructDefinition, Signature, FieldHandleIndex, FieldHandle, FunctionHandleIndex }, }; @@ -82,6 +82,26 @@ fn make_module_with_local(code: Vec, signature: SignatureToken) -> Com module } +fn add_function_with_parameters(module: &mut CompiledModule, parameters: Signature) { + let fun_def = FunctionDefinition { + code: None, + ..Default::default() + }; + + let fun_handle = FunctionHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(0), + parameters: SignatureIndex(2), + return_: SignatureIndex(3), + type_parameters: vec![], + }; + + module.signatures.push(parameters); + module.signatures.push(Signature(vec![])); + + module.function_handles.push(fun_handle); + module.function_defs.push(fun_def); +} fn add_native_struct(module: &mut CompiledModule) { let struct_def = StructDefinition { @@ -1442,3 +1462,39 @@ fn test_ret_no_arg() { let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); } + +#[test] +fn test_call_correct_types() { + let code = vec![Bytecode::LdU64(42), Bytecode::LdTrue, Bytecode::Call(FunctionHandleIndex(1))]; + let parameters = Signature(vec![SignatureToken::U64, SignatureToken::Bool]); + let mut module = make_module(code); + add_function_with_parameters(&mut module, parameters); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); +} + +#[test] +fn test_call_wrong_types() { + let code = vec![Bytecode::LdTrue, Bytecode::LdU64(42), Bytecode::Call(FunctionHandleIndex(1))]; + let parameters = Signature(vec![SignatureToken::U64, SignatureToken::Bool]); + let mut module = make_module(code); + add_function_with_parameters(&mut module, parameters); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::CALL_TYPE_MISMATCH_ERROR + ); +} + +#[test] +#[should_panic] +fn test_call_too_few_args() { + let code = vec![Bytecode::LdTrue, Bytecode::Call(FunctionHandleIndex(1))]; + let parameters = Signature(vec![SignatureToken::U64, SignatureToken::Bool]); + let mut module = make_module(code); + add_function_with_parameters(&mut module, parameters); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); +} From 674d1d10f709254c5c24c664f817b8ba8c65634c Mon Sep 17 00:00:00 2001 From: Valerii Huhnin Date: Fri, 30 Aug 2024 05:50:22 +0000 Subject: [PATCH 30/52] `cargo fmt` --- .../src/type_safety_tests/mod.rs | 342 +++++++----------- 1 file changed, 136 insertions(+), 206 deletions(-) diff --git a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs index 72d1a79fbf..22ffe3c48a 100644 --- a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs +++ b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs @@ -1,23 +1,23 @@ use move_binary_format::file_format::{ - empty_module, Bytecode, CodeUnit, FunctionDefinition, FunctionDefinitionIndex, FunctionHandle, IdentifierIndex, ModuleHandleIndex, SignatureIndex, StructDefinitionIndex + empty_module, Bytecode, CodeUnit, FunctionDefinition, FunctionDefinitionIndex, FunctionHandle, + IdentifierIndex, ModuleHandleIndex, SignatureIndex, StructDefinitionIndex, }; -use move_core_types::{ - u256::U256, vm_status::StatusCode, -}; +use move_core_types::{u256::U256, vm_status::StatusCode}; use move_binary_format::{ - CompiledModule, file_format::{ - ConstantPoolIndex, Constant, SignatureToken, AbilitySet, StructHandle, TypeSignature, FieldDefinition, StructHandleIndex, StructFieldInformation, StructDefinition, Signature, FieldHandleIndex, FieldHandle, FunctionHandleIndex + AbilitySet, Constant, ConstantPoolIndex, FieldDefinition, FieldHandle, FieldHandleIndex, + FunctionHandleIndex, Signature, SignatureToken, StructDefinition, StructFieldInformation, + StructHandle, StructHandleIndex, TypeSignature, }, + CompiledModule, }; -use move_bytecode_verifier_meter::dummy::DummyMeter; use crate::absint::FunctionContext; use crate::constants; use crate::type_safety; - +use move_bytecode_verifier_meter::dummy::DummyMeter; fn make_module(code: Vec) -> CompiledModule { make_module_with_ret(code, SignatureToken::U32) @@ -45,10 +45,7 @@ fn make_module_with_ret(code: Vec, return_: SignatureToken) -> Compile let mut module = empty_module(); module.function_handles.push(fun_handle); module.function_defs.push(fun_def); - module.signatures = vec![ - Signature(vec![]), - Signature(vec![return_]), - ]; + module.signatures = vec![Signature(vec![]), Signature(vec![return_])]; module } @@ -75,9 +72,7 @@ fn make_module_with_local(code: Vec, signature: SignatureToken) -> Com let mut module = empty_module(); module.function_handles.push(fun_handle); module.function_defs.push(fun_def); - module.signatures = vec![ - Signature(vec![signature]), - ]; + module.signatures = vec![Signature(vec![signature])]; module } @@ -119,12 +114,10 @@ fn add_native_struct(module: &mut CompiledModule) { module.struct_defs.push(struct_def); module.struct_handles.push(struct_handle); - module.field_handles = vec![ - FieldHandle { - owner: StructDefinitionIndex(0), - field: 0, - }, - ]; + module.field_handles = vec![FieldHandle { + owner: StructDefinitionIndex(0), + field: 0, + }]; } fn add_simple_struct(module: &mut CompiledModule) { @@ -148,7 +141,7 @@ fn add_simple_struct(module: &mut CompiledModule) { abilities: AbilitySet::EMPTY, type_parameters: vec![], }; - + module.struct_defs.push(struct_def); module.struct_handles.push(struct_handle); @@ -160,20 +153,17 @@ fn add_simple_struct(module: &mut CompiledModule) { FieldHandle { owner: StructDefinitionIndex(0), field: 1, - } + }, ]; } - fn add_simple_struct_with_abilities(module: &mut CompiledModule, abilities: AbilitySet) { let struct_def = StructDefinition { struct_handle: StructHandleIndex(0), - field_information: StructFieldInformation::Declared(vec![ - FieldDefinition { - name: IdentifierIndex(5), - signature: TypeSignature(SignatureToken::U32), - }, - ]), + field_information: StructFieldInformation::Declared(vec![FieldDefinition { + name: IdentifierIndex(5), + signature: TypeSignature(SignatureToken::U32), + }]), }; let struct_handle = StructHandle { @@ -187,23 +177,18 @@ fn add_simple_struct_with_abilities(module: &mut CompiledModule, abilities: Abil module.struct_handles.push(struct_handle); } - fn get_fun_context(module: &CompiledModule) -> FunctionContext { FunctionContext::new( &module, - FunctionDefinitionIndex(0), + FunctionDefinitionIndex(0), module.function_defs[0].code.as_ref().unwrap(), &module.function_handles[0], ) } - #[test] fn test_br_true_false_correct_type() { - for instr in vec![ - Bytecode::BrTrue(0), - Bytecode::BrFalse(0), - ] { + for instr in vec![Bytecode::BrTrue(0), Bytecode::BrFalse(0)] { let code = vec![Bytecode::LdTrue, instr]; let module = make_module(code); let fun_context = get_fun_context(&module); @@ -214,10 +199,7 @@ fn test_br_true_false_correct_type() { #[test] fn test_br_true_false_wrong_type() { - for instr in vec![ - Bytecode::BrTrue(0), - Bytecode::BrFalse(0), - ] { + for instr in vec![Bytecode::BrTrue(0), Bytecode::BrFalse(0)] { let code = vec![Bytecode::LdU32(0), instr]; let module = make_module(code); let fun_context = get_fun_context(&module); @@ -232,10 +214,7 @@ fn test_br_true_false_wrong_type() { #[test] #[should_panic] fn test_br_true_false_no_arg() { - for instr in vec![ - Bytecode::BrTrue(0), - Bytecode::BrFalse(0), - ] { + for instr in vec![Bytecode::BrTrue(0), Bytecode::BrFalse(0)] { let code = vec![instr]; let module = make_module(code); let fun_context = get_fun_context(&module); @@ -243,7 +222,6 @@ fn test_br_true_false_no_arg() { } } - #[test] fn test_abort_correct_type() { let code = vec![Bytecode::LdU64(0), Bytecode::Abort]; @@ -253,7 +231,6 @@ fn test_abort_correct_type() { assert!(result.is_ok()); } - #[test] fn test_abort_wrong_type() { let code = vec![Bytecode::LdU32(0), Bytecode::Abort]; @@ -275,7 +252,6 @@ fn test_abort_no_arg() { let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); } - #[test] fn test_cast_correct_type() { for instr in vec![ @@ -333,8 +309,6 @@ fn test_cast_no_arg() { } } - - #[test] fn test_arithmetic_correct_types() { for instr in vec![ @@ -419,7 +393,6 @@ fn test_arithmetic_wrong_type() { } } - #[test] #[should_panic] fn test_arithmetic_too_few_args() { @@ -460,13 +433,9 @@ fn test_arithmetic_no_args() { } } - #[test] fn test_shl_shr_correct_types() { - for instr in vec![ - Bytecode::Shl, - Bytecode::Shr, - ] { + for instr in vec![Bytecode::Shl, Bytecode::Shr] { for push_ty_instr in vec![ Bytecode::LdU8(42), Bytecode::LdU16(257), @@ -486,10 +455,7 @@ fn test_shl_shr_correct_types() { #[test] fn test_shl_shr_first_operand_wrong_type() { - for instr in vec![ - Bytecode::Shl, - Bytecode::Shr, - ] { + for instr in vec![Bytecode::Shl, Bytecode::Shr] { let code = vec![Bytecode::LdTrue, Bytecode::LdU8(2), instr.clone()]; let module = make_module(code); let fun_context = get_fun_context(&module); @@ -503,10 +469,7 @@ fn test_shl_shr_first_operand_wrong_type() { #[test] fn test_shl_shr_second_operand_wrong_type() { - for instr in vec![ - Bytecode::Shl, - Bytecode::Shr, - ] { + for instr in vec![Bytecode::Shl, Bytecode::Shr] { let code = vec![Bytecode::LdU32(42), Bytecode::LdU16(2), instr.clone()]; let module = make_module(code); let fun_context = get_fun_context(&module); @@ -521,25 +484,18 @@ fn test_shl_shr_second_operand_wrong_type() { #[test] #[should_panic] fn test_shl_shr_too_few_args() { - for instr in vec![ - Bytecode::Shl, - Bytecode::Shr, - ] { + for instr in vec![Bytecode::Shl, Bytecode::Shr] { let code = vec![Bytecode::LdU16(42), instr.clone()]; let module = make_module(code); let fun_context = get_fun_context(&module); let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); - } } #[test] #[should_panic] fn test_shl_shr_no_args() { - for instr in vec![ - Bytecode::Shl, - Bytecode::Shr, - ] { + for instr in vec![Bytecode::Shl, Bytecode::Shr] { let code = vec![instr.clone()]; let module = make_module(code); let fun_context = get_fun_context(&module); @@ -547,13 +503,9 @@ fn test_shl_shr_no_args() { } } - #[test] fn test_or_and_correct_types() { - for instr in vec![ - Bytecode::Or, - Bytecode::And, - ] { + for instr in vec![Bytecode::Or, Bytecode::And] { let code = vec![Bytecode::LdFalse, Bytecode::LdTrue, instr.clone()]; let module = make_module(code); let fun_context = get_fun_context(&module); @@ -564,10 +516,7 @@ fn test_or_and_correct_types() { #[test] fn test_or_and_wrong_types() { - for instr in vec![ - Bytecode::Or, - Bytecode::And, - ] { + for instr in vec![Bytecode::Or, Bytecode::And] { let code = vec![Bytecode::LdU32(42), Bytecode::LdTrue, instr.clone()]; let module = make_module(code); let fun_context = get_fun_context(&module); @@ -591,10 +540,7 @@ fn test_or_and_wrong_types() { #[test] #[should_panic] fn test_or_and_too_few_args() { - for instr in vec![ - Bytecode::Or, - Bytecode::And, - ] { + for instr in vec![Bytecode::Or, Bytecode::And] { let code = vec![Bytecode::LdTrue, instr.clone()]; let module = make_module(code); let fun_context = get_fun_context(&module); @@ -605,10 +551,7 @@ fn test_or_and_too_few_args() { #[test] #[should_panic] fn test_or_and_no_args() { - for instr in vec![ - Bytecode::Or, - Bytecode::And, - ] { + for instr in vec![Bytecode::Or, Bytecode::And] { let code = vec![instr.clone()]; let module = make_module(code); let fun_context = get_fun_context(&module); @@ -616,7 +559,6 @@ fn test_or_and_no_args() { } } - #[test] fn test_not_correct_type() { let code = vec![Bytecode::LdFalse, Bytecode::Not]; @@ -647,7 +589,6 @@ fn test_not_no_arg() { let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); } - #[test] fn test_comparison_correct_types() { for instr in vec![ @@ -677,12 +618,7 @@ fn test_comparison_correct_types() { #[test] fn test_comparison_mismatched_types() { - for instr in vec![ - Bytecode::Lt, - Bytecode::Gt, - Bytecode::Le, - Bytecode::Ge, - ] { + for instr in vec![Bytecode::Lt, Bytecode::Gt, Bytecode::Le, Bytecode::Ge] { let code = vec![Bytecode::LdU8(42), Bytecode::LdU64(94), instr.clone()]; let module = make_module(code); let fun_context = get_fun_context(&module); @@ -696,12 +632,7 @@ fn test_comparison_mismatched_types() { #[test] fn test_comparison_wrong_type() { - for instr in vec![ - Bytecode::Lt, - Bytecode::Gt, - Bytecode::Le, - Bytecode::Ge, - ] { + for instr in vec![Bytecode::Lt, Bytecode::Gt, Bytecode::Le, Bytecode::Ge] { let code = vec![Bytecode::LdTrue, Bytecode::LdU64(94), instr.clone()]; let module = make_module(code); let fun_context = get_fun_context(&module); @@ -725,12 +656,7 @@ fn test_comparison_wrong_type() { #[test] #[should_panic] fn test_comparison_too_few_args() { - for instr in vec![ - Bytecode::Lt, - Bytecode::Gt, - Bytecode::Le, - Bytecode::Ge, - ] { + for instr in vec![Bytecode::Lt, Bytecode::Gt, Bytecode::Le, Bytecode::Ge] { let code = vec![Bytecode::LdU16(42), instr.clone()]; let module = make_module(code); let fun_context = get_fun_context(&module); @@ -741,12 +667,7 @@ fn test_comparison_too_few_args() { #[test] #[should_panic] fn test_comparison_no_args() { - for instr in vec![ - Bytecode::Lt, - Bytecode::Gt, - Bytecode::Le, - Bytecode::Ge, - ] { + for instr in vec![Bytecode::Lt, Bytecode::Gt, Bytecode::Le, Bytecode::Ge] { let code = vec![instr.clone()]; let module = make_module(code); let fun_context = get_fun_context(&module); @@ -754,14 +675,10 @@ fn test_comparison_no_args() { } } - // these operation does not produce errors in verify_instr() #[test] fn test_branch_nop_ok() { - for instr in vec![ - Bytecode::Branch(0), - Bytecode::Nop, - ] { + for instr in vec![Bytecode::Branch(0), Bytecode::Nop] { let code = vec![instr]; let module = make_module(code); let fun_context = get_fun_context(&module); @@ -770,7 +687,6 @@ fn test_branch_nop_ok() { } } - #[test] fn test_ld_integers_ok() { for instr in vec![ @@ -789,13 +705,9 @@ fn test_ld_integers_ok() { } } - #[test] fn test_ld_true_false_ok() { - for instr in vec![ - Bytecode::LdTrue, - Bytecode::LdFalse, - ] { + for instr in vec![Bytecode::LdTrue, Bytecode::LdFalse] { let code = vec![instr]; let module = make_module(code); let fun_context = get_fun_context(&module); @@ -804,7 +716,6 @@ fn test_ld_true_false_ok() { } } - #[test] fn test_ld_const_ok() { let code = vec![Bytecode::LdConst(ConstantPoolIndex(0))]; @@ -820,10 +731,13 @@ fn test_ld_const_ok() { assert!(result.is_ok()); } - #[test] fn test_pack_correct_types() { - let code = vec![Bytecode::LdU32(42), Bytecode::LdTrue, Bytecode::Pack(StructDefinitionIndex(0))]; + let code = vec![ + Bytecode::LdU32(42), + Bytecode::LdTrue, + Bytecode::Pack(StructDefinitionIndex(0)), + ]; let mut module: CompiledModule = make_module(code); add_simple_struct(&mut module); let fun_context = get_fun_context(&module); @@ -833,7 +747,11 @@ fn test_pack_correct_types() { #[test] fn test_pack_mismatched_types() { - let code = vec![Bytecode::LdTrue, Bytecode::LdU32(42), Bytecode::Pack(StructDefinitionIndex(0))]; + let code = vec![ + Bytecode::LdTrue, + Bytecode::LdU32(42), + Bytecode::Pack(StructDefinitionIndex(0)), + ]; let mut module: CompiledModule = make_module(code); add_simple_struct(&mut module); let fun_context = get_fun_context(&module); @@ -854,11 +772,11 @@ fn test_pack_too_few_args() { let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); } - #[test] fn test_unpack_correct_types() { let code = vec![ - Bytecode::LdU32(42), Bytecode::LdTrue, + Bytecode::LdU32(42), + Bytecode::LdTrue, Bytecode::Pack(StructDefinitionIndex(0)), Bytecode::Unpack(StructDefinitionIndex(0)), ]; @@ -871,7 +789,10 @@ fn test_unpack_correct_types() { #[test] fn test_unpack_wrong_type() { - let code = vec![Bytecode::LdU32(42), Bytecode::Unpack(StructDefinitionIndex(0))]; + let code = vec![ + Bytecode::LdU32(42), + Bytecode::Unpack(StructDefinitionIndex(0)), + ]; let mut module: CompiledModule = make_module(code); add_simple_struct(&mut module); let fun_context = get_fun_context(&module); @@ -892,13 +813,9 @@ fn test_unpack_no_arg() { let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); } - #[test] fn test_eq_neq_correct_types() { - for instr in vec![ - Bytecode::Eq, - Bytecode::Neq, - ] { + for instr in vec![Bytecode::Eq, Bytecode::Neq] { let code = vec![Bytecode::LdU32(42), Bytecode::LdU32(42), instr.clone()]; let module = make_module(code); let fun_context = get_fun_context(&module); @@ -910,7 +827,7 @@ fn test_eq_neq_correct_types() { Bytecode::Pack(StructDefinitionIndex(0)), Bytecode::LdU32(51), Bytecode::Pack(StructDefinitionIndex(0)), - instr.clone() + instr.clone(), ]; let mut module = make_module(code); add_simple_struct_with_abilities(&mut module, AbilitySet::PRIMITIVES); @@ -922,10 +839,7 @@ fn test_eq_neq_correct_types() { #[test] fn test_eq_neq_mismatched_types() { - for instr in vec![ - Bytecode::Eq, - Bytecode::Neq, - ] { + for instr in vec![Bytecode::Eq, Bytecode::Neq] { let code = vec![Bytecode::LdU32(42), Bytecode::LdU64(42), instr.clone()]; let module = make_module(code); let fun_context = get_fun_context(&module); @@ -937,18 +851,15 @@ fn test_eq_neq_mismatched_types() { } } -#[test] +#[test] fn test_eq_neq_no_drop() { - for instr in vec![ - Bytecode::Eq, - Bytecode::Neq, - ] { + for instr in vec![Bytecode::Eq, Bytecode::Neq] { let code = vec![ Bytecode::LdU32(42), Bytecode::Pack(StructDefinitionIndex(0)), Bytecode::LdU32(51), Bytecode::Pack(StructDefinitionIndex(0)), - instr.clone() + instr.clone(), ]; let mut module = make_module(code); @@ -965,10 +876,7 @@ fn test_eq_neq_no_drop() { #[test] #[should_panic] fn test_eq_neq_too_few_args() { - for instr in vec![ - Bytecode::Eq, - Bytecode::Neq, - ] { + for instr in vec![Bytecode::Eq, Bytecode::Neq] { let code = vec![Bytecode::LdU32(42), instr.clone()]; let module = make_module(code); let fun_context = get_fun_context(&module); @@ -979,10 +887,7 @@ fn test_eq_neq_too_few_args() { #[test] #[should_panic] fn test_eq_neq_no_args() { - for instr in vec![ - Bytecode::Eq, - Bytecode::Neq, - ] { + for instr in vec![Bytecode::Eq, Bytecode::Neq] { let code = vec![instr.clone()]; let module = make_module(code); let fun_context = get_fun_context(&module); @@ -990,7 +895,6 @@ fn test_eq_neq_no_args() { } } - #[test] fn test_pop_ok() { let code = vec![Bytecode::LdU32(42), Bytecode::Pop]; @@ -1002,7 +906,11 @@ fn test_pop_ok() { #[test] fn test_pop_no_drop() { - let code = vec![Bytecode::LdU32(42), Bytecode::Pack(StructDefinitionIndex(0)), Bytecode::Pop]; + let code = vec![ + Bytecode::LdU32(42), + Bytecode::Pack(StructDefinitionIndex(0)), + Bytecode::Pop, + ]; let mut module = make_module(code); add_simple_struct_with_abilities(&mut module, AbilitySet::EMPTY); let fun_context = get_fun_context(&module); @@ -1022,13 +930,9 @@ fn test_pop_no_arg() { let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); } - #[test] fn test_borrow_loc_ok() { - for instr in vec![ - Bytecode::ImmBorrowLoc(1), - Bytecode::MutBorrowLoc(0), - ] { + for instr in vec![Bytecode::ImmBorrowLoc(1), Bytecode::MutBorrowLoc(0)] { let code = vec![instr]; let module = make_module_with_local(code, SignatureToken::U64); let fun_context = get_fun_context(&module); @@ -1039,10 +943,7 @@ fn test_borrow_loc_ok() { #[test] fn test_borrow_loc_reference() { - for instr in vec![ - Bytecode::ImmBorrowLoc(1), - Bytecode::MutBorrowLoc(0), - ] { + for instr in vec![Bytecode::ImmBorrowLoc(1), Bytecode::MutBorrowLoc(0)] { for reference in vec![ SignatureToken::Reference(Box::new(SignatureToken::U64)), SignatureToken::MutableReference(Box::new(SignatureToken::U32)), @@ -1059,7 +960,6 @@ fn test_borrow_loc_reference() { } } - #[test] fn test_st_lock_correct_type() { let code = vec![Bytecode::LdU32(51), Bytecode::StLoc(0)]; @@ -1090,7 +990,6 @@ fn test_st_lock_no_arg() { let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); } - #[test] fn test_copy_loc_ok() { let code = vec![Bytecode::CopyLoc(0)]; @@ -1113,7 +1012,6 @@ fn test_copy_loc_no_copy() { ); } - #[test] fn test_move_loc_ok() { let code = vec![Bytecode::MoveLoc(0)]; @@ -1123,7 +1021,6 @@ fn test_move_loc_ok() { assert!(result.is_ok()); } - #[test] fn test_freeze_ref_correct_type() { let code = vec![Bytecode::MutBorrowLoc(0), Bytecode::FreezeRef]; @@ -1163,13 +1060,9 @@ fn test_freeze_ref_no_arg() { let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); } - #[test] fn test_read_ref_correct_type() { - for instr in vec![ - Bytecode::ImmBorrowLoc(0), - Bytecode::MutBorrowLoc(0), - ] { + for instr in vec![Bytecode::ImmBorrowLoc(0), Bytecode::MutBorrowLoc(0)] { let code = vec![instr, Bytecode::ReadRef]; let module = make_module_with_local(code, SignatureToken::U64); let fun_context = get_fun_context(&module); @@ -1180,7 +1073,7 @@ fn test_read_ref_correct_type() { #[test] fn test_read_ref_wrong_type() { -let code = vec![Bytecode::LdU64(42), Bytecode::ReadRef]; + let code = vec![Bytecode::LdU64(42), Bytecode::ReadRef]; let module = make_module_with_local(code, SignatureToken::U64); let fun_context = get_fun_context(&module); let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); @@ -1192,10 +1085,7 @@ let code = vec![Bytecode::LdU64(42), Bytecode::ReadRef]; #[test] fn test_read_ref_no_copy() { - for instr in vec![ - Bytecode::ImmBorrowLoc(0), - Bytecode::MutBorrowLoc(0), - ] { + for instr in vec![Bytecode::ImmBorrowLoc(0), Bytecode::MutBorrowLoc(0)] { let code = vec![instr, Bytecode::ReadRef]; let mut module = make_module_with_local(code, SignatureToken::Struct(StructHandleIndex(0))); add_simple_struct_with_abilities(&mut module, AbilitySet::EMPTY); @@ -1217,10 +1107,13 @@ fn test_read_ref_no_arg() { let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); } - #[test] fn test_write_ref_correct_type() { - let code = vec![Bytecode::LdU64(42), Bytecode::MutBorrowLoc(0), Bytecode::WriteRef]; + let code = vec![ + Bytecode::LdU64(42), + Bytecode::MutBorrowLoc(0), + Bytecode::WriteRef, + ]; let module = make_module_with_local(code, SignatureToken::U64); let fun_context = get_fun_context(&module); let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); @@ -1230,19 +1123,22 @@ fn test_write_ref_correct_type() { Bytecode::LdU32(42), Bytecode::Pack(StructDefinitionIndex(0)), Bytecode::MutBorrowLoc(0), - Bytecode::WriteRef + Bytecode::WriteRef, ]; let mut module = make_module_with_local(code, SignatureToken::Struct(StructHandleIndex(0))); add_simple_struct_with_abilities(&mut module, AbilitySet::PRIMITIVES); let fun_context = get_fun_context(&module); let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); assert!(result.is_ok()); - } #[test] fn test_write_ref_wrong_type() { - let code = vec![Bytecode::LdU64(42), Bytecode::ImmBorrowLoc(0), Bytecode::WriteRef]; + let code = vec![ + Bytecode::LdU64(42), + Bytecode::ImmBorrowLoc(0), + Bytecode::WriteRef, + ]; let module = make_module_with_local(code, SignatureToken::U64); let fun_context = get_fun_context(&module); let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); @@ -1254,7 +1150,11 @@ fn test_write_ref_wrong_type() { #[test] fn test_write_ref_mismatched_types() { - let code = vec![Bytecode::LdU32(42), Bytecode::MutBorrowLoc(0), Bytecode::WriteRef]; + let code = vec![ + Bytecode::LdU32(42), + Bytecode::MutBorrowLoc(0), + Bytecode::WriteRef, + ]; let module = make_module_with_local(code, SignatureToken::U64); let fun_context = get_fun_context(&module); let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); @@ -1270,7 +1170,7 @@ fn test_write_ref_no_drop() { Bytecode::LdU32(42), Bytecode::Pack(StructDefinitionIndex(0)), Bytecode::MutBorrowLoc(0), - Bytecode::WriteRef + Bytecode::WriteRef, ]; let mut module = make_module_with_local(code, SignatureToken::Struct(StructHandleIndex(0))); add_simple_struct_with_abilities(&mut module, AbilitySet::EMPTY); @@ -1300,10 +1200,12 @@ fn test_write_ref_no_args() { let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); } - #[test] fn test_imm_borrow_field_correct_type() { - let code = vec![Bytecode::ImmBorrowLoc(0), Bytecode::ImmBorrowField(FieldHandleIndex(0))]; + let code = vec![ + Bytecode::ImmBorrowLoc(0), + Bytecode::ImmBorrowField(FieldHandleIndex(0)), + ]; let mut module = make_module_with_local(code, SignatureToken::Struct(StructHandleIndex(0))); add_simple_struct(&mut module); let fun_context = get_fun_context(&module); @@ -1313,7 +1215,10 @@ fn test_imm_borrow_field_correct_type() { #[test] fn test_imm_borrow_field_wrong_type() { - let code = vec![Bytecode::LdTrue, Bytecode::ImmBorrowField(FieldHandleIndex(0))]; + let code = vec![ + Bytecode::LdTrue, + Bytecode::ImmBorrowField(FieldHandleIndex(0)), + ]; let mut module = make_module_with_local(code, SignatureToken::Struct(StructHandleIndex(0))); add_simple_struct(&mut module); let fun_context = get_fun_context(&module); @@ -1326,7 +1231,10 @@ fn test_imm_borrow_field_wrong_type() { #[test] fn test_imm_borrow_field_mismatched_types() { - let code = vec![Bytecode::ImmBorrowLoc(0), Bytecode::ImmBorrowField(FieldHandleIndex(0))]; + let code = vec![ + Bytecode::ImmBorrowLoc(0), + Bytecode::ImmBorrowField(FieldHandleIndex(0)), + ]; let mut module = make_module_with_local(code, SignatureToken::U64); add_simple_struct(&mut module); let fun_context = get_fun_context(&module); @@ -1339,7 +1247,10 @@ fn test_imm_borrow_field_mismatched_types() { #[test] fn test_imm_borrow_field_bad_field() { - let code = vec![Bytecode::ImmBorrowLoc(0), Bytecode::ImmBorrowField(FieldHandleIndex(0))]; + let code = vec![ + Bytecode::ImmBorrowLoc(0), + Bytecode::ImmBorrowField(FieldHandleIndex(0)), + ]; let mut module = make_module_with_local(code, SignatureToken::Struct(StructHandleIndex(0))); add_native_struct(&mut module); let fun_context = get_fun_context(&module); @@ -1360,10 +1271,12 @@ fn test_imm_borrow_field_no_arg() { let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); } - #[test] fn test_mut_borrow_field_correct_type() { - let code = vec![Bytecode::MutBorrowLoc(0), Bytecode::MutBorrowField(FieldHandleIndex(0))]; + let code = vec![ + Bytecode::MutBorrowLoc(0), + Bytecode::MutBorrowField(FieldHandleIndex(0)), + ]; let mut module = make_module_with_local(code, SignatureToken::Struct(StructHandleIndex(0))); add_simple_struct(&mut module); let fun_context = get_fun_context(&module); @@ -1373,7 +1286,10 @@ fn test_mut_borrow_field_correct_type() { #[test] fn test_mut_borrow_field_wrong_type() { - let code = vec![Bytecode::LdTrue, Bytecode::MutBorrowField(FieldHandleIndex(0))]; + let code = vec![ + Bytecode::LdTrue, + Bytecode::MutBorrowField(FieldHandleIndex(0)), + ]; let mut module = make_module_with_local(code, SignatureToken::Struct(StructHandleIndex(0))); add_simple_struct(&mut module); let fun_context = get_fun_context(&module); @@ -1383,7 +1299,10 @@ fn test_mut_borrow_field_wrong_type() { StatusCode::BORROWFIELD_TYPE_MISMATCH_ERROR ); - let code = vec![Bytecode::ImmBorrowLoc(0), Bytecode::MutBorrowField(FieldHandleIndex(0))]; + let code = vec![ + Bytecode::ImmBorrowLoc(0), + Bytecode::MutBorrowField(FieldHandleIndex(0)), + ]; let mut module = make_module_with_local(code, SignatureToken::Struct(StructHandleIndex(0))); add_simple_struct(&mut module); let fun_context = get_fun_context(&module); @@ -1392,12 +1311,14 @@ fn test_mut_borrow_field_wrong_type() { result.unwrap_err().major_status(), StatusCode::BORROWFIELD_TYPE_MISMATCH_ERROR ); - } #[test] fn test_mut_borrow_field_mismatched_types() { - let code = vec![Bytecode::MutBorrowLoc(0), Bytecode::MutBorrowField(FieldHandleIndex(0))]; + let code = vec![ + Bytecode::MutBorrowLoc(0), + Bytecode::MutBorrowField(FieldHandleIndex(0)), + ]; let mut module = make_module_with_local(code, SignatureToken::U64); add_simple_struct(&mut module); let fun_context = get_fun_context(&module); @@ -1410,7 +1331,10 @@ fn test_mut_borrow_field_mismatched_types() { #[test] fn test_mut_borrow_field_bad_field() { - let code = vec![Bytecode::MutBorrowLoc(0), Bytecode::MutBorrowField(FieldHandleIndex(0))]; + let code = vec![ + Bytecode::MutBorrowLoc(0), + Bytecode::MutBorrowField(FieldHandleIndex(0)), + ]; let mut module = make_module_with_local(code, SignatureToken::Struct(StructHandleIndex(0))); add_native_struct(&mut module); let fun_context = get_fun_context(&module); @@ -1431,7 +1355,6 @@ fn test_mut_borrow_field_no_arg() { let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); } - #[test] fn test_ret_correct_type() { let code = vec![Bytecode::LdU32(42), Bytecode::Ret]; @@ -1462,10 +1385,13 @@ fn test_ret_no_arg() { let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); } - #[test] fn test_call_correct_types() { - let code = vec![Bytecode::LdU64(42), Bytecode::LdTrue, Bytecode::Call(FunctionHandleIndex(1))]; + let code = vec![ + Bytecode::LdU64(42), + Bytecode::LdTrue, + Bytecode::Call(FunctionHandleIndex(1)), + ]; let parameters = Signature(vec![SignatureToken::U64, SignatureToken::Bool]); let mut module = make_module(code); add_function_with_parameters(&mut module, parameters); @@ -1476,7 +1402,11 @@ fn test_call_correct_types() { #[test] fn test_call_wrong_types() { - let code = vec![Bytecode::LdTrue, Bytecode::LdU64(42), Bytecode::Call(FunctionHandleIndex(1))]; + let code = vec![ + Bytecode::LdTrue, + Bytecode::LdU64(42), + Bytecode::Call(FunctionHandleIndex(1)), + ]; let parameters = Signature(vec![SignatureToken::U64, SignatureToken::Bool]); let mut module = make_module(code); add_function_with_parameters(&mut module, parameters); From 7f3853befe71ea752196ebd5c6e4ec5cdf58d6c9 Mon Sep 17 00:00:00 2001 From: Valerii Huhnin Date: Sat, 31 Aug 2024 06:11:09 +0000 Subject: [PATCH 31/52] tests for `VecPack` operation --- .../src/type_safety_tests/mod.rs | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs index 22ffe3c48a..eab5b3153e 100644 --- a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs +++ b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs @@ -1428,3 +1428,50 @@ fn test_call_too_few_args() { let fun_context = get_fun_context(&module); let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); } + +#[test] +fn test_vec_pack_correct_type() { + let code = vec![ + Bytecode::LdU32(33), + Bytecode::LdU32(42), + Bytecode::LdU32(51), + Bytecode::VecPack(SignatureIndex(1), 3), + ]; + let module = make_module(code); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); +} + +#[test] +fn test_vec_pack_wrong_type() { + let code = vec![ + Bytecode::LdU32(33), + Bytecode::LdU64(42), + Bytecode::LdU32(51), + Bytecode::VecPack(SignatureIndex(1), 3), + ]; + let module = make_module(code); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::TYPE_MISMATCH + ); +} + +#[test] +fn test_vec_pack_too_few_args() { + let code = vec![ + Bytecode::LdU32(33), + Bytecode::LdU32(51), + Bytecode::VecPack(SignatureIndex(1), 3), + ]; + let module = make_module(code); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::TYPE_MISMATCH + ); +} From 7ad39c59e70fe6daf51262fc28e32d6146cc326c Mon Sep 17 00:00:00 2001 From: Valerii Huhnin Date: Sat, 31 Aug 2024 08:42:31 +0000 Subject: [PATCH 32/52] tests for `VecUnpack` operation --- .../src/type_safety_tests/mod.rs | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs index eab5b3153e..85e318bb18 100644 --- a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs +++ b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs @@ -1475,3 +1475,73 @@ fn test_vec_pack_too_few_args() { StatusCode::TYPE_MISMATCH ); } + +#[test] +fn test_vec_unpack_correct_type() { + let code = vec![ + Bytecode::LdU32(33), + Bytecode::LdU32(42), + Bytecode::LdU32(51), + Bytecode::VecPack(SignatureIndex(1), 3), + Bytecode::VecUnpack(SignatureIndex(1), 3), + ]; + let module = make_module(code); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); +} + +#[test] +fn test_vec_unpack_wrong_type() { + let code = vec![ + Bytecode::LdU32(33), + Bytecode::VecUnpack(SignatureIndex(1), 3), + ]; + let module = make_module(code); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::TYPE_MISMATCH + ); + + let code = vec![ + Bytecode::LdU32(33), + Bytecode::LdU32(42), + Bytecode::LdU64(51), + Bytecode::VecPack(SignatureIndex(1), 3), + Bytecode::VecUnpack(SignatureIndex(2), 3), + ]; + let mut module = make_module(code); + module.signatures.push(Signature(vec![SignatureToken::U64])); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::TYPE_MISMATCH + ); +} + +#[test] +fn test_vec_unpack_too_few_elements() { + let code = vec![ + Bytecode::LdU32(33), + Bytecode::LdU32(42), + Bytecode::LdU32(51), + Bytecode::VecPack(SignatureIndex(1), 3), + Bytecode::VecUnpack(SignatureIndex(1), 100500), + ]; + let module = make_module(code); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); +} + +#[test] +#[should_panic] +fn test_vec_unpack_no_arg() { + let code = vec![Bytecode::VecUnpack(SignatureIndex(1), 3)]; + let module = make_module(code); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); +} From b91b97584a7ba8623c6b14552e3cfce0b075c315 Mon Sep 17 00:00:00 2001 From: Valerii Huhnin Date: Mon, 2 Sep 2024 13:33:00 +0000 Subject: [PATCH 33/52] tests for `VecLen` operation --- .../src/type_safety_tests/mod.rs | 64 +++++++++++++++++-- 1 file changed, 60 insertions(+), 4 deletions(-) diff --git a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs index 85e318bb18..303dabd68e 100644 --- a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs +++ b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs @@ -53,7 +53,8 @@ fn make_module_with_ret(code: Vec, return_: SignatureToken) -> Compile fn make_module_with_local(code: Vec, signature: SignatureToken) -> CompiledModule { let code_unit = CodeUnit { code, - locals: SignatureIndex(0), + locals: SignatureIndex(2), + ..Default::default() }; let fun_def = FunctionDefinition { @@ -64,15 +65,15 @@ fn make_module_with_local(code: Vec, signature: SignatureToken) -> Com let fun_handle = FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), - parameters: SignatureIndex(0), - return_: SignatureIndex(0), + parameters: SignatureIndex(2), + return_: SignatureIndex(1), type_parameters: vec![], }; let mut module = empty_module(); module.function_handles.push(fun_handle); module.function_defs.push(fun_def); - module.signatures = vec![Signature(vec![signature])]; + module.signatures = vec![Signature(vec![]), Signature(vec![SignatureToken::U32]), Signature(vec![signature])]; module } @@ -1545,3 +1546,58 @@ fn test_vec_unpack_no_arg() { let fun_context = get_fun_context(&module); let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); } + +#[test] +fn test_vec_len_correct_type() { + let code = vec![ + Bytecode::ImmBorrowLoc(0), + Bytecode::VecLen(SignatureIndex(3)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + module.signatures.push(Signature(vec![SignatureToken::U32])); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); +} + +#[test] +fn test_vec_len_type_mismatch() { + let code = vec![ + Bytecode::ImmBorrowLoc(0), + Bytecode::VecLen(SignatureIndex(3)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + module.signatures.push(Signature(vec![SignatureToken::U64])); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::TYPE_MISMATCH + ); +} + +#[test] +fn test_vec_len_wrong_type() { + let code = vec![ + Bytecode::LdU32(42), + Bytecode::VecLen(SignatureIndex(3)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + module.signatures.push(Signature(vec![SignatureToken::U32])); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::TYPE_MISMATCH + ); +} + +#[test] +#[should_panic] +fn test_vec_len_no_arg() { + let code = vec![Bytecode::VecLen(SignatureIndex(3))]; + let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + module.signatures.push(Signature(vec![SignatureToken::U32])); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); +} From d40d47dc413203d303d94f7a917d645353c42d94 Mon Sep 17 00:00:00 2001 From: Valerii Huhnin Date: Mon, 2 Sep 2024 14:19:06 +0000 Subject: [PATCH 34/52] tests for `VecImmBorrow` operation --- .../src/type_safety_tests/mod.rs | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs index 303dabd68e..fd96d322e9 100644 --- a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs +++ b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs @@ -1601,3 +1601,99 @@ fn test_vec_len_no_arg() { let fun_context = get_fun_context(&module); let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); } + +#[test] +fn test_vec_imm_borrow_correct_type() { + let code = vec![ + Bytecode::ImmBorrowLoc(0), + Bytecode::LdU64(2), + Bytecode::VecImmBorrow(SignatureIndex(3)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + module.signatures.push(Signature(vec![SignatureToken::U32])); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); + + let code = vec![ + Bytecode::MutBorrowLoc(0), + Bytecode::LdU64(2), + Bytecode::VecImmBorrow(SignatureIndex(3)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + module.signatures.push(Signature(vec![SignatureToken::U32])); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); +} + +#[test] +fn test_vec_imm_borrow_type_mismatch() { + let code = vec![ + Bytecode::ImmBorrowLoc(0), + Bytecode::LdU64(2), + Bytecode::VecImmBorrow(SignatureIndex(3)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + module.signatures.push(Signature(vec![SignatureToken::U64])); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::TYPE_MISMATCH + ); +} + +#[test] +fn test_vec_imm_borrow_wrong_type() { + let code = vec![ + Bytecode::LdU32(42), + Bytecode::LdU64(2), + Bytecode::VecImmBorrow(SignatureIndex(3)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + module.signatures.push(Signature(vec![SignatureToken::U32])); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::TYPE_MISMATCH + ); + + let code = vec![ + Bytecode::ImmBorrowLoc(0), + Bytecode::LdU32(2), + Bytecode::VecImmBorrow(SignatureIndex(3)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + module.signatures.push(Signature(vec![SignatureToken::U32])); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::TYPE_MISMATCH + ); +} + +#[test] +#[should_panic] +fn test_vec_imm_borrow_too_few_args() { + let code = vec![ + Bytecode::ImmBorrowLoc(0), + Bytecode::VecImmBorrow(SignatureIndex(3)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + module.signatures.push(Signature(vec![SignatureToken::U32])); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); +} + +#[test] +#[should_panic] +fn test_vec_imm_borrow_no_arg() { + let code = vec![Bytecode::VecImmBorrow(SignatureIndex(3))]; + let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + module.signatures.push(Signature(vec![SignatureToken::U32])); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); +} From 34e725e3b5389e92d7394289106bd8ecb412c7ff Mon Sep 17 00:00:00 2001 From: Valerii Huhnin Date: Mon, 2 Sep 2024 14:27:51 +0000 Subject: [PATCH 35/52] tests for `VecMutBorrow` operation --- .../src/type_safety_tests/mod.rs | 99 +++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs index fd96d322e9..f2017c736f 100644 --- a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs +++ b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs @@ -1697,3 +1697,102 @@ fn test_vec_imm_borrow_no_arg() { let fun_context = get_fun_context(&module); let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); } + +#[test] +fn test_vec_mut_borrow_correct_type() { + let code = vec![ + Bytecode::MutBorrowLoc(0), + Bytecode::LdU64(2), + Bytecode::VecMutBorrow(SignatureIndex(3)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + module.signatures.push(Signature(vec![SignatureToken::U32])); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); +} + +#[test] +fn test_vec_mut_borrow_type_mismatch() { + let code = vec![ + Bytecode::MutBorrowLoc(0), + Bytecode::LdU64(2), + Bytecode::VecMutBorrow(SignatureIndex(3)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + module.signatures.push(Signature(vec![SignatureToken::U64])); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::TYPE_MISMATCH + ); +} + +#[test] +fn test_vec_mut_borrow_wrong_type() { + let code = vec![ + Bytecode::LdU32(42), + Bytecode::LdU64(2), + Bytecode::VecMutBorrow(SignatureIndex(3)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + module.signatures.push(Signature(vec![SignatureToken::U32])); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::TYPE_MISMATCH + ); + + let code = vec![ + Bytecode::ImmBorrowLoc(0), + Bytecode::LdU64(2), + Bytecode::VecMutBorrow(SignatureIndex(3)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + module.signatures.push(Signature(vec![SignatureToken::U32])); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::TYPE_MISMATCH + ); + + let code = vec![ + Bytecode::MutBorrowLoc(0), + Bytecode::LdU32(2), + Bytecode::VecMutBorrow(SignatureIndex(3)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + module.signatures.push(Signature(vec![SignatureToken::U32])); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::TYPE_MISMATCH + ); +} + +#[test] +#[should_panic] +fn test_vec_mut_borrow_too_few_args() { + let code = vec![ + Bytecode::MutBorrowLoc(0), + Bytecode::VecMutBorrow(SignatureIndex(3)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + module.signatures.push(Signature(vec![SignatureToken::U32])); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); +} + +#[test] +#[should_panic] +fn test_vec_mut_borrow_no_arg() { + let code = vec![Bytecode::VecMutBorrow(SignatureIndex(3))]; + let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + module.signatures.push(Signature(vec![SignatureToken::U32])); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); +} From cd27f706484e32ede0db4ac8b656b7d8929a2bb3 Mon Sep 17 00:00:00 2001 From: Valerii Huhnin Date: Mon, 2 Sep 2024 14:45:50 +0000 Subject: [PATCH 36/52] tests for `VecPushBack` operation --- .../src/type_safety_tests/mod.rs | 113 ++++++++++++++++++ 1 file changed, 113 insertions(+) diff --git a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs index f2017c736f..fc6089a7f3 100644 --- a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs +++ b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs @@ -1796,3 +1796,116 @@ fn test_vec_mut_borrow_no_arg() { let fun_context = get_fun_context(&module); let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); } + +#[test] +fn test_vec_push_back_correct_type() { + let code = vec![ + Bytecode::MutBorrowLoc(0), + Bytecode::LdU32(42), + Bytecode::VecPushBack(SignatureIndex(3)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + module.signatures.push(Signature(vec![SignatureToken::U32])); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); +} + +#[test] +fn test_vec_push_back_type_mismatch() { + let code = vec![ + Bytecode::MutBorrowLoc(0), + Bytecode::LdFalse, + Bytecode::VecPushBack(SignatureIndex(3)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + module.signatures.push(Signature(vec![SignatureToken::U32])); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::TYPE_MISMATCH + ); + + let code = vec![ + Bytecode::MutBorrowLoc(0), + Bytecode::LdU32(51), + Bytecode::VecPushBack(SignatureIndex(3)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U64))); + module.signatures.push(Signature(vec![SignatureToken::U32])); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::TYPE_MISMATCH + ); + + let code = vec![ + Bytecode::MutBorrowLoc(0), + Bytecode::LdU32(51), + Bytecode::VecPushBack(SignatureIndex(3)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + module.signatures.push(Signature(vec![SignatureToken::U64])); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::TYPE_MISMATCH + ); +} + +#[test] +fn test_vec_push_back_wrong_type() { + let code = vec![ + Bytecode::LdTrue, + Bytecode::LdU32(42), + Bytecode::VecPushBack(SignatureIndex(3)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + module.signatures.push(Signature(vec![SignatureToken::U32])); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::TYPE_MISMATCH + ); + + let code = vec![ + Bytecode::ImmBorrowLoc(0), + Bytecode::LdU32(42), + Bytecode::VecPushBack(SignatureIndex(3)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + module.signatures.push(Signature(vec![SignatureToken::U32])); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::TYPE_MISMATCH + ); +} + +#[test] +#[should_panic] +fn test_vec_push_back_too_few_args() { + let code = vec![ + Bytecode::MutBorrowLoc(0), + Bytecode::VecPushBack(SignatureIndex(3)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + module.signatures.push(Signature(vec![SignatureToken::U32])); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); +} + +#[test] +#[should_panic] +fn test_vec_push_back_no_arg() { + let code = vec![Bytecode::VecPushBack(SignatureIndex(3))]; + let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + module.signatures.push(Signature(vec![SignatureToken::U32])); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); +} From 094db42b72cbb7e4d5e2ce791a7bd29bb7edce90 Mon Sep 17 00:00:00 2001 From: Valerii Huhnin Date: Mon, 2 Sep 2024 14:51:13 +0000 Subject: [PATCH 37/52] tests for `VecPopBack` operation --- .../src/type_safety_tests/mod.rs | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs index fc6089a7f3..110c7c7143 100644 --- a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs +++ b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs @@ -1909,3 +1909,71 @@ fn test_vec_push_back_no_arg() { let fun_context = get_fun_context(&module); let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); } + +#[test] +fn test_vec_pop_back_correct_type() { + let code = vec![ + Bytecode::MutBorrowLoc(0), + Bytecode::VecPopBack(SignatureIndex(3)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + module.signatures.push(Signature(vec![SignatureToken::U32])); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); +} + +#[test] +fn test_vec_pop_back_type_mismatch() { + let code = vec![ + Bytecode::MutBorrowLoc(0), + Bytecode::VecPopBack(SignatureIndex(3)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + module.signatures.push(Signature(vec![SignatureToken::U64])); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::TYPE_MISMATCH + ); +} + +#[test] +fn test_vec_pop_back_wrong_type() { + let code = vec![ + Bytecode::LdTrue, + Bytecode::VecPopBack(SignatureIndex(3)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + module.signatures.push(Signature(vec![SignatureToken::U32])); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::TYPE_MISMATCH + ); + + let code = vec![ + Bytecode::ImmBorrowLoc(0), + Bytecode::VecPopBack(SignatureIndex(3)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + module.signatures.push(Signature(vec![SignatureToken::U32])); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::TYPE_MISMATCH + ); +} + +#[test] +#[should_panic] +fn test_vec_pop_back_no_arg() { + let code = vec![Bytecode::VecPopBack(SignatureIndex(3))]; + let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + module.signatures.push(Signature(vec![SignatureToken::U32])); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); +} From 887b39e55a9e4690f7423e0a424aa0cb055e69d3 Mon Sep 17 00:00:00 2001 From: Valerii Huhnin Date: Mon, 2 Sep 2024 14:56:28 +0000 Subject: [PATCH 38/52] tests for `VecSwap` operation --- .../src/type_safety_tests/mod.rs | 105 ++++++++++++++++++ 1 file changed, 105 insertions(+) diff --git a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs index 110c7c7143..07c001963e 100644 --- a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs +++ b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs @@ -1977,3 +1977,108 @@ fn test_vec_pop_back_no_arg() { let fun_context = get_fun_context(&module); let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); } + +#[test] +fn test_vec_swap_correct_type() { + let code = vec![ + Bytecode::MutBorrowLoc(0), + Bytecode::LdU64(2), + Bytecode::LdU64(3), + Bytecode::VecSwap(SignatureIndex(3)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + module.signatures.push(Signature(vec![SignatureToken::U32])); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); +} + +#[test] +fn test_vec_swap_type_mismatch() { + let code = vec![ + Bytecode::MutBorrowLoc(0), + Bytecode::LdU64(2), + Bytecode::LdU64(3), + Bytecode::VecSwap(SignatureIndex(3)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + module.signatures.push(Signature(vec![SignatureToken::U64])); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!(result.unwrap_err().major_status(), StatusCode::TYPE_MISMATCH); +} + +#[test] +fn test_vec_swap_wrong_type() { + let code = vec![ + Bytecode::LdTrue, + Bytecode::LdU64(2), + Bytecode::LdU64(3), + Bytecode::VecSwap(SignatureIndex(3)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + module.signatures.push(Signature(vec![SignatureToken::U32])); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!(result.unwrap_err().major_status(), StatusCode::TYPE_MISMATCH); + + let code = vec![ + Bytecode::ImmBorrowLoc(0), + Bytecode::LdU64(2), + Bytecode::LdU64(3), + Bytecode::VecSwap(SignatureIndex(3)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + module.signatures.push(Signature(vec![SignatureToken::U32])); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!(result.unwrap_err().major_status(), StatusCode::TYPE_MISMATCH); + + let code = vec![ + Bytecode::MutBorrowLoc(0), + Bytecode::LdU32(2), + Bytecode::LdU64(3), + Bytecode::VecSwap(SignatureIndex(3)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + module.signatures.push(Signature(vec![SignatureToken::U32])); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!(result.unwrap_err().major_status(), StatusCode::TYPE_MISMATCH); + + let code = vec![ + Bytecode::MutBorrowLoc(0), + Bytecode::LdU64(2), + Bytecode::LdU32(3), + Bytecode::VecSwap(SignatureIndex(3)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + module.signatures.push(Signature(vec![SignatureToken::U32])); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!(result.unwrap_err().major_status(), StatusCode::TYPE_MISMATCH); +} + +#[test] +#[should_panic] +fn test_vec_swap_too_few_args() { + let code = vec![ + Bytecode::MutBorrowLoc(0), + Bytecode::LdU64(2), + Bytecode::VecSwap(SignatureIndex(3)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + module.signatures.push(Signature(vec![SignatureToken::U32])); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); +} + +#[test] +#[should_panic] +fn test_vec_swap_no_arg() { + let code = vec![Bytecode::VecSwap(SignatureIndex(3))]; + let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + module.signatures.push(Signature(vec![SignatureToken::U32])); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); +} From c17baa2171475814739cd4982f2f54154a5d3839 Mon Sep 17 00:00:00 2001 From: Valerii Huhnin Date: Mon, 2 Sep 2024 14:56:54 +0000 Subject: [PATCH 39/52] `cargo fmt` --- .../src/type_safety_tests/mod.rs | 158 ++++++++++++------ 1 file changed, 105 insertions(+), 53 deletions(-) diff --git a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs index 07c001963e..dc3dd7ced6 100644 --- a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs +++ b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs @@ -73,7 +73,11 @@ fn make_module_with_local(code: Vec, signature: SignatureToken) -> Com let mut module = empty_module(); module.function_handles.push(fun_handle); module.function_defs.push(fun_def); - module.signatures = vec![Signature(vec![]), Signature(vec![SignatureToken::U32]), Signature(vec![signature])]; + module.signatures = vec![ + Signature(vec![]), + Signature(vec![SignatureToken::U32]), + Signature(vec![signature]), + ]; module } @@ -1553,7 +1557,8 @@ fn test_vec_len_correct_type() { Bytecode::ImmBorrowLoc(0), Bytecode::VecLen(SignatureIndex(3)), ]; - let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + let mut module = + make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); module.signatures.push(Signature(vec![SignatureToken::U32])); let fun_context = get_fun_context(&module); let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); @@ -1566,7 +1571,8 @@ fn test_vec_len_type_mismatch() { Bytecode::ImmBorrowLoc(0), Bytecode::VecLen(SignatureIndex(3)), ]; - let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + let mut module = + make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); module.signatures.push(Signature(vec![SignatureToken::U64])); let fun_context = get_fun_context(&module); let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); @@ -1578,11 +1584,9 @@ fn test_vec_len_type_mismatch() { #[test] fn test_vec_len_wrong_type() { - let code = vec![ - Bytecode::LdU32(42), - Bytecode::VecLen(SignatureIndex(3)), - ]; - let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + let code = vec![Bytecode::LdU32(42), Bytecode::VecLen(SignatureIndex(3))]; + let mut module = + make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); module.signatures.push(Signature(vec![SignatureToken::U32])); let fun_context = get_fun_context(&module); let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); @@ -1596,7 +1600,8 @@ fn test_vec_len_wrong_type() { #[should_panic] fn test_vec_len_no_arg() { let code = vec![Bytecode::VecLen(SignatureIndex(3))]; - let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + let mut module = + make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); module.signatures.push(Signature(vec![SignatureToken::U32])); let fun_context = get_fun_context(&module); let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); @@ -1609,7 +1614,8 @@ fn test_vec_imm_borrow_correct_type() { Bytecode::LdU64(2), Bytecode::VecImmBorrow(SignatureIndex(3)), ]; - let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + let mut module = + make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); module.signatures.push(Signature(vec![SignatureToken::U32])); let fun_context = get_fun_context(&module); let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); @@ -1620,7 +1626,8 @@ fn test_vec_imm_borrow_correct_type() { Bytecode::LdU64(2), Bytecode::VecImmBorrow(SignatureIndex(3)), ]; - let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + let mut module = + make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); module.signatures.push(Signature(vec![SignatureToken::U32])); let fun_context = get_fun_context(&module); let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); @@ -1634,7 +1641,8 @@ fn test_vec_imm_borrow_type_mismatch() { Bytecode::LdU64(2), Bytecode::VecImmBorrow(SignatureIndex(3)), ]; - let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + let mut module = + make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); module.signatures.push(Signature(vec![SignatureToken::U64])); let fun_context = get_fun_context(&module); let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); @@ -1651,7 +1659,8 @@ fn test_vec_imm_borrow_wrong_type() { Bytecode::LdU64(2), Bytecode::VecImmBorrow(SignatureIndex(3)), ]; - let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + let mut module = + make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); module.signatures.push(Signature(vec![SignatureToken::U32])); let fun_context = get_fun_context(&module); let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); @@ -1665,7 +1674,8 @@ fn test_vec_imm_borrow_wrong_type() { Bytecode::LdU32(2), Bytecode::VecImmBorrow(SignatureIndex(3)), ]; - let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + let mut module = + make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); module.signatures.push(Signature(vec![SignatureToken::U32])); let fun_context = get_fun_context(&module); let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); @@ -1682,7 +1692,8 @@ fn test_vec_imm_borrow_too_few_args() { Bytecode::ImmBorrowLoc(0), Bytecode::VecImmBorrow(SignatureIndex(3)), ]; - let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + let mut module = + make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); module.signatures.push(Signature(vec![SignatureToken::U32])); let fun_context = get_fun_context(&module); let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); @@ -1692,7 +1703,8 @@ fn test_vec_imm_borrow_too_few_args() { #[should_panic] fn test_vec_imm_borrow_no_arg() { let code = vec![Bytecode::VecImmBorrow(SignatureIndex(3))]; - let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + let mut module = + make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); module.signatures.push(Signature(vec![SignatureToken::U32])); let fun_context = get_fun_context(&module); let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); @@ -1705,7 +1717,8 @@ fn test_vec_mut_borrow_correct_type() { Bytecode::LdU64(2), Bytecode::VecMutBorrow(SignatureIndex(3)), ]; - let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + let mut module = + make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); module.signatures.push(Signature(vec![SignatureToken::U32])); let fun_context = get_fun_context(&module); let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); @@ -1719,7 +1732,8 @@ fn test_vec_mut_borrow_type_mismatch() { Bytecode::LdU64(2), Bytecode::VecMutBorrow(SignatureIndex(3)), ]; - let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + let mut module = + make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); module.signatures.push(Signature(vec![SignatureToken::U64])); let fun_context = get_fun_context(&module); let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); @@ -1736,7 +1750,8 @@ fn test_vec_mut_borrow_wrong_type() { Bytecode::LdU64(2), Bytecode::VecMutBorrow(SignatureIndex(3)), ]; - let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + let mut module = + make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); module.signatures.push(Signature(vec![SignatureToken::U32])); let fun_context = get_fun_context(&module); let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); @@ -1750,7 +1765,8 @@ fn test_vec_mut_borrow_wrong_type() { Bytecode::LdU64(2), Bytecode::VecMutBorrow(SignatureIndex(3)), ]; - let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + let mut module = + make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); module.signatures.push(Signature(vec![SignatureToken::U32])); let fun_context = get_fun_context(&module); let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); @@ -1764,7 +1780,8 @@ fn test_vec_mut_borrow_wrong_type() { Bytecode::LdU32(2), Bytecode::VecMutBorrow(SignatureIndex(3)), ]; - let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + let mut module = + make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); module.signatures.push(Signature(vec![SignatureToken::U32])); let fun_context = get_fun_context(&module); let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); @@ -1781,7 +1798,8 @@ fn test_vec_mut_borrow_too_few_args() { Bytecode::MutBorrowLoc(0), Bytecode::VecMutBorrow(SignatureIndex(3)), ]; - let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + let mut module = + make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); module.signatures.push(Signature(vec![SignatureToken::U32])); let fun_context = get_fun_context(&module); let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); @@ -1791,7 +1809,8 @@ fn test_vec_mut_borrow_too_few_args() { #[should_panic] fn test_vec_mut_borrow_no_arg() { let code = vec![Bytecode::VecMutBorrow(SignatureIndex(3))]; - let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + let mut module = + make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); module.signatures.push(Signature(vec![SignatureToken::U32])); let fun_context = get_fun_context(&module); let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); @@ -1804,7 +1823,8 @@ fn test_vec_push_back_correct_type() { Bytecode::LdU32(42), Bytecode::VecPushBack(SignatureIndex(3)), ]; - let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + let mut module = + make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); module.signatures.push(Signature(vec![SignatureToken::U32])); let fun_context = get_fun_context(&module); let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); @@ -1818,7 +1838,8 @@ fn test_vec_push_back_type_mismatch() { Bytecode::LdFalse, Bytecode::VecPushBack(SignatureIndex(3)), ]; - let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + let mut module = + make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); module.signatures.push(Signature(vec![SignatureToken::U32])); let fun_context = get_fun_context(&module); let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); @@ -1832,7 +1853,8 @@ fn test_vec_push_back_type_mismatch() { Bytecode::LdU32(51), Bytecode::VecPushBack(SignatureIndex(3)), ]; - let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U64))); + let mut module = + make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U64))); module.signatures.push(Signature(vec![SignatureToken::U32])); let fun_context = get_fun_context(&module); let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); @@ -1846,7 +1868,8 @@ fn test_vec_push_back_type_mismatch() { Bytecode::LdU32(51), Bytecode::VecPushBack(SignatureIndex(3)), ]; - let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + let mut module = + make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); module.signatures.push(Signature(vec![SignatureToken::U64])); let fun_context = get_fun_context(&module); let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); @@ -1863,7 +1886,8 @@ fn test_vec_push_back_wrong_type() { Bytecode::LdU32(42), Bytecode::VecPushBack(SignatureIndex(3)), ]; - let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + let mut module = + make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); module.signatures.push(Signature(vec![SignatureToken::U32])); let fun_context = get_fun_context(&module); let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); @@ -1877,7 +1901,8 @@ fn test_vec_push_back_wrong_type() { Bytecode::LdU32(42), Bytecode::VecPushBack(SignatureIndex(3)), ]; - let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + let mut module = + make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); module.signatures.push(Signature(vec![SignatureToken::U32])); let fun_context = get_fun_context(&module); let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); @@ -1894,7 +1919,8 @@ fn test_vec_push_back_too_few_args() { Bytecode::MutBorrowLoc(0), Bytecode::VecPushBack(SignatureIndex(3)), ]; - let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + let mut module = + make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); module.signatures.push(Signature(vec![SignatureToken::U32])); let fun_context = get_fun_context(&module); let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); @@ -1904,7 +1930,8 @@ fn test_vec_push_back_too_few_args() { #[should_panic] fn test_vec_push_back_no_arg() { let code = vec![Bytecode::VecPushBack(SignatureIndex(3))]; - let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + let mut module = + make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); module.signatures.push(Signature(vec![SignatureToken::U32])); let fun_context = get_fun_context(&module); let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); @@ -1916,7 +1943,8 @@ fn test_vec_pop_back_correct_type() { Bytecode::MutBorrowLoc(0), Bytecode::VecPopBack(SignatureIndex(3)), ]; - let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + let mut module = + make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); module.signatures.push(Signature(vec![SignatureToken::U32])); let fun_context = get_fun_context(&module); let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); @@ -1929,7 +1957,8 @@ fn test_vec_pop_back_type_mismatch() { Bytecode::MutBorrowLoc(0), Bytecode::VecPopBack(SignatureIndex(3)), ]; - let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + let mut module = + make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); module.signatures.push(Signature(vec![SignatureToken::U64])); let fun_context = get_fun_context(&module); let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); @@ -1941,11 +1970,9 @@ fn test_vec_pop_back_type_mismatch() { #[test] fn test_vec_pop_back_wrong_type() { - let code = vec![ - Bytecode::LdTrue, - Bytecode::VecPopBack(SignatureIndex(3)), - ]; - let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + let code = vec![Bytecode::LdTrue, Bytecode::VecPopBack(SignatureIndex(3))]; + let mut module = + make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); module.signatures.push(Signature(vec![SignatureToken::U32])); let fun_context = get_fun_context(&module); let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); @@ -1958,7 +1985,8 @@ fn test_vec_pop_back_wrong_type() { Bytecode::ImmBorrowLoc(0), Bytecode::VecPopBack(SignatureIndex(3)), ]; - let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + let mut module = + make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); module.signatures.push(Signature(vec![SignatureToken::U32])); let fun_context = get_fun_context(&module); let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); @@ -1972,7 +2000,8 @@ fn test_vec_pop_back_wrong_type() { #[should_panic] fn test_vec_pop_back_no_arg() { let code = vec![Bytecode::VecPopBack(SignatureIndex(3))]; - let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + let mut module = + make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); module.signatures.push(Signature(vec![SignatureToken::U32])); let fun_context = get_fun_context(&module); let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); @@ -1986,7 +2015,8 @@ fn test_vec_swap_correct_type() { Bytecode::LdU64(3), Bytecode::VecSwap(SignatureIndex(3)), ]; - let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + let mut module = + make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); module.signatures.push(Signature(vec![SignatureToken::U32])); let fun_context = get_fun_context(&module); let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); @@ -2001,11 +2031,15 @@ fn test_vec_swap_type_mismatch() { Bytecode::LdU64(3), Bytecode::VecSwap(SignatureIndex(3)), ]; - let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + let mut module = + make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); module.signatures.push(Signature(vec![SignatureToken::U64])); let fun_context = get_fun_context(&module); let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); - assert_eq!(result.unwrap_err().major_status(), StatusCode::TYPE_MISMATCH); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::TYPE_MISMATCH + ); } #[test] @@ -2016,11 +2050,15 @@ fn test_vec_swap_wrong_type() { Bytecode::LdU64(3), Bytecode::VecSwap(SignatureIndex(3)), ]; - let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + let mut module = + make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); module.signatures.push(Signature(vec![SignatureToken::U32])); let fun_context = get_fun_context(&module); let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); - assert_eq!(result.unwrap_err().major_status(), StatusCode::TYPE_MISMATCH); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::TYPE_MISMATCH + ); let code = vec![ Bytecode::ImmBorrowLoc(0), @@ -2028,11 +2066,15 @@ fn test_vec_swap_wrong_type() { Bytecode::LdU64(3), Bytecode::VecSwap(SignatureIndex(3)), ]; - let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + let mut module = + make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); module.signatures.push(Signature(vec![SignatureToken::U32])); let fun_context = get_fun_context(&module); let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); - assert_eq!(result.unwrap_err().major_status(), StatusCode::TYPE_MISMATCH); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::TYPE_MISMATCH + ); let code = vec![ Bytecode::MutBorrowLoc(0), @@ -2040,11 +2082,15 @@ fn test_vec_swap_wrong_type() { Bytecode::LdU64(3), Bytecode::VecSwap(SignatureIndex(3)), ]; - let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + let mut module = + make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); module.signatures.push(Signature(vec![SignatureToken::U32])); let fun_context = get_fun_context(&module); let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); - assert_eq!(result.unwrap_err().major_status(), StatusCode::TYPE_MISMATCH); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::TYPE_MISMATCH + ); let code = vec![ Bytecode::MutBorrowLoc(0), @@ -2052,11 +2098,15 @@ fn test_vec_swap_wrong_type() { Bytecode::LdU32(3), Bytecode::VecSwap(SignatureIndex(3)), ]; - let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + let mut module = + make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); module.signatures.push(Signature(vec![SignatureToken::U32])); let fun_context = get_fun_context(&module); let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); - assert_eq!(result.unwrap_err().major_status(), StatusCode::TYPE_MISMATCH); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::TYPE_MISMATCH + ); } #[test] @@ -2067,7 +2117,8 @@ fn test_vec_swap_too_few_args() { Bytecode::LdU64(2), Bytecode::VecSwap(SignatureIndex(3)), ]; - let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + let mut module = + make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); module.signatures.push(Signature(vec![SignatureToken::U32])); let fun_context = get_fun_context(&module); let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); @@ -2077,7 +2128,8 @@ fn test_vec_swap_too_few_args() { #[should_panic] fn test_vec_swap_no_arg() { let code = vec![Bytecode::VecSwap(SignatureIndex(3))]; - let mut module = make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); + let mut module = + make_module_with_local(code, SignatureToken::Vector(Box::new(SignatureToken::U32))); module.signatures.push(Signature(vec![SignatureToken::U32])); let fun_context = get_fun_context(&module); let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); From 34a065ebc5b01ddf17ed5a545d10fe221f17f9ca Mon Sep 17 00:00:00 2001 From: Valerii Huhnin Date: Wed, 4 Sep 2024 06:11:57 +0000 Subject: [PATCH 40/52] tests for `ExistsDeprecated` instruction --- .../src/type_safety_tests/mod.rs | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs index dc3dd7ced6..5aa44aa05d 100644 --- a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs +++ b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs @@ -2134,3 +2134,58 @@ fn test_vec_swap_no_arg() { let fun_context = get_fun_context(&module); let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); } + +#[test] +fn test_exists_deprecated_correct_type() { + let code = vec![ + Bytecode::CopyLoc(0), + Bytecode::ExistsDeprecated(StructDefinitionIndex(0)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Address); + add_simple_struct_with_abilities(&mut module, AbilitySet::ALL); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); +} + +#[test] +fn test_exists_deprecated_wrong_type() { + let code = vec![ + Bytecode::LdU64(42), + Bytecode::ExistsDeprecated(StructDefinitionIndex(0)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Address); + add_simple_struct_with_abilities(&mut module, AbilitySet::ALL); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::EXISTS_WITHOUT_KEY_ABILITY_OR_BAD_ARGUMENT + ); +} + +#[test] +fn test_exists_deprecated_no_key() { + let code = vec![ + Bytecode::CopyLoc(0), + Bytecode::ExistsDeprecated(StructDefinitionIndex(0)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Address); + add_simple_struct_with_abilities(&mut module, AbilitySet::PRIMITIVES); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::EXISTS_WITHOUT_KEY_ABILITY_OR_BAD_ARGUMENT + ); +} + +#[test] +#[should_panic] +fn test_exists_deprecated_no_arg() { + let code = vec![Bytecode::ExistsDeprecated(StructDefinitionIndex(0))]; + let mut module = make_module_with_local(code, SignatureToken::Address); + add_simple_struct_with_abilities(&mut module, AbilitySet::ALL); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); +} From 69ef9c90d566ed1a5abdfe8b091f7850f62efcaa Mon Sep 17 00:00:00 2001 From: Valerii Huhnin Date: Wed, 4 Sep 2024 06:14:50 +0000 Subject: [PATCH 41/52] tests for `MoveFromDeprecated` instruction --- .../src/type_safety_tests/mod.rs | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs index 5aa44aa05d..19ce6a6d92 100644 --- a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs +++ b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs @@ -2189,3 +2189,58 @@ fn test_exists_deprecated_no_arg() { let fun_context = get_fun_context(&module); let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); } + +#[test] +fn test_move_from_deprecated_correct_type() { + let code = vec![ + Bytecode::CopyLoc(0), + Bytecode::MoveFromDeprecated(StructDefinitionIndex(0)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Address); + add_simple_struct_with_abilities(&mut module, AbilitySet::ALL); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); +} + +#[test] +fn test_move_from_deprecated_wrong_type() { + let code = vec![ + Bytecode::LdU64(42), + Bytecode::MoveFromDeprecated(StructDefinitionIndex(0)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Address); + add_simple_struct_with_abilities(&mut module, AbilitySet::ALL); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::MOVEFROM_TYPE_MISMATCH_ERROR + ); +} + +#[test] +fn test_move_from_deprecated_no_key() { + let code = vec![ + Bytecode::CopyLoc(0), + Bytecode::MoveFromDeprecated(StructDefinitionIndex(0)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Address); + add_simple_struct_with_abilities(&mut module, AbilitySet::PRIMITIVES); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::MOVEFROM_WITHOUT_KEY_ABILITY + ); +} + +#[test] +#[should_panic] +fn test_move_from_deprecated_no_arg() { + let code = vec![Bytecode::MoveFromDeprecated(StructDefinitionIndex(0))]; + let mut module = make_module_with_local(code, SignatureToken::Address); + add_simple_struct_with_abilities(&mut module, AbilitySet::ALL); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); +} From 6b9224eca71ed3baed240d82eeef1f99fd90b46c Mon Sep 17 00:00:00 2001 From: Valerii Huhnin Date: Wed, 4 Sep 2024 06:59:58 +0000 Subject: [PATCH 42/52] tests for `ImmBorrowGlobalDeprecated` and `MutBorrowGlobalDeprecated` --- .../src/type_safety_tests/mod.rs | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs index 19ce6a6d92..6fe6c385a0 100644 --- a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs +++ b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs @@ -2244,3 +2244,69 @@ fn test_move_from_deprecated_no_arg() { let fun_context = get_fun_context(&module); let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); } + +#[test] +fn test_borrow_global_deprecated_correct_type() { + for instr in vec![ + Bytecode::ImmBorrowGlobalDeprecated(StructDefinitionIndex(0)), + Bytecode::MutBorrowGlobalDeprecated(StructDefinitionIndex(0)), + ] { + let code = vec![Bytecode::CopyLoc(0), instr]; + let mut module = make_module_with_local(code, SignatureToken::Address); + add_simple_struct_with_abilities(&mut module, AbilitySet::ALL); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); + } +} + +#[test] +fn test_borrow_global_deprecated_wrong_type() { + for instr in vec![ + Bytecode::ImmBorrowGlobalDeprecated(StructDefinitionIndex(0)), + Bytecode::MutBorrowGlobalDeprecated(StructDefinitionIndex(0)), + ] { + let code = vec![Bytecode::LdU64(42), instr]; + let mut module = make_module_with_local(code, SignatureToken::Address); + add_simple_struct_with_abilities(&mut module, AbilitySet::ALL); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::BORROWGLOBAL_TYPE_MISMATCH_ERROR + ); + } +} + +#[test] +fn test_borrow_global_deprecated_no_key() { + for instr in vec![ + Bytecode::ImmBorrowGlobalDeprecated(StructDefinitionIndex(0)), + Bytecode::MutBorrowGlobalDeprecated(StructDefinitionIndex(0)), + ] { + let code = vec![Bytecode::CopyLoc(0), instr]; + let mut module = make_module_with_local(code, SignatureToken::Address); + add_simple_struct_with_abilities(&mut module, AbilitySet::PRIMITIVES); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::BORROWGLOBAL_WITHOUT_KEY_ABILITY + ); + } +} + +#[test] +#[should_panic] +fn test_borrow_global_deprecated_no_arg() { + for instr in vec![ + Bytecode::ImmBorrowGlobalDeprecated(StructDefinitionIndex(0)), + Bytecode::MutBorrowGlobalDeprecated(StructDefinitionIndex(0)), + ] { + let code = vec![instr]; + let mut module = make_module_with_local(code, SignatureToken::Address); + add_simple_struct_with_abilities(&mut module, AbilitySet::ALL); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + } +} From f91cdf2f630e3711774fe16cd1e8a5fca7753e3a Mon Sep 17 00:00:00 2001 From: Valerii Huhnin Date: Wed, 4 Sep 2024 08:10:05 +0000 Subject: [PATCH 43/52] tests for `MoveToDeprecated` instructions --- .../src/type_safety_tests/mod.rs | 106 ++++++++++++++++++ 1 file changed, 106 insertions(+) diff --git a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs index 6fe6c385a0..0eec1e3296 100644 --- a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs +++ b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs @@ -2245,6 +2245,112 @@ fn test_move_from_deprecated_no_arg() { let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); } +#[test] +fn test_move_to_deprecated_correct_type() { + let code = vec![ + Bytecode::ImmBorrowLoc(0), + Bytecode::LdU32(42), + Bytecode::Pack(StructDefinitionIndex(0)), + Bytecode::MoveToDeprecated(StructDefinitionIndex(0)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Signer); + add_simple_struct_with_abilities(&mut module, AbilitySet::ALL); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); +} + +#[test] +fn test_move_to_deprecated_mismatched_types() { + let code = vec![ + Bytecode::ImmBorrowLoc(0), + Bytecode::LdU32(42), + Bytecode::MoveToDeprecated(StructDefinitionIndex(0)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Signer); + add_simple_struct_with_abilities(&mut module, AbilitySet::ALL); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::MOVETO_TYPE_MISMATCH_ERROR + ); +} + +#[test] +fn test_move_to_deprecated_wrong_type() { + let code = vec![ + Bytecode::MutBorrowLoc(0), + Bytecode::LdU32(42), + Bytecode::Pack(StructDefinitionIndex(0)), + Bytecode::MoveToDeprecated(StructDefinitionIndex(0)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Signer); + add_simple_struct_with_abilities(&mut module, AbilitySet::ALL); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::MOVETO_TYPE_MISMATCH_ERROR + ); + + let code = vec![ + Bytecode::ImmBorrowLoc(0), + Bytecode::LdU32(42), + Bytecode::Pack(StructDefinitionIndex(0)), + Bytecode::MoveToDeprecated(StructDefinitionIndex(0)), + ]; + let mut module = make_module_with_local(code, SignatureToken::U32); + add_simple_struct_with_abilities(&mut module, AbilitySet::ALL); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::MOVETO_TYPE_MISMATCH_ERROR + ); +} + +#[test] +fn test_move_to_deprecated_no_key() { + let code = vec![ + Bytecode::ImmBorrowLoc(0), + Bytecode::LdU32(42), + Bytecode::Pack(StructDefinitionIndex(0)), + Bytecode::MoveToDeprecated(StructDefinitionIndex(0)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Signer); + add_simple_struct_with_abilities(&mut module, AbilitySet::PRIMITIVES); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::MOVETO_WITHOUT_KEY_ABILITY + ); +} + +#[test] +#[should_panic] +fn test_move_to_too_few_args() { + let code = vec![ + Bytecode::ImmBorrowLoc(0), + Bytecode::MoveToDeprecated(StructDefinitionIndex(0)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Signer); + add_simple_struct_with_abilities(&mut module, AbilitySet::ALL); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); +} + +#[test] +#[should_panic] +fn test_move_to_deprecated_no_arg() { + let code = vec![Bytecode::MoveToDeprecated(StructDefinitionIndex(0))]; + let mut module = make_module_with_local(code, SignatureToken::Signer); + add_simple_struct_with_abilities(&mut module, AbilitySet::ALL); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); +} + #[test] fn test_borrow_global_deprecated_correct_type() { for instr in vec![ From 6ee23f8217991bc0262776026982002e05372a4d Mon Sep 17 00:00:00 2001 From: Valerii Huhnin Date: Thu, 5 Sep 2024 23:46:43 +0000 Subject: [PATCH 44/52] tests for `CallGeneric` instruction --- .../src/type_safety_tests/mod.rs | 87 ++++++++++++++++++- 1 file changed, 85 insertions(+), 2 deletions(-) diff --git a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs index 0eec1e3296..47cefdcb64 100644 --- a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs +++ b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs @@ -8,8 +8,9 @@ use move_core_types::{u256::U256, vm_status::StatusCode}; use move_binary_format::{ file_format::{ AbilitySet, Constant, ConstantPoolIndex, FieldDefinition, FieldHandle, FieldHandleIndex, - FunctionHandleIndex, Signature, SignatureToken, StructDefinition, StructFieldInformation, - StructHandle, StructHandleIndex, TypeSignature, + FunctionHandleIndex, FunctionInstantiation, FunctionInstantiationIndex, Signature, + SignatureToken, StructDefinition, StructFieldInformation, StructHandle, StructHandleIndex, + TypeSignature, }, CompiledModule, }; @@ -103,6 +104,39 @@ fn add_function_with_parameters(module: &mut CompiledModule, parameters: Signatu module.function_defs.push(fun_def); } +fn add_generic_function_with_parameters( + module: &mut CompiledModule, + type_parameter: SignatureToken, +) { + let fun_def = FunctionDefinition { + code: None, + ..Default::default() + }; + + let fun_handle = FunctionHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(0), + parameters: SignatureIndex(3), + return_: SignatureIndex(4), + type_parameters: vec![AbilitySet::PRIMITIVES], + }; + + let fun_inst = FunctionInstantiation { + handle: FunctionHandleIndex(1), + type_parameters: SignatureIndex(2), + }; + + module.signatures.push(Signature(vec![type_parameter])); + module + .signatures + .push(Signature(vec![SignatureToken::TypeParameter(0)])); + module.signatures.push(Signature(vec![])); + + module.function_handles.push(fun_handle); + module.function_defs.push(fun_def); + module.function_instantiations.push(fun_inst); +} + fn add_native_struct(module: &mut CompiledModule) { let struct_def = StructDefinition { struct_handle: StructHandleIndex(0), @@ -1434,6 +1468,55 @@ fn test_call_too_few_args() { let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); } +#[test] +fn test_call_generic_correct_types() { + let code = vec![ + Bytecode::LdU32(42), + Bytecode::CallGeneric(FunctionInstantiationIndex(0)), + ]; + let mut module = make_module(code); + add_generic_function_with_parameters(&mut module, SignatureToken::U32); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); + + let code = vec![ + Bytecode::LdU64(51), + Bytecode::CallGeneric(FunctionInstantiationIndex(0)), + ]; + let mut module = make_module(code); + add_generic_function_with_parameters(&mut module, SignatureToken::U64); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); +} + +#[test] +fn test_call_generic_wrong_types() { + let code = vec![ + Bytecode::LdTrue, + Bytecode::CallGeneric(FunctionInstantiationIndex(0)), + ]; + let mut module = make_module(code); + add_generic_function_with_parameters(&mut module, SignatureToken::U32); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::CALL_TYPE_MISMATCH_ERROR + ); +} + +#[test] +#[should_panic] +fn test_call_generic_too_few_args() { + let code = vec![Bytecode::CallGeneric(FunctionInstantiationIndex(0))]; + let mut module = make_module(code); + add_generic_function_with_parameters(&mut module, SignatureToken::U32); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); +} + #[test] fn test_vec_pack_correct_type() { let code = vec![ From 662a5fa0eb60908cf68abf3914c925405318aeee Mon Sep 17 00:00:00 2001 From: Valerii Huhnin Date: Fri, 6 Sep 2024 06:38:29 +0000 Subject: [PATCH 45/52] tests for `PackGeneric` and `UnpackGeneric` --- .../src/type_safety_tests/mod.rs | 160 +++++++++++++++++- 1 file changed, 159 insertions(+), 1 deletion(-) diff --git a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs index 47cefdcb64..e848a94c44 100644 --- a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs +++ b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs @@ -9,7 +9,8 @@ use move_binary_format::{ file_format::{ AbilitySet, Constant, ConstantPoolIndex, FieldDefinition, FieldHandle, FieldHandleIndex, FunctionHandleIndex, FunctionInstantiation, FunctionInstantiationIndex, Signature, - SignatureToken, StructDefinition, StructFieldInformation, StructHandle, StructHandleIndex, + SignatureToken, StructDefInstantiation, StructDefInstantiationIndex, StructDefinition, + StructFieldInformation, StructHandle, StructHandleIndex, StructTypeParameter, TypeSignature, }, CompiledModule, @@ -196,6 +197,46 @@ fn add_simple_struct(module: &mut CompiledModule) { ]; } +fn add_simple_struct_generic_with_abilities( + module: &mut CompiledModule, + abilities: AbilitySet, + type_parameter: SignatureToken, +) { + let struct_def = StructDefinition { + struct_handle: StructHandleIndex(0), + field_information: StructFieldInformation::Declared(vec![FieldDefinition { + name: IdentifierIndex(5), + signature: TypeSignature(SignatureToken::TypeParameter(0)), + }]), + }; + + let struct_handle = StructHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(0), + abilities: abilities, + type_parameters: vec![StructTypeParameter { + constraints: AbilitySet::PRIMITIVES, + is_phantom: false, + }], + }; + + module.struct_defs.push(struct_def); + module.struct_handles.push(struct_handle); + module + .struct_def_instantiations + .push(StructDefInstantiation { + def: StructDefinitionIndex(0), + type_parameters: SignatureIndex(2), + }); + + module.signatures.push(Signature(vec![type_parameter])); + + module.field_handles = vec![FieldHandle { + owner: StructDefinitionIndex(0), + field: 0, + }]; +} + fn add_simple_struct_with_abilities(module: &mut CompiledModule, abilities: AbilitySet) { let struct_def = StructDefinition { struct_handle: StructHandleIndex(0), @@ -811,6 +852,71 @@ fn test_pack_too_few_args() { let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); } +#[test] +fn test_pack_generic_correct_types() { + let code = vec![ + Bytecode::LdU32(42), + Bytecode::PackGeneric(StructDefInstantiationIndex(0)), + ]; + let mut module: CompiledModule = make_module(code); + add_simple_struct_generic_with_abilities( + &mut module, + AbilitySet::PRIMITIVES, + SignatureToken::U32, + ); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); + + let code = vec![ + Bytecode::LdU64(42), + Bytecode::PackGeneric(StructDefInstantiationIndex(0)), + ]; + let mut module: CompiledModule = make_module(code); + add_simple_struct_generic_with_abilities( + &mut module, + AbilitySet::PRIMITIVES, + SignatureToken::U64, + ); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); +} + +#[test] +fn test_pack_generic_mismatched_types() { + let code = vec![ + Bytecode::LdU64(42), + Bytecode::PackGeneric(StructDefInstantiationIndex(0)), + ]; + let mut module: CompiledModule = make_module(code); + add_simple_struct_generic_with_abilities( + &mut module, + AbilitySet::PRIMITIVES, + SignatureToken::U32, + ); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::PACK_TYPE_MISMATCH_ERROR + ); +} + +#[test] +#[should_panic] +fn test_pack_generic_too_few_args() { + let code = vec![Bytecode::PackGeneric(StructDefInstantiationIndex(0))]; + let mut module: CompiledModule = make_module(code); + add_simple_struct_generic_with_abilities( + &mut module, + AbilitySet::PRIMITIVES, + SignatureToken::U32, + ); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); +} + #[test] fn test_unpack_correct_types() { let code = vec![ @@ -852,6 +958,58 @@ fn test_unpack_no_arg() { let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); } +#[test] +fn test_unpack_generic_correct_types() { + let code = vec![ + Bytecode::LdU32(42), + Bytecode::PackGeneric(StructDefInstantiationIndex(0)), + Bytecode::UnpackGeneric(StructDefInstantiationIndex(0)), + ]; + let mut module: CompiledModule = make_module(code); + add_simple_struct_generic_with_abilities( + &mut module, + AbilitySet::PRIMITIVES, + SignatureToken::U32, + ); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); +} + +#[test] +fn test_unpack_generic_wrong_type() { + let code = vec![ + Bytecode::LdU32(42), + Bytecode::UnpackGeneric(StructDefInstantiationIndex(0)), + ]; + let mut module: CompiledModule = make_module(code); + add_simple_struct_generic_with_abilities( + &mut module, + AbilitySet::PRIMITIVES, + SignatureToken::U32, + ); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::UNPACK_TYPE_MISMATCH_ERROR + ); +} + +#[test] +#[should_panic] +fn test_unpack_generic_no_arg() { + let code = vec![Bytecode::UnpackGeneric(StructDefInstantiationIndex(0))]; + let mut module: CompiledModule = make_module(code); + add_simple_struct_generic_with_abilities( + &mut module, + AbilitySet::PRIMITIVES, + SignatureToken::U32, + ); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); +} + #[test] fn test_eq_neq_correct_types() { for instr in vec![Bytecode::Eq, Bytecode::Neq] { From 689cf60136df9664707eb96f878ec2431785c4e5 Mon Sep 17 00:00:00 2001 From: Valerii Huhnin Date: Fri, 6 Sep 2024 06:47:33 +0000 Subject: [PATCH 46/52] tests for `ExistsGenericDeprecated` instruction --- .../src/type_safety_tests/mod.rs | 101 ++++++++++++++---- 1 file changed, 81 insertions(+), 20 deletions(-) diff --git a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs index e848a94c44..b102b6e823 100644 --- a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs +++ b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs @@ -197,6 +197,26 @@ fn add_simple_struct(module: &mut CompiledModule) { ]; } +fn add_simple_struct_with_abilities(module: &mut CompiledModule, abilities: AbilitySet) { + let struct_def = StructDefinition { + struct_handle: StructHandleIndex(0), + field_information: StructFieldInformation::Declared(vec![FieldDefinition { + name: IdentifierIndex(5), + signature: TypeSignature(SignatureToken::U32), + }]), + }; + + let struct_handle = StructHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(0), + abilities: abilities, + type_parameters: vec![], + }; + + module.struct_defs.push(struct_def); + module.struct_handles.push(struct_handle); +} + fn add_simple_struct_generic_with_abilities( module: &mut CompiledModule, abilities: AbilitySet, @@ -237,26 +257,6 @@ fn add_simple_struct_generic_with_abilities( }]; } -fn add_simple_struct_with_abilities(module: &mut CompiledModule, abilities: AbilitySet) { - let struct_def = StructDefinition { - struct_handle: StructHandleIndex(0), - field_information: StructFieldInformation::Declared(vec![FieldDefinition { - name: IdentifierIndex(5), - signature: TypeSignature(SignatureToken::U32), - }]), - }; - - let struct_handle = StructHandle { - module: ModuleHandleIndex(0), - name: IdentifierIndex(0), - abilities: abilities, - type_parameters: vec![], - }; - - module.struct_defs.push(struct_def); - module.struct_handles.push(struct_handle); -} - fn get_fun_context(module: &CompiledModule) -> FunctionContext { FunctionContext::new( &module, @@ -2431,6 +2431,67 @@ fn test_exists_deprecated_no_arg() { let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); } +#[test] +fn test_exists_generic_deprecated_correct_type() { + let code = vec![ + Bytecode::CopyLoc(0), + Bytecode::ExistsGenericDeprecated(StructDefInstantiationIndex(0)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Address); + add_simple_struct_generic_with_abilities(&mut module, AbilitySet::ALL, SignatureToken::U32); + let fun_context: FunctionContext<'_> = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); +} + +#[test] +fn test_exists_generic_deprecated_wrong_type() { + let code = vec![ + Bytecode::LdU64(42), + Bytecode::ExistsGenericDeprecated(StructDefInstantiationIndex(0)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Address); + add_simple_struct_generic_with_abilities(&mut module, AbilitySet::ALL, SignatureToken::U32); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::EXISTS_WITHOUT_KEY_ABILITY_OR_BAD_ARGUMENT + ); +} + +#[test] +fn test_exists_generic_deprecated_no_key() { + let code = vec![ + Bytecode::CopyLoc(0), + Bytecode::ExistsGenericDeprecated(StructDefInstantiationIndex(0)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Address); + add_simple_struct_generic_with_abilities( + &mut module, + AbilitySet::PRIMITIVES, + SignatureToken::U32, + ); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::EXISTS_WITHOUT_KEY_ABILITY_OR_BAD_ARGUMENT + ); +} + +#[test] +#[should_panic] +fn test_exists_generic_deprecated_no_arg() { + let code = vec![Bytecode::ExistsGenericDeprecated( + StructDefInstantiationIndex(0), + )]; + let mut module = make_module_with_local(code, SignatureToken::Address); + add_simple_struct_generic_with_abilities(&mut module, AbilitySet::ALL, SignatureToken::U32); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); +} + #[test] fn test_move_from_deprecated_correct_type() { let code = vec![ From 1a760f92b3c78fba42d5fd01370b866d6907592e Mon Sep 17 00:00:00 2001 From: Valerii Huhnin Date: Fri, 6 Sep 2024 06:48:04 +0000 Subject: [PATCH 47/52] tests for `MoveFromGenericDeprecated` instruction --- .../src/type_safety_tests/mod.rs | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs index b102b6e823..5d409867a4 100644 --- a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs +++ b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs @@ -2547,6 +2547,67 @@ fn test_move_from_deprecated_no_arg() { let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); } +#[test] +fn test_move_from_generic_deprecated_correct_type() { + let code = vec![ + Bytecode::CopyLoc(0), + Bytecode::MoveFromGenericDeprecated(StructDefInstantiationIndex(0)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Address); + add_simple_struct_generic_with_abilities(&mut module, AbilitySet::ALL, SignatureToken::U32); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); +} + +#[test] +fn test_move_from_generic_deprecated_wrong_type() { + let code = vec![ + Bytecode::LdU64(42), + Bytecode::MoveFromGenericDeprecated(StructDefInstantiationIndex(0)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Address); + add_simple_struct_generic_with_abilities(&mut module, AbilitySet::ALL, SignatureToken::U32); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::MOVEFROM_TYPE_MISMATCH_ERROR + ); +} + +#[test] +fn test_move_from_generic_deprecated_no_key() { + let code = vec![ + Bytecode::CopyLoc(0), + Bytecode::MoveFromGenericDeprecated(StructDefInstantiationIndex(0)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Address); + add_simple_struct_generic_with_abilities( + &mut module, + AbilitySet::PRIMITIVES, + SignatureToken::U32, + ); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::MOVEFROM_WITHOUT_KEY_ABILITY + ); +} + +#[test] +#[should_panic] +fn test_move_from_generic_deprecated_no_arg() { + let code = vec![Bytecode::MoveFromGenericDeprecated( + StructDefInstantiationIndex(0), + )]; + let mut module = make_module_with_local(code, SignatureToken::Address); + add_simple_struct_generic_with_abilities(&mut module, AbilitySet::ALL, SignatureToken::U32); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); +} + #[test] fn test_move_to_deprecated_correct_type() { let code = vec![ From ee84b11fcb63fba86df4cde1238c71f7e507d233 Mon Sep 17 00:00:00 2001 From: Valerii Huhnin Date: Fri, 6 Sep 2024 07:11:01 +0000 Subject: [PATCH 48/52] use the same number of signatures in `make_module` and its `with_local` variant for better compatibility with other functions --- .../src/type_safety_tests/mod.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs index 5d409867a4..e5c0957388 100644 --- a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs +++ b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs @@ -47,7 +47,7 @@ fn make_module_with_ret(code: Vec, return_: SignatureToken) -> Compile let mut module = empty_module(); module.function_handles.push(fun_handle); module.function_defs.push(fun_def); - module.signatures = vec![Signature(vec![]), Signature(vec![return_])]; + module.signatures = vec![Signature(vec![]), Signature(vec![return_]), Signature(vec![])]; module } @@ -93,8 +93,8 @@ fn add_function_with_parameters(module: &mut CompiledModule, parameters: Signatu let fun_handle = FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), - parameters: SignatureIndex(2), - return_: SignatureIndex(3), + parameters: SignatureIndex(3), + return_: SignatureIndex(4), type_parameters: vec![], }; @@ -117,14 +117,14 @@ fn add_generic_function_with_parameters( let fun_handle = FunctionHandle { module: ModuleHandleIndex(0), name: IdentifierIndex(0), - parameters: SignatureIndex(3), - return_: SignatureIndex(4), + parameters: SignatureIndex(4), + return_: SignatureIndex(5), type_parameters: vec![AbilitySet::PRIMITIVES], }; let fun_inst = FunctionInstantiation { handle: FunctionHandleIndex(1), - type_parameters: SignatureIndex(2), + type_parameters: SignatureIndex(3), }; module.signatures.push(Signature(vec![type_parameter])); @@ -246,7 +246,7 @@ fn add_simple_struct_generic_with_abilities( .struct_def_instantiations .push(StructDefInstantiation { def: StructDefinitionIndex(0), - type_parameters: SignatureIndex(2), + type_parameters: SignatureIndex(3), }); module.signatures.push(Signature(vec![type_parameter])); From 1e876a49513c454eacc7f18d9e4876a70e838c15 Mon Sep 17 00:00:00 2001 From: Valerii Huhnin Date: Fri, 6 Sep 2024 07:11:25 +0000 Subject: [PATCH 49/52] tests for `MoveToGenericDeprecated` instruction --- .../src/type_safety_tests/mod.rs | 112 ++++++++++++++++++ 1 file changed, 112 insertions(+) diff --git a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs index e5c0957388..90856491b7 100644 --- a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs +++ b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs @@ -2714,6 +2714,118 @@ fn test_move_to_deprecated_no_arg() { let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); } +#[test] +fn test_move_to_generic_deprecated_correct_type() { + let code = vec![ + Bytecode::ImmBorrowLoc(0), + Bytecode::LdU32(42), + Bytecode::PackGeneric(StructDefInstantiationIndex(0)), + Bytecode::MoveToGenericDeprecated(StructDefInstantiationIndex(0)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Signer); + add_simple_struct_generic_with_abilities(&mut module, AbilitySet::ALL, SignatureToken::U32); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); +} + +#[test] +fn test_move_to_generic_deprecated_mismatched_types() { + let code = vec![ + Bytecode::ImmBorrowLoc(0), + Bytecode::LdU32(42), + Bytecode::MoveToGenericDeprecated(StructDefInstantiationIndex(0)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Signer); + add_simple_struct_generic_with_abilities(&mut module, AbilitySet::ALL, SignatureToken::U32); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::MOVETO_TYPE_MISMATCH_ERROR + ); +} + +#[test] +fn test_move_to_generic_deprecated_wrong_type() { + let code = vec![ + Bytecode::MutBorrowLoc(0), + Bytecode::LdU32(42), + Bytecode::PackGeneric(StructDefInstantiationIndex(0)), + Bytecode::MoveToGenericDeprecated(StructDefInstantiationIndex(0)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Signer); + add_simple_struct_generic_with_abilities(&mut module, AbilitySet::ALL, SignatureToken::U32); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::MOVETO_TYPE_MISMATCH_ERROR + ); + + let code = vec![ + Bytecode::ImmBorrowLoc(0), + Bytecode::LdU32(42), + Bytecode::PackGeneric(StructDefInstantiationIndex(0)), + Bytecode::MoveToGenericDeprecated(StructDefInstantiationIndex(0)), + ]; + let mut module = make_module_with_local(code, SignatureToken::U32); + add_simple_struct_generic_with_abilities(&mut module, AbilitySet::ALL, SignatureToken::U32); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::MOVETO_TYPE_MISMATCH_ERROR + ); +} + +#[test] +fn test_move_to_generic_deprecated_no_key() { + let code = vec![ + Bytecode::ImmBorrowLoc(0), + Bytecode::LdU32(42), + Bytecode::PackGeneric(StructDefInstantiationIndex(0)), + Bytecode::MoveToGenericDeprecated(StructDefInstantiationIndex(0)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Signer); + add_simple_struct_generic_with_abilities( + &mut module, + AbilitySet::PRIMITIVES, + SignatureToken::U32, + ); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::MOVETO_WITHOUT_KEY_ABILITY + ); +} + +#[test] +#[should_panic] +fn test_move_to_generic_deprecated_too_few_args() { + let code = vec![ + Bytecode::ImmBorrowLoc(0), + Bytecode::MoveToGenericDeprecated(StructDefInstantiationIndex(0)), + ]; + let mut module = make_module_with_local(code, SignatureToken::Signer); + add_simple_struct_generic_with_abilities(&mut module, AbilitySet::ALL, SignatureToken::U32); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); +} + +#[test] +#[should_panic] +fn test_move_to_generic_deprecated_no_arg() { + let code = vec![Bytecode::MoveToGenericDeprecated( + StructDefInstantiationIndex(0), + )]; + let mut module = make_module_with_local(code, SignatureToken::Signer); + add_simple_struct_generic_with_abilities(&mut module, AbilitySet::ALL, SignatureToken::U32); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); +} + #[test] fn test_borrow_global_deprecated_correct_type() { for instr in vec![ From 3040986b3132b21c7d08d5f0de786bf1d73075a5 Mon Sep 17 00:00:00 2001 From: Valerii Huhnin Date: Fri, 6 Sep 2024 07:16:30 +0000 Subject: [PATCH 50/52] tests for `ImmBorrowGlobalGenericDeprecated` and `MutBorrowGlobalGenericDeprecated` --- .../src/type_safety_tests/mod.rs | 76 ++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) diff --git a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs index 90856491b7..1bb4ef8960 100644 --- a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs +++ b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs @@ -47,7 +47,11 @@ fn make_module_with_ret(code: Vec, return_: SignatureToken) -> Compile let mut module = empty_module(); module.function_handles.push(fun_handle); module.function_defs.push(fun_def); - module.signatures = vec![Signature(vec![]), Signature(vec![return_]), Signature(vec![])]; + module.signatures = vec![ + Signature(vec![]), + Signature(vec![return_]), + Signature(vec![]), + ]; module } @@ -2891,3 +2895,73 @@ fn test_borrow_global_deprecated_no_arg() { let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); } } + +#[test] +fn test_borrow_global_generic_deprecated_correct_type() { + for instr in vec![ + Bytecode::ImmBorrowGlobalGenericDeprecated(StructDefInstantiationIndex(0)), + Bytecode::MutBorrowGlobalGenericDeprecated(StructDefInstantiationIndex(0)), + ] { + let code = vec![Bytecode::CopyLoc(0), instr]; + let mut module = make_module_with_local(code, SignatureToken::Address); + add_simple_struct_generic_with_abilities(&mut module, AbilitySet::ALL, SignatureToken::U32); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); + } +} + +#[test] +fn test_borrow_global_generic_deprecated_wrong_type() { + for instr in vec![ + Bytecode::ImmBorrowGlobalGenericDeprecated(StructDefInstantiationIndex(0)), + Bytecode::MutBorrowGlobalGenericDeprecated(StructDefInstantiationIndex(0)), + ] { + let code = vec![Bytecode::LdU64(42), instr]; + let mut module = make_module_with_local(code, SignatureToken::Address); + add_simple_struct_generic_with_abilities(&mut module, AbilitySet::ALL, SignatureToken::U32); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::BORROWGLOBAL_TYPE_MISMATCH_ERROR + ); + } +} + +#[test] +fn test_borrow_global_generic_deprecated_no_key() { + for instr in vec![ + Bytecode::ImmBorrowGlobalGenericDeprecated(StructDefInstantiationIndex(0)), + Bytecode::MutBorrowGlobalGenericDeprecated(StructDefInstantiationIndex(0)), + ] { + let code = vec![Bytecode::CopyLoc(0), instr]; + let mut module = make_module_with_local(code, SignatureToken::Address); + add_simple_struct_generic_with_abilities( + &mut module, + AbilitySet::PRIMITIVES, + SignatureToken::U32, + ); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::BORROWGLOBAL_WITHOUT_KEY_ABILITY + ); + } +} + +#[test] +#[should_panic] +fn test_borrow_global_generic_deprecated_no_arg() { + for instr in vec![ + Bytecode::ImmBorrowGlobalGenericDeprecated(StructDefInstantiationIndex(0)), + Bytecode::MutBorrowGlobalGenericDeprecated(StructDefInstantiationIndex(0)), + ] { + let code = vec![instr]; + let mut module = make_module_with_local(code, SignatureToken::Address); + add_simple_struct_generic_with_abilities(&mut module, AbilitySet::ALL, SignatureToken::U32); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + } +} From 53ad165e68d3ae0221b39bb347fea0b49de236b9 Mon Sep 17 00:00:00 2001 From: Valerii Huhnin Date: Fri, 6 Sep 2024 07:57:49 +0000 Subject: [PATCH 51/52] tests for `ImmBorrowFieldGeneric` instruction --- .../src/type_safety_tests/mod.rs | 159 +++++++++++++++++- 1 file changed, 153 insertions(+), 6 deletions(-) diff --git a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs index 1bb4ef8960..3b4dcf1cdb 100644 --- a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs +++ b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs @@ -1,6 +1,7 @@ use move_binary_format::file_format::{ - empty_module, Bytecode, CodeUnit, FunctionDefinition, FunctionDefinitionIndex, FunctionHandle, - IdentifierIndex, ModuleHandleIndex, SignatureIndex, StructDefinitionIndex, + empty_module, Bytecode, CodeUnit, FieldInstantiationIndex, FunctionDefinition, + FunctionDefinitionIndex, FunctionHandle, IdentifierIndex, ModuleHandleIndex, SignatureIndex, + StructDefinitionIndex, }; use move_core_types::{u256::U256, vm_status::StatusCode}; @@ -8,10 +9,10 @@ use move_core_types::{u256::U256, vm_status::StatusCode}; use move_binary_format::{ file_format::{ AbilitySet, Constant, ConstantPoolIndex, FieldDefinition, FieldHandle, FieldHandleIndex, - FunctionHandleIndex, FunctionInstantiation, FunctionInstantiationIndex, Signature, - SignatureToken, StructDefInstantiation, StructDefInstantiationIndex, StructDefinition, - StructFieldInformation, StructHandle, StructHandleIndex, StructTypeParameter, - TypeSignature, + FieldInstantiation, FunctionHandleIndex, FunctionInstantiation, FunctionInstantiationIndex, + Signature, SignatureToken, StructDefInstantiation, StructDefInstantiationIndex, + StructDefinition, StructFieldInformation, StructHandle, StructHandleIndex, + StructTypeParameter, TypeSignature, }, CompiledModule, }; @@ -164,6 +165,44 @@ fn add_native_struct(module: &mut CompiledModule) { }]; } +fn add_native_struct_generic(module: &mut CompiledModule, type_parameter: SignatureToken) { + let struct_def = StructDefinition { + struct_handle: StructHandleIndex(0), + field_information: StructFieldInformation::Native, + }; + + let struct_handle = StructHandle { + module: ModuleHandleIndex(0), + name: IdentifierIndex(0), + abilities: AbilitySet::EMPTY, + type_parameters: vec![StructTypeParameter { + constraints: AbilitySet::PRIMITIVES, + is_phantom: false, + }], + }; + + module.struct_defs.push(struct_def); + module.struct_handles.push(struct_handle); + module + .struct_def_instantiations + .push(StructDefInstantiation { + def: StructDefinitionIndex(0), + type_parameters: SignatureIndex(3), + }); + + module.signatures.push(Signature(vec![type_parameter])); + + module.field_handles = vec![FieldHandle { + owner: StructDefinitionIndex(0), + field: 0, + }]; + + module.field_instantiations.push(FieldInstantiation { + handle: FieldHandleIndex(0), + type_parameters: SignatureIndex(3), + }); +} + fn add_simple_struct(module: &mut CompiledModule) { let struct_def = StructDefinition { struct_handle: StructHandleIndex(0), @@ -259,6 +298,11 @@ fn add_simple_struct_generic_with_abilities( owner: StructDefinitionIndex(0), field: 0, }]; + + module.field_instantiations.push(FieldInstantiation { + handle: FieldHandleIndex(0), + type_parameters: SignatureIndex(3), + }); } fn get_fun_context(module: &CompiledModule) -> FunctionContext { @@ -1472,6 +1516,109 @@ fn test_imm_borrow_field_no_arg() { let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); } +#[test] +fn test_imm_borrow_field_generic_correct_type() { + let code = vec![ + Bytecode::ImmBorrowLoc(0), + Bytecode::ImmBorrowFieldGeneric(FieldInstantiationIndex(0)), + ]; + let signature = SignatureToken::StructInstantiation(Box::new(( + StructHandleIndex(0), + vec![SignatureToken::U64], + ))); + let mut module: CompiledModule = make_module_with_local(code, signature); + add_simple_struct_generic_with_abilities( + &mut module, + AbilitySet::PRIMITIVES, + SignatureToken::U64, + ); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); +} + +#[test] +fn test_imm_borrow_field_generic_wrong_type() { + let code = vec![ + Bytecode::LdTrue, + Bytecode::ImmBorrowFieldGeneric(FieldInstantiationIndex(0)), + ]; + let signature = SignatureToken::StructInstantiation(Box::new(( + StructHandleIndex(0), + vec![SignatureToken::U64], + ))); + let mut module = make_module_with_local(code, signature); + add_simple_struct_generic_with_abilities( + &mut module, + AbilitySet::PRIMITIVES, + SignatureToken::U64, + ); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::BORROWFIELD_TYPE_MISMATCH_ERROR + ); +} + +#[test] +fn test_imm_borrow_field_generic_mismatched_types() { + let code = vec![ + Bytecode::ImmBorrowLoc(0), + Bytecode::ImmBorrowFieldGeneric(FieldInstantiationIndex(0)), + ]; + let mut module = make_module_with_local(code, SignatureToken::U64); + add_simple_struct_generic_with_abilities( + &mut module, + AbilitySet::PRIMITIVES, + SignatureToken::U64, + ); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::BORROWFIELD_TYPE_MISMATCH_ERROR + ); +} + +#[test] +fn test_imm_borrow_field_generic_bad_field() { + let code = vec![ + Bytecode::ImmBorrowLoc(0), + Bytecode::ImmBorrowFieldGeneric(FieldInstantiationIndex(0)), + ]; + let signature = SignatureToken::StructInstantiation(Box::new(( + StructHandleIndex(0), + vec![SignatureToken::U64], + ))); + let mut module = make_module_with_local(code, signature); + add_native_struct_generic(&mut module, SignatureToken::U64); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::BORROWFIELD_BAD_FIELD_ERROR + ); +} + +#[test] +#[should_panic] +fn test_imm_borrow_field_generic_no_arg() { + let code = vec![Bytecode::ImmBorrowFieldGeneric(FieldInstantiationIndex(0))]; + let signature = SignatureToken::StructInstantiation(Box::new(( + StructHandleIndex(0), + vec![SignatureToken::U64], + ))); + let mut module = make_module_with_local(code, signature); + add_simple_struct_generic_with_abilities( + &mut module, + AbilitySet::PRIMITIVES, + SignatureToken::U64, + ); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); +} + #[test] fn test_mut_borrow_field_correct_type() { let code = vec![ From 156cb98470a1bfa2aedde05a28992d844a421d51 Mon Sep 17 00:00:00 2001 From: Valerii Huhnin Date: Fri, 6 Sep 2024 08:03:16 +0000 Subject: [PATCH 52/52] tests for `MutBorrowFieldGeneric` instruction --- .../src/type_safety_tests/mod.rs | 124 ++++++++++++++++++ 1 file changed, 124 insertions(+) diff --git a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs index 3b4dcf1cdb..0b84f68825 100644 --- a/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs +++ b/crates/move-bytecode-verifier/src/type_safety_tests/mod.rs @@ -1703,6 +1703,130 @@ fn test_mut_borrow_field_no_arg() { let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); } +#[test] +fn test_mut_borrow_field_generic_correct_type() { + let code = vec![ + Bytecode::MutBorrowLoc(0), + Bytecode::MutBorrowFieldGeneric(FieldInstantiationIndex(0)), + ]; + let signature = SignatureToken::StructInstantiation(Box::new(( + StructHandleIndex(0), + vec![SignatureToken::U64], + ))); + let mut module = make_module_with_local(code, signature); + add_simple_struct_generic_with_abilities( + &mut module, + AbilitySet::PRIMITIVES, + SignatureToken::U64, + ); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert!(result.is_ok()); +} + +#[test] +fn test_mut_borrow_field_generic_wrong_type() { + let code = vec![ + Bytecode::LdTrue, + Bytecode::MutBorrowFieldGeneric(FieldInstantiationIndex(0)), + ]; + let signature = SignatureToken::StructInstantiation(Box::new(( + StructHandleIndex(0), + vec![SignatureToken::U64], + ))); + let mut module = make_module_with_local(code, signature); + add_simple_struct_generic_with_abilities( + &mut module, + AbilitySet::PRIMITIVES, + SignatureToken::U64, + ); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::BORROWFIELD_TYPE_MISMATCH_ERROR + ); + + let code = vec![ + Bytecode::ImmBorrowLoc(0), + Bytecode::MutBorrowFieldGeneric(FieldInstantiationIndex(0)), + ]; + let signature = SignatureToken::StructInstantiation(Box::new(( + StructHandleIndex(0), + vec![SignatureToken::U64], + ))); + let mut module = make_module_with_local(code, signature); + add_simple_struct_generic_with_abilities( + &mut module, + AbilitySet::PRIMITIVES, + SignatureToken::U64, + ); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::BORROWFIELD_TYPE_MISMATCH_ERROR + ); +} + +#[test] +fn test_mut_borrow_field_generic_mismatched_types() { + let code = vec![ + Bytecode::MutBorrowLoc(0), + Bytecode::MutBorrowFieldGeneric(FieldInstantiationIndex(0)), + ]; + let mut module: CompiledModule = make_module_with_local(code, SignatureToken::U64); + add_simple_struct_generic_with_abilities( + &mut module, + AbilitySet::PRIMITIVES, + SignatureToken::U64, + ); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::BORROWFIELD_TYPE_MISMATCH_ERROR + ); +} + +#[test] +fn test_mut_borrow_field_generic_bad_field() { + let code = vec![ + Bytecode::MutBorrowLoc(0), + Bytecode::MutBorrowFieldGeneric(FieldInstantiationIndex(0)), + ]; + let signature = SignatureToken::StructInstantiation(Box::new(( + StructHandleIndex(0), + vec![SignatureToken::U64], + ))); + let mut module = make_module_with_local(code, signature); + add_native_struct_generic(&mut module, SignatureToken::U64); + let fun_context = get_fun_context(&module); + let result = type_safety::verify(&module, &fun_context, &mut DummyMeter); + assert_eq!( + result.unwrap_err().major_status(), + StatusCode::BORROWFIELD_BAD_FIELD_ERROR + ); +} + +#[test] +#[should_panic] +fn test_mut_borrow_field_generic_no_arg() { + let code = vec![Bytecode::MutBorrowFieldGeneric(FieldInstantiationIndex(0))]; + let signature = SignatureToken::StructInstantiation(Box::new(( + StructHandleIndex(0), + vec![SignatureToken::U64], + ))); + let mut module = make_module_with_local(code, signature); + add_simple_struct_generic_with_abilities( + &mut module, + AbilitySet::PRIMITIVES, + SignatureToken::U64, + ); + let fun_context = get_fun_context(&module); + let _result = type_safety::verify(&module, &fun_context, &mut DummyMeter); +} + #[test] fn test_ret_correct_type() { let code = vec![Bytecode::LdU32(42), Bytecode::Ret];