capnp-ocaml icon indicating copy to clipboard operation
capnp-ocaml copied to clipboard

Reinitialising a composite list zeros out other values

Open talex5 opened this issue 7 years ago • 0 comments

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.

talex5 avatar May 14 '17 10:05 talex5