Safe Haskell | None |
---|---|

Language | Haskell2010 |

This module is used to mitigate several pitfalls with the capnproto format, which could potentially lead to denial of service vulnerabilities.

In particular, while they are illegal according to the spec, it is possible to encode objects which have many pointers pointing the same place, or even cycles. A naive traversal therefore could involve quite a lot of computation for a message that is very small on the wire.

Accordingly, most implementations of the format keep track of how many bytes of a message have been accessed, and start signaling errors after a certain value (the "traversal limit") has been reached. The Haskell implementation is no exception; this module implements that logic. We provide a monad transformer and mtl-style type class to track the limit; reading from the message happens inside of this monad.

## Synopsis

- class Monad m => MonadLimit m where
- data LimitT m a
- runLimitT :: MonadThrow m => Int -> LimitT m a -> m (a, Int)
- evalLimitT :: MonadThrow m => Int -> LimitT m a -> m a
- execLimitT :: MonadThrow m => Int -> LimitT m a -> m Int
- defaultLimit :: Int

# Documentation

class Monad m => MonadLimit m where Source #

mtl-style type class to track the traversal limit. This is used by other parts of the library which actually do the reading.

invoice :: Int -> m () Source #

deducts `invoice`

n`n`

from the traversal limit, signaling
an error if the limit is exhausted.

## Instances

MonadThrow m => MonadLimit (LimitT m) Source # | |

MonadLimit m => MonadLimit (StateT s m) Source # | |

MonadLimit m => MonadLimit (StateT s m) Source # | |

(Monoid w, MonadLimit m) => MonadLimit (WriterT w m) Source # | |

MonadLimit m => MonadLimit (ReaderT r m) Source # | |

(Monoid w, MonadLimit m) => MonadLimit (RWST r w s m) Source # | |

Monad transformer implementing `MonadLimit`

. The underlying monad
must implement `MonadThrow`

. `invoice`

calls

when the limit is exhausted.`throwM`

`TraversalLimitError`

## Instances

MonadTrans LimitT Source # | |

Defined in Data.Capnp.TraversalLimit | |

MonadState s m => MonadState s (LimitT m) Source # | |

Monad m => Monad (LimitT m) Source # | |

Functor m => Functor (LimitT m) Source # | |

Monad m => Applicative (LimitT m) Source # | |

MonadThrow m => MonadThrow (LimitT m) Source # | |

Defined in Data.Capnp.TraversalLimit | |

(PrimMonad m, s ~ PrimState m) => PrimMonad (LimitT m) Source # | |

MonadThrow m => MonadLimit (LimitT m) Source # | |

type PrimState (LimitT m) Source # | |

Defined in Data.Capnp.TraversalLimit type PrimState (LimitT m) = PrimState m |

runLimitT :: MonadThrow m => Int -> LimitT m a -> m (a, Int) Source #

Run a `LimitT`

, returning the value from the computation and the remaining
traversal limit.

evalLimitT :: MonadThrow m => Int -> LimitT m a -> m a Source #

Run a `LimitT`

, returning the value from the computation.

execLimitT :: MonadThrow m => Int -> LimitT m a -> m Int Source #

Run a `LimitT`

, returning the remaining traversal limit.

defaultLimit :: Int Source #

A sensible default traversal limit. Currently 64 MiB.