use crate::{
metadata::{
tables::{
CodedIndex, CodedIndexType, GenericParamBuilder, GenericParamConstraintRaw,
TableDataOwned, TableId, TypeDefBuilder,
},
token::Token,
},
test::{create_test_assembly_with_error, get_testfile_wb, TestAssembly},
Error, Result,
};
pub fn raw_generic_constraint_validator_file_factory() -> Result<Vec<TestAssembly>> {
let mut assemblies = Vec::new();
let Some(clean_testfile) = get_testfile_wb() else {
return Err(Error::Other(
"WindowsBase.dll not available - test cannot run".to_string(),
));
};
assemblies.push(TestAssembly::new(&clean_testfile, true));
assemblies.push(create_assembly_with_invalid_parameter_flags()?);
assemblies.push(create_assembly_with_null_constraint_owner()?);
assemblies.push(create_assembly_with_constraint_owner_exceeding_bounds()?);
Ok(assemblies)
}
pub fn create_assembly_with_null_constraint_owner() -> Result<TestAssembly> {
create_test_assembly_with_error(get_testfile_wb, "Malformed", |assembly| {
let typedef_token = TypeDefBuilder::new()
.name("GenericType")
.namespace("Test")
.flags(0x00100000)
.build(assembly)?;
let owner = CodedIndex::new(
TableId::TypeDef,
typedef_token.placeholder(),
CodedIndexType::TypeOrMethodDef,
);
let _generic_param_token = GenericParamBuilder::new()
.number(0)
.flags(0x0000)
.owner(owner)
.name("T")
.build(assembly)?;
let invalid_constraint = GenericParamConstraintRaw {
owner: 0, constraint: CodedIndex::new(
TableId::TypeDef,
typedef_token.placeholder(),
CodedIndexType::TypeDefOrRef,
),
rid: 1,
token: Token::new(0x2C000001), offset: 0,
};
assembly.table_row_add(
TableId::GenericParamConstraint,
TableDataOwned::GenericParamConstraint(invalid_constraint),
)?;
Ok(())
})
}
pub fn create_assembly_with_constraint_owner_exceeding_bounds() -> Result<TestAssembly> {
create_test_assembly_with_error(get_testfile_wb, "Malformed", |assembly| {
let typedef_token = TypeDefBuilder::new()
.name("GenericType")
.namespace("Test")
.flags(0x00100000)
.build(assembly)?;
let owner = CodedIndex::new(
TableId::TypeDef,
typedef_token.placeholder(),
CodedIndexType::TypeOrMethodDef,
);
let _generic_param_token = GenericParamBuilder::new()
.number(0)
.flags(0x0000)
.owner(owner)
.name("T")
.build(assembly)?;
let invalid_constraint = GenericParamConstraintRaw {
owner: 0xFFFF, constraint: CodedIndex::new(
TableId::TypeDef,
typedef_token.placeholder(),
CodedIndexType::TypeDefOrRef,
),
rid: 1,
token: Token::new(0x2C000001), offset: 0,
};
assembly.table_row_add(
TableId::GenericParamConstraint,
TableDataOwned::GenericParamConstraint(invalid_constraint),
)?;
Ok(())
})
}
pub fn create_assembly_with_invalid_parameter_flags() -> Result<TestAssembly> {
create_test_assembly_with_error(get_testfile_wb, "Malformed", |assembly| {
let typedef_builder = TypeDefBuilder::new()
.name("GenericType")
.namespace("Test")
.flags(0x00100000);
let typedef_token = typedef_builder.build(assembly)?;
let owner = CodedIndex::new(
TableId::TypeDef,
typedef_token.placeholder(),
CodedIndexType::TypeOrMethodDef,
);
GenericParamBuilder::new()
.number(0)
.flags(0x0003)
.owner(owner)
.name("T")
.build(assembly)?;
Ok(())
})
}