use crate::{
metadata::{
tables::{
CodedIndex, CodedIndexType, MethodDefRaw, TableDataOwned, TableId, TypeAttributes,
TypeDefRaw,
},
token::Token,
},
test::{create_test_assembly, get_testfile_mscorlib, TestAssembly},
Error, Result,
};
pub fn owned_ownership_validator_file_factory() -> Result<Vec<TestAssembly>> {
let mut assemblies = Vec::new();
let Some(clean_testfile) = get_testfile_mscorlib() else {
return Err(Error::Other(
"mscorlib.dll not available - test cannot run".to_string(),
));
};
assemblies.push(TestAssembly::new(&clean_testfile, true));
assemblies.push(create_assembly_with_broken_method_ownership()?);
assemblies.push(create_assembly_with_invalid_method_accessibility()?);
assemblies.push(create_assembly_with_invalid_static_constructor()?);
Ok(assemblies)
}
pub fn create_assembly_with_broken_method_ownership() -> Result<TestAssembly> {
create_test_assembly(get_testfile_mscorlib, |assembly| {
let empty_method_name_index = assembly.string_add("")?;
let method_rid = assembly.original_table_row_count(TableId::MethodDef) + 1;
let invalid_method = MethodDefRaw {
rid: method_rid,
token: Token::new(0x06000000 + method_rid),
offset: 0,
rva: 0,
impl_flags: 0,
flags: 0x0006, name: empty_method_name_index.placeholder(), signature: 1,
param_list: 1,
};
assembly.table_row_add(
TableId::MethodDef,
TableDataOwned::MethodDef(invalid_method),
)?;
let type_name_index = assembly.string_add("TestType")?;
let type_rid = assembly.original_table_row_count(TableId::TypeDef) + 1;
let invalid_type = TypeDefRaw {
rid: type_rid,
token: Token::new(0x02000000 + type_rid),
offset: 0,
flags: TypeAttributes::PUBLIC,
type_name: type_name_index.placeholder(),
type_namespace: 0,
extends: CodedIndex::new(TableId::TypeRef, 1, CodedIndexType::TypeDefOrRef),
field_list: 1,
method_list: method_rid, };
assembly.table_row_add(TableId::TypeDef, TableDataOwned::TypeDef(invalid_type))?;
Ok(())
})
}
pub fn create_assembly_with_invalid_method_accessibility() -> Result<TestAssembly> {
create_test_assembly(get_testfile_mscorlib, |assembly| {
let method_name_index = assembly.string_add("TestMethod")?;
let method_rid = assembly.original_table_row_count(TableId::MethodDef) + 1;
let invalid_method = MethodDefRaw {
rid: method_rid,
token: Token::new(0x06000000 + method_rid),
offset: 0,
rva: 0,
impl_flags: 0,
flags: 0x0008, name: method_name_index.placeholder(),
signature: 1,
param_list: 1,
};
assembly.table_row_add(
TableId::MethodDef,
TableDataOwned::MethodDef(invalid_method),
)?;
let type_name_index = assembly.string_add("TestType")?;
let type_rid = assembly.original_table_row_count(TableId::TypeDef) + 1;
let test_type = TypeDefRaw {
rid: type_rid,
token: Token::new(0x02000000 + type_rid),
offset: 0,
flags: TypeAttributes::PUBLIC,
type_name: type_name_index.placeholder(),
type_namespace: 0,
extends: CodedIndex::new(TableId::TypeRef, 1, CodedIndexType::TypeDefOrRef),
field_list: 1,
method_list: method_rid,
};
assembly.table_row_add(TableId::TypeDef, TableDataOwned::TypeDef(test_type))?;
Ok(())
})
}
pub fn create_assembly_with_invalid_static_constructor() -> Result<TestAssembly> {
create_test_assembly(get_testfile_mscorlib, |assembly| {
let cctor_name_index = assembly.string_add(".cctor")?;
let method_rid = assembly.original_table_row_count(TableId::MethodDef) + 1;
let invalid_cctor = MethodDefRaw {
rid: method_rid,
token: Token::new(0x06000000 + method_rid),
offset: 0,
rva: 0,
impl_flags: 0,
flags: 0x0006, name: cctor_name_index.placeholder(),
signature: 1,
param_list: 1,
};
assembly.table_row_add(TableId::MethodDef, TableDataOwned::MethodDef(invalid_cctor))?;
let type_name_index = assembly.string_add("TestType")?;
let type_rid = assembly.original_table_row_count(TableId::TypeDef) + 1;
let test_type = TypeDefRaw {
rid: type_rid,
token: Token::new(0x02000000 + type_rid),
offset: 0,
flags: TypeAttributes::PUBLIC,
type_name: type_name_index.placeholder(),
type_namespace: 0,
extends: CodedIndex::new(TableId::TypeRef, 1, CodedIndexType::TypeDefOrRef),
field_list: 1,
method_list: method_rid,
};
assembly.table_row_add(TableId::TypeDef, TableDataOwned::TypeDef(test_type))?;
Ok(())
})
}