Module puffin::algebra::dynamic_function

source ·
Expand description

This module provides traits for calling rust functions dynamically.

All functions which implement the DynamicFunction trait can be called by passing an array of EvaluatedTerms to it. The return value is again of type EvaluatedTerm.

Rust is a statically typed language. That means the compiler would be able to statically verify that a term evaluates without any type errors.

While this is generally an advance, in the case of our fuzzer this is not very helpful. The fuzzer should be able to mutate the term trees arbitrarily. Of course, we also have to check for the types during runtime. If types are not compatible then, the evaluation of the term will fail. But this is not something that can be done during compile time. Therefore, we introduced a trait for dynamically typed functions on top of statically typed Rust functions.

Each function which implements the following trait can be made into a dynamic function:

use puffin::algebra::error::FnError;

type ConcreteFunction<A1, A2, A3, R> = dyn Fn(A1, A2, A3) -> Result<R, FnError>;

where A1, A2, A3 are argument types and R is the return type. From these statically typed function we can generate dynamically types ones which implement the following trait:

use std::any::Any;

use puffin::algebra::error::FnError;
use puffin::protocol::{EvaluatedTerm, ProtocolTypes};

pub trait DynamicFunction<PT: ProtocolTypes>:
    Fn(&Vec<Box<dyn EvaluatedTerm<PT>>>) -> Result<Box<dyn EvaluatedTerm<PT>>, FnError>
{
}

Note, that both functions return a Result and therefore can gracefully fail.

DynamicFunctions can be called with an array of any type implementing the EvaluatedTerm trait. The result must also implement EvaluatedTerm. Rust offers a unique ID for each type. Using this type we can check during runtime whether types are available. The types of each variable, constant and function are preserved and stored alongside the DynamicFunction.

The following function is a simple example for a constant:

use puffin::algebra::error::FnError;

pub fn fn_some_value() -> Result<u32, FnError> {
    Ok(42)
}

It returns one possibility for the cipher suites which could be sent during a ClientHello.

Macros§

Structs§

Traits§

  • This trait is implemented for function traits in order to:
  • Cloneable type for dynamic functions. This trait is automatically implemented for arbitrary closures and functions of the form: Fn(&Vec<Box<dyn Any>>) -> Box<dyn Any>

Functions§