Quoting prasanth somasundar (2019-05-29 22:08:27)

> Thanks for the feedback. This is really helpful.

You're welcome.

> * Not supporting every feature/Optimize for well written schema
> Very interesting point. I'm not generally good at making those sorts of 
> concessions, but I probably should do that more often. I'll think about where 
> I can relax some of the requirements to allow a better API. If you have a 
> suggestion on any place in the API, let me know.

My advice: pin down some use cases that you care about. Once you have
actual requirements, those can help drive the design.

One bit of food for thought: you can't exactly mmap() in elm, and even
to get from bytes to `Array Int` you have to do some non-trivial
unmarshalling.  It may make as much sense to just bite the bullet and
parse the whole thing (deeply) into an idiomatic data type up front,
just like implementations protobufs; by the time you take into account
all of Elm's limitations, it's not clear to me how much keeping it in
the wire format like the C++ implementation does actually buys you.
Doing an up front parse solves a lot things, so if you go another
route, be clear on why.

> * 64-bit ints/Numeric library
> Yup, I’m aware. It's not particularly fun code to write (I find it boring at 
> least), but I think I'll have to build it either way.

It would make sense to publish this as a package by itself; it's a nice
conceptual unit that would be useful as a library for other projects.

> * Traversal Limit
> So I forgot to add a field to the struct data type. It was missing a 
> `traversalLimit` field. This field is set on a call to `Capnp.init`. Once 
> it's set, we keep track of the traversal depth by incrementing the 
> `currentTraversalDistance` field. If a call to `Capnp.get` or similar 
> function ever encounters a situation where `currentTraversalDistance > 
> traversalLimit`, we return `Err TraversalLimitExceeded`. If they succeed, the 
> function returns an `Ok` with the `currentTraversalDistance` updated.
>
> One thing that isn't very clear to me is whether this is a limit per call to 
> `Capnp.get` or a limit per message (you can only traverse 64 Mib in depth 
> before you give up). I've interpreted this as the latter for this 
> implementation. The former is almost trivial to implement within the `get` 
> itself.

Most implementations track this per message. It's also not just about
limiting depth but amplification attacks; consider:

    struct Tree {
        union {
            leaf @0 :Int32;
            branch :group {
                left @1 :Tree;
                right @2 :Tree;
            }
        }
    }

It's possible to encode a tree using the above where parts of the
structure are shared. Even if it's finite and has reasonable depth,
traversing it could still take exponential time in the size of the
message, if enough nodes are shared.

This was a somewhat awkward thing to cover with the Haskell
implementation; what I ended up doing amounts to a glorified state
monad:

    
https://hackage.haskell.org/package/capnp-0.4.0.0/docs/Capnp-TraversalLimit.html

But I don't think this would translate especially easily to elm, at
least not in a way that was at all ergonomic.

-Ian

-- 
You received this message because you are subscribed to the Google Groups 
"Cap'n Proto" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
Visit this group at https://groups.google.com/group/capnproto.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/capnproto/155919737778.5382.7160284187479028259%40localhost.localdomain.

Reply via email to