Skip to content

Support for validation and size limiting #14

@pzmarzly

Description

@pzmarzly

Right now if the raw bytes parse correctly, the next step in most applications is to validate (sanitize) the data. This being an additional step is a risk (programmer may forget about validation) and waste of resources (protocol has to parse all fields before sanitation can run). It may also result in unnecessary allocations - let's say our protocol accepts Vec<_> and someone sends us 8GB of data. protocol will download, parse and allocate 8GB Vec, which will be rejected by the next instruction like if vec.len() > 64 { return; }.

I imagine code could look like this:

#[derive(Protocol)]
pub struct User {
    pub name: String,
    pub pub_key: [u8; 64],
}

impl User {
    fn validate_name(name: String) -> bool { /* some code */ }
    fn validate_pub_key(pub_key: [u8; 64]) -> bool { /* some code */ }
}

User::parse( // or `User::validate_from_raw_bytes`
    &data,
    &protocol::Settings::default()
).unwrap();

Alternatively, protocol could generate trait, so we could have different ways of validating the same struct, and stateful validators:

#[derive(Protocol)]
pub struct User {
    pub name: String,
    pub pub_key: [u8; 64],
}

// protocol generates:
//
// trait UserValidate {
//     fn validate_name(&mut self, name: String) -> bool;
//     fn validate_pub_key(&mut self, pub_key: [u8; 64]) -> bool;
// }

struct UserBasicValidator;
impl UserValidate for UserBasicValidator {
    fn validate_name(&mut self, name: String) -> bool { /* some code */ }
    fn validate_pub_key(&mut self, pub_key: [u8; 64]) -> bool { /* some code */ }
}

User::parse(
    &data,
    &protocol::Settings::default(),
    UserBasicValidator::new(),
).unwrap();

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions