capnp-ocaml
capnp-ocaml copied to clipboard
Reinitialising a composite list zeros out other values
Test case:
let open Examples.Api.Builder in
let p = Payload.init_root () in
let content = Payload.content_get p in
Payload.cap_table_init p 1 |> ignore;
TestArgs.params_init content 1 |> ignore;
Alcotest.(check int) "Args len aa" 1 (Capnp.Array.length (TestArgs.params_get content));
Payload.cap_table_init p 1 |> ignore;
Alcotest.(check int) "Args len bb" 1 (Capnp.Array.length (TestArgs.params_get content))
With schema (simplfied from an RPC system):
struct CapDescriptor {
v @0 :Float64;
}
struct Payload {
content @0 :TestArgs;
capTable @1 :List(CapDescriptor);
}
struct TestArgs {
params @0 :List(Float64);
}
The second assertion fails: the second call to cap_table_init
zeroes out the last element of params
.
Stepping through with ocamldebug, it seems the problem is at https://github.com/pelzlpj/capnp-ocaml/blob/f711ece828a5a662569c68d048671390d7fb1862/src/runtime/builderOps.ml#L834:
(* Composite lists prefix the data with a tag word, so clean up
the tag word along with everything else *)
let content_slice = {
list_storage.storage with
RWM.Slice.start = list_storage.storage.RWM.Slice.start - sizeof_uint64;
RWM.Slice.len = list_storage.storage.RWM.Slice.len + sizeof_uint64;
} in
RWM.Slice.zero_out content_slice ~pos:0 ~len:content_slice.RWM.Slice.len
By contrast, alloc_list_storage
appears to return a slice that includes the tag.
This means that whatever happens to be stored just before the list gets zeroed out.
Possibly it also fails to zero the list properly.