Quoting Yaron Minsky (2019-05-14 16:06:29)

> If I write something in the new spec that uses the age branch of the
> union, the old struct can try to read it, and get very confused.
> In particular, if someone tries to read the email for a struct that
> actually populates age, they'll end up reading a Float64 as if it were
> a pointer to a text block.

In this case, the failure mode is a bit different, because the wire
encoding separates pointers and basic types (like Float64) into two
sections:

    https://capnproto.org/encoding.html#structs

For this example, the old code would read the email as a null pointer,
ignoring the union tag saying that email is not set. If you added more
pointer fields to the union, like:

    struct Person {
        name @0 :Text;
        union {
            email @1 :Text;
            age @2 :Float64;
            emergencyContact @3 :Person;
            mailingAddress @4 :Text;
        }
    }

Then it would read the pointer back without realizing it was a different
field. In the above, if mailingAddress was set you might run in to some
amusing bugs where code tried to send email to street addresses. If
emergencyContact was set, I know the Haskell implementation will throw
an exception when it reads it, since it's a struct pointer instead of a
text (list) pointer. I believe the C++ implementation can be configured
to do either that or return a default value? Not sure about others.

There are also some docs on protocol evolution:

    https://capnproto.org/language.html#evolving-your-protocol

> Am I understanding the issue correctly? If so, how do people handle
> these kinds of protocol changes?  Do people use retroactive
> unionization in practice?

If you have the foresight to know that you *might* add other variants
later, you can do something like this:

    
https://github.com/capnproto/capnproto/blob/master/c%2B%2B/src/capnp/rpc.capnp#L1016

..but obviously that's not really "retroactive." I don't think there's
a general solution, and I haven't seen it done in practice.

> Do people use schema validation of some kind to detect when someone
> makes a potentially unsafe change like this one?

Tools that do this sort of thing have been discussed before and
consensus is that it would be useful, but I don't think anyone's written
any.

Hope this helps,

-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/155786658794.8996.3240552006055861816%40localhost.localdomain.

Reply via email to