stacks-core
stacks-core copied to clipboard
`ContractName::try_from()` allows invalid `ContractName` to be created
Description
The ContractName struct is implemented using a macro, like this:
guarded_string!(
ContractName,
"ContractName",
CONTRACT_NAME_REGEX,
MAX_STRING_LEN,
RuntimeErrorType,
RuntimeErrorType::BadNameValue
);
MAX_STRING_LEN is 128, so it's possible to construct a ContractName with up to 128 characters. However, when we implement StacksMessageCodec for ContractName:
fn consensus_serialize<W: Write>(&self, fd: &mut W) -> Result<(), codec_error> {
if self.as_bytes().len() < CONTRACT_MIN_NAME_LENGTH as usize
|| self.as_bytes().len() > CONTRACT_MAX_NAME_LENGTH as usize
{
// Error!
}
// ...
}
CONTRACT_MAX_NAME_LENGTH is 40, much smaller than MAX_STRING_LEN. This means that ContractName::try_from() allows us to create structs that can't be serialized
Proposed solutions
- Change the macro to use
CONTRACT_MAX_NAME_LENGTHinstead ofMAX_STRING_LEN. This won't actually fix the problem, and will likely expose more invalidContractNames that were never being serialized, but it will make invalidContractNames easy to find and fix. Where it fails, we can replaceContractName::try_from()withContractName::from_truncated()orContractName::try_from_truncated() - Change
CONTRACT_MAX_NAME_LENGTHto matchMAX_STRING_LEN. Probably not what we want to do, but would fix the issue immediately
Related issues
- #4396