Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

type uint32 = int32 is risky #86

Open
talex5 opened this issue Mar 4, 2016 · 8 comments
Open

type uint32 = int32 is risky #86

talex5 opened this issue Mar 4, 2016 · 8 comments

Comments

@talex5
Copy link
Contributor

talex5 commented Mar 4, 2016

Cstruct declares uint32 = int32. However, int32 is signed and doing Int32.to_int may result in a negative number, which the calling code is unlikely to be expecting. Perhaps we should use a separate type for this, with safe accessor functions.

For example, ocaml-9p does:

let big_enough_for name buf needed =
  let length = Cstruct.len buf in
  if length < needed
  then error_msg "%s: buffer too small (%d < %d)" name length needed
  else return ()

let read rest =
  Fid.read rest
  >>= fun (fid, rest) ->
  Int64.read rest
  >>= fun (offset, rest) ->
  Int32.read rest
  >>= fun (len, rest) ->
  let len = Int32.to_int len in
  big_enough_for "Write.data" rest len
  >>= fun () ->
  let data = Cstruct.sub rest 0 len in
  let rest = Cstruct.shift rest len in
  return ({ fid; offset; data }, rest)

This can raise an exception (which the code is trying to avoid) for large values of len.

@avsm
Copy link
Member

avsm commented Mar 4, 2016

agreed, with a a major bump in the library version

@avsm
Copy link
Member

avsm commented May 11, 2017

We could do this via the integers package now, cc @yallop. I can do this after #138 is merged and immediately open up a version 4.0 with the bump for this type change.

@hannesm
Copy link
Member

hannesm commented May 11, 2017

I'm not sure whether integers is always the right solution, please take a look at yallop/ocaml-integers#2 .. there could be some cstruct-integers layer which translates the stdlib types to integers types - it would be convenient (at least for me) to not introduce a hard dependency on integers, and be able to access the byte representation.

@yallop
Copy link
Member

yallop commented May 11, 2017

@hannesm, I'd like to understand your concerns better.

please take a look at yallop/ocaml-integers#2

Could you expand on how that (resolved) issue is relevant to using integers in cstruct? e.g. were you hoping for some other resolution?

some cstruct-integers layer which translates the stdlib types to integers types

The integers package already provides conversions between standard library types and types in that library (e.g.). Do you have something else in mind?

it would be convenient (at least for me) to [...] be able to access the byte representation.

I'm not sure what you mean here, either.

@hannesm
Copy link
Member

hannesm commented May 11, 2017 via email

@hannesm
Copy link
Member

hannesm commented May 11, 2017

Clearly, performance benchmarks of parsing e.g. uint32 (which atm is int32) vs Unsigned.Uint32.t (and the corresponding 64bit numbers) could help to show that my concerns are void.

@yallop
Copy link
Member

yallop commented May 22, 2017

Yes, I agree that it would be good to avoid a chain of conversions. We should certainly not go through stdlib int on the way to UInt32.t! It should instead be possible to go directly from the bigarray-referenced memory to an UInt32.t value.

I think the last piece of the puzzle, going from Unsigned.UInt32.t to the Usane type, would be fixed by this issue: hannesm/usane#3.

@XVilka
Copy link
Contributor

XVilka commented Jan 9, 2019

So what was decided on this one?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants