core.go: The vdl "any" type is now generated as go *vdl.Value.
Previously we were generating as vdl.AnyRep, which was another
name for interface{}. There are multiple problems with using
interface{}:
1) Decoding into an "interface{}" requires that the type has
been registered with VDL, and uses our type name based
matching logic. This is error prone; if we happen to change
the package path, the type name changes. And if the type
isn't registered, we'll end up with a *vdl.Value anyways.
Now there's no ambiguity; you always get a *vdl.Value, which
can represent values of all vdl types.
2) Some Go values aren't valid in VDL. E.g. Go values that
contain channels, functions or unsafe pointers are all
invalid. Using *vdl.Value at our API boundaries forces the
callers to make an informed decision.
This is the main portion of a 7-part CL, which removes
vdl.AnyRep, and uses *vdl.Value instead.
MultiPart: 1/7
Change-Id: Ie4f3ab6bce0363f82f53c2315a7435844f6ffe85
diff --git a/runtimes/google/ipc/client.go b/runtimes/google/ipc/client.go
index c3e7136..eeb9ef5 100644
--- a/runtimes/google/ipc/client.go
+++ b/runtimes/google/ipc/client.go
@@ -306,7 +306,7 @@
return
}
-func mkDischargeImpetus(serverBlessings []string, method string, args []interface{}) security.DischargeImpetus {
+func mkDischargeImpetus(serverBlessings []string, method string, args []interface{}) (security.DischargeImpetus, error) {
var impetus security.DischargeImpetus
if len(serverBlessings) > 0 {
impetus.Server = make([]security.BlessingPattern, len(serverBlessings))
@@ -316,12 +316,16 @@
}
impetus.Method = method
if len(args) > 0 {
- impetus.Arguments = make([]vdl.AnyRep, len(args))
+ impetus.Arguments = make([]*vdl.Value, len(args))
for i, a := range args {
- impetus.Arguments[i] = vdl.AnyRep(a)
+ vArg, err := vdl.ValueFromReflect(reflect.ValueOf(a))
+ if err != nil {
+ return security.DischargeImpetus{}, err
+ }
+ impetus.Arguments[i] = vArg
}
}
- return impetus
+ return impetus, nil
}
// startCall ensures StartCall always returns verror.Standard.
@@ -785,7 +789,13 @@
// Fetch any discharges for third-party caveats on the client's blessings
// if this client owns a discharge-client.
if self := fc.flow.LocalBlessings(); self != nil && fc.dc != nil {
- fc.discharges = fc.dc.PrepareDischarges(fc.ctx, self.ThirdPartyCaveats(), mkDischargeImpetus(fc.server, method, args))
+ impetus, err := mkDischargeImpetus(fc.server, method, args)
+ if err != nil {
+ // TODO(toddw): Fix up the internal error.
+ berr := verror.New(verror.ErrBadProtocol, fc.ctx, fmt.Errorf("couldn't make discharge impetus: %v", err))
+ return fc.close(berr)
+ }
+ fc.discharges = fc.dc.PrepareDischarges(fc.ctx, self.ThirdPartyCaveats(), impetus)
}
// Encode the Blessings information for the client to authorize the flow.
var blessingsRequest ipc.BlessingsRequest