Skip to content

Commit 554f6a8

Browse files
committed
Merge pull request #11 from avsm/master
Fix cstruct overflow, correct sequencing in cenum, add docs
2 parents 15c1345 + fdde118 commit 554f6a8

File tree

16 files changed

+277
-138
lines changed

16 files changed

+277
-138
lines changed

.travis-ci.sh

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
OPAM_DEPENDS="ocplib-endian lwt async"
2+
3+
case "$OCAML_VERSION,$OPAM_VERSION" in
4+
3.12.1,1.0.0) ppa=avsm/ocaml312+opam10 ;;
5+
3.12.1,1.1.0) ppa=avsm/ocaml312+opam11 ;;
6+
4.00.1,1.0.0) ppa=avsm/ocaml40+opam10 ;;
7+
4.00.1,1.1.0) ppa=avsm/ocaml40+opam11 ;;
8+
4.01.0,1.0.0) ppa=avsm/ocaml41+opam10 ;;
9+
4.01.0,1.1.0) ppa=avsm/ocaml41+opam11 ;;
10+
*) echo Unknown $OCAML_VERSION,$OPAM_VERSION; exit 1 ;;
11+
esac
12+
13+
echo "yes" | sudo add-apt-repository ppa:$ppa
14+
sudo apt-get update -qq
15+
sudo apt-get install -qq ocaml ocaml-native-compilers camlp4-extra opam time
16+
17+
export OPAMYES=1
18+
export OPAMVERBOSE=1
19+
echo OCaml version
20+
ocaml -version
21+
echo OPAM versions
22+
opam --version
23+
opam --git-version
24+
25+
opam init
26+
opam install ${OPAM_DEPENDS}
27+
28+
eval `opam config env`
29+
make
30+
./test.sh

.travis.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
language: c
2+
script: bash -ex .travis-ci.sh
3+
env:
4+
- OCAML_VERSION=4.01.0 OPAM_VERSION=1.0.0
5+
- OCAML_VERSION=4.01.0 OPAM_VERSION=1.1.0
6+
- OCAML_VERSION=4.00.1 OPAM_VERSION=1.0.0
7+
- OCAML_VERSION=4.00.1 OPAM_VERSION=1.1.0
8+
- OCAML_VERSION=3.12.1 OPAM_VERSION=1.0.0
9+
- OCAML_VERSION=3.12.1 OPAM_VERSION=1.1.0

CHANGES

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
0.7.2 (trunk):
2+
* Improved ocamldoc for BE/LE modules.
3+
* Add Travis-CI test scripts and fix `test.sh` script compilation.
4+
* Check and raise error in case of negative offsets for blits (#4).
5+
* Correctly preserve the sequence after a constant constructor is set during a `cenum` definition.
6+
* Do not repeat the `sizeof_<field>` binding for every get/set field (should be no externally observable change).
7+
18
0.7.1 (06-Mar-2013):
29
* Add `Async_cstruct.Pipe` to map pipes of `Cstruct` buffers to strings or `Bigsubstring`.
310

README.md

Lines changed: 82 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,91 @@ cstruct ipv4 {
4242
} as big_endian
4343
```
4444

45+
This auto-generates generates functions of the form below in the `ml` file:
46+
47+
```
48+
let sizeof_pcap_packet = 16
49+
let get_pcap_packet_ts_sec v = Cstruct.LE.get_uint32 v 0
50+
let set_pcap_packet_ts_sec v x = Cstruct.LE.set_uint32 v 0 x
51+
let get_pcap_packet_ts_usec v = Cstruct.LE.get_uint32 v 4
52+
let set_pcap_packet_ts_usec v x = Cstruct.LE.set_uint32 v 4 x
53+
let get_pcap_packet_incl_len v = Cstruct.LE.get_uint32 v 8
54+
let set_pcap_packet_incl_len v x = Cstruct.LE.set_uint32 v 8 x
55+
let get_pcap_packet_orig_len v = Cstruct.LE.get_uint32 v 12
56+
let set_pcap_packet_orig_len v x = Cstruct.LE.set_uint32 v 12 x
57+
58+
let sizeof_ethernet = 14
59+
let get_ethernet_dst src = Cstruct.sub src 0 6
60+
let copy_ethernet_dst src = Cstruct.copy src 0 6
61+
let set_ethernet_dst src srcoff dst =
62+
Cstruct.blit_from_string src srcoff dst 0 6
63+
let blit_ethernet_dst src srcoff dst = Cstruct.blit src srcoff dst 0 6
64+
let get_ethernet_src src = Cstruct.sub src 6 6
65+
let copy_ethernet_src src = Cstruct.copy src 6 6
66+
let set_ethernet_src src srcoff dst =
67+
Cstruct.blit_from_string src srcoff dst 6 6
68+
let blit_ethernet_src src srcoff dst = Cstruct.blit src srcoff dst 6 6
69+
let get_ethernet_ethertype v = Cstruct.BE.get_uint16 v 12
70+
let set_ethernet_ethertype v x = Cstruct.BE.set_uint16 v 12 x
71+
```
72+
73+
The `mli` file will have signatures of this form:
74+
75+
```
76+
val sizeof_pcap_packet : int
77+
val get_pcap_packet_ts_sec : Cstruct.t -> Cstruct.uint32
78+
val set_pcap_packet_ts_sec : Cstruct.t -> Cstruct.uint32 -> unit
79+
val get_pcap_packet_ts_usec : Cstruct.t -> Cstruct.uint32
80+
val set_pcap_packet_ts_usec : Cstruct.t -> Cstruct.uint32 -> unit
81+
val get_pcap_packet_incl_len : Cstruct.t -> Cstruct.uint32
82+
val set_pcap_packet_incl_len : Cstruct.t -> Cstruct.uint32 -> unit
83+
val get_pcap_packet_orig_len : Cstruct.t -> Cstruct.uint32
84+
val set_pcap_packet_orig_len : Cstruct.t -> Cstruct.uint32 -> unit
85+
86+
val sizeof_ethernet : int
87+
val get_ethernet_dst : Cstruct.t -> Cstruct.t
88+
val copy_ethernet_dst : Cstruct.t -> string
89+
val set_ethernet_dst : string -> int -> Cstruct.t -> unit
90+
val blit_ethernet_dst : Cstruct.t -> int -> Cstruct.t -> unit
91+
val get_ethernet_src : Cstruct.t -> Cstruct.t
92+
val copy_ethernet_src : Cstruct.t -> string
93+
val set_ethernet_src : string -> int -> Cstruct.t -> unit
94+
val blit_ethernet_src : Cstruct.t -> int -> Cstruct.t -> unit
95+
val get_ethernet_ethertype : Cstruct.t -> Cstruct.uint16
96+
val set_ethernet_ethertype : Cstruct.t -> Cstruct.uint16 -> unit
97+
```
4598
You can also declare C-like enums:
4699

47100
```
48-
cenum foo64 {
49-
ONE64;
50-
TWO64;
51-
THREE64
52-
} as uint64_t
101+
cenum foo32 {
102+
ONE32;
103+
TWO32 = 0xfffffffel;
104+
THREE32
105+
} as uint32_t
106+
107+
cenum bar16 {
108+
ONE = 1;
109+
TWO;
110+
FOUR = 4;
111+
FIVE
112+
} as uint16_t
113+
```
114+
115+
This generates signatures of the form:
116+
117+
```
118+
type foo32 = | ONE32 | TWO32 | THREE32
119+
val int_to_foo32 : int32 -> foo32 option
120+
val foo32_to_int : foo32 -> int32
121+
val foo32_to_string : foo32 -> string
122+
val string_to_foo32 : string -> foo32 option
123+
type bar16 = | ONE | TWO | FOUR | FIVE
124+
val int_to_bar16 : int -> bar16 option
125+
val bar16_to_int : bar16 -> int
126+
val bar16_to_string : bar16 -> string
127+
val string_to_bar16 : string -> bar16 option
53128
```
54129

55130
Please see the `lib_test/` directory for more in-depth examples.
131+
132+
[![Build Status](https://travis-ci.org/avsm/ocaml-cstruct.png)](https://travis-ci.org/avsm/ocaml-cstruct)

_oasis

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
OASISFormat: 0.3
22
Name: cstruct
3-
Version: 0.7.1
3+
Version: 0.7.2
44
Synopsis: Manipulate external buffers as C-like structs
55
Authors: Anil Madhavapeddy, Richard Mortier, Thomas Gazagnaire, Pierre Chambart
66
License: ISC

lib/META

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# OASIS_START
2-
# DO NOT EDIT (digest: c671864304beccb6078416a289ce5ee8)
3-
version = "0.7.1"
2+
# DO NOT EDIT (digest: 930869fcefc42a7e26a3e025657bc63c)
3+
version = "0.7.2"
44
description = "Manipulate external buffers as C-like structs"
55
requires = "bigarray ocplib-endian ocplib-endian.bigstring"
66
archive(byte) = "cstruct.cma"
@@ -9,7 +9,7 @@ archive(native) = "cstruct.cmxa"
99
archive(native, plugin) = "cstruct.cmxs"
1010
exists_if = "cstruct.cma"
1111
package "unix" (
12-
version = "0.7.1"
12+
version = "0.7.2"
1313
description = "Manipulate external buffers as C-like structs"
1414
requires = "cstruct unix"
1515
archive(byte) = "unix_cstruct.cma"
@@ -20,7 +20,7 @@ package "unix" (
2020
)
2121

2222
package "syntax" (
23-
version = "0.7.1"
23+
version = "0.7.2"
2424
description = "Syntax extension for Cstruct"
2525
requires = "camlp4"
2626
archive(syntax, preprocessor) = "cstruct-syntax.cma"
@@ -29,7 +29,7 @@ package "syntax" (
2929
)
3030

3131
package "lwt" (
32-
version = "0.7.1"
32+
version = "0.7.2"
3333
description = "Manipulate external buffers as C-like structs"
3434
requires = "cstruct lwt.unix"
3535
archive(byte) = "lwt_cstruct.cma"
@@ -40,7 +40,7 @@ package "lwt" (
4040
)
4141

4242
package "async" (
43-
version = "0.7.1"
43+
version = "0.7.2"
4444
description = "Manipulate external buffers as C-like structs"
4545
requires = "cstruct async threads"
4646
archive(byte) = "async_cstruct.cma"

lib/cstruct.ml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -132,23 +132,23 @@ external unsafe_blit_string_to_bigstring : string -> int -> buffer -> int -> int
132132
external unsafe_blit_bigstring_to_string : buffer -> int -> string -> int -> int -> unit = "caml_blit_bigstring_to_string" "noalloc"
133133

134134
let copy src srcoff len =
135-
if src.len - srcoff < len then raise (Invalid_argument (invalid_bounds srcoff len));
135+
if len < 0 || srcoff < 0 || src.len - srcoff < len then raise (Invalid_argument (invalid_bounds srcoff len));
136136
let s = String.create len in
137137
unsafe_blit_bigstring_to_string src.buffer (src.off+srcoff) s 0 len;
138138
s
139139

140140
let blit src srcoff dst dstoff len =
141-
if src.len - srcoff < len then raise (Invalid_argument (invalid_bounds srcoff len));
141+
if len < 0 || srcoff < 0 || src.len - srcoff < len then raise (Invalid_argument (invalid_bounds srcoff len));
142142
if dst.len - dstoff < len then raise (Invalid_argument (invalid_bounds dstoff len));
143143
unsafe_blit_bigstring_to_bigstring src.buffer (src.off+srcoff) dst.buffer (dst.off+dstoff) len
144144

145145
let blit_from_string src srcoff dst dstoff len =
146-
if String.length src - srcoff < len then raise (Invalid_argument (invalid_bounds srcoff len));
146+
if len < 0 || srcoff < 0 || dstoff < 0 || String.length src - srcoff < len then raise (Invalid_argument (invalid_bounds srcoff len));
147147
if dst.len - dstoff < len then raise (Invalid_argument (invalid_bounds dstoff len));
148148
unsafe_blit_string_to_bigstring src srcoff dst.buffer (dst.off+dstoff) len
149149

150150
let blit_to_string src srcoff dst dstoff len =
151-
if src.len - srcoff < len then raise (Invalid_argument (invalid_bounds srcoff len));
151+
if len < 0 || srcoff < 0 || dstoff < 0 || src.len - srcoff < len then raise (Invalid_argument (invalid_bounds srcoff len));
152152
if String.length dst - dstoff < len then raise (Invalid_argument (invalid_bounds dstoff len));
153153
unsafe_blit_bigstring_to_string src.buffer (src.off+srcoff) dst dstoff len
154154

lib_test/basic.ml

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -30,27 +30,27 @@ cstruct bar {
3030

3131
let _ =
3232
(* Test basic set/get functions *)
33-
let be = Bigarray.(Array1.create char c_layout sizeof_foo) in
33+
let be = Cstruct.of_bigarray (Bigarray.(Array1.create char c_layout sizeof_foo)) in
3434
for i = 0 to 255 do
3535
set_bar_a be i;
3636
assert(get_bar_a be = i)
3737
done;
38-
let le = Bigarray.(Array1.create char c_layout sizeof_bar) in
38+
let le = Cstruct.of_bigarray (Bigarray.(Array1.create char c_layout sizeof_bar)) in
3939
for i = 0 to 255 do
4040
set_foo_a le i;
4141
assert(get_foo_a le = i)
4242
done;
43-
let be = Bigarray.(Array1.create char c_layout sizeof_foo) in
43+
let be = Cstruct.of_bigarray (Bigarray.(Array1.create char c_layout sizeof_foo)) in
4444
for i = 0 to 65535 do
4545
set_bar_b be i;
4646
assert(get_bar_b be = i)
4747
done;
48-
let le = Bigarray.(Array1.create char c_layout sizeof_bar) in
48+
let le = Cstruct.of_bigarray(Bigarray.(Array1.create char c_layout sizeof_bar)) in
4949
for i = 0 to 65535 do
5050
set_foo_b le i;
5151
assert(get_foo_b le = i)
5252
done;
53-
let be = Bigarray.(Array1.create char c_layout sizeof_foo) in
53+
let be = Cstruct.of_bigarray (Bigarray.(Array1.create char c_layout sizeof_foo)) in
5454
let rec fn = function
5555
|i when i < 0l -> ()
5656
|i ->
@@ -59,7 +59,7 @@ let _ =
5959
fn (Int32.sub i 0x10l)
6060
in fn 0xffffffff_l;
6161
(* Get/set buffers and blits *)
62-
let le = Bigarray.(Array1.create char c_layout sizeof_bar) in
62+
let le = Cstruct.of_bigarray (Bigarray.(Array1.create char c_layout sizeof_bar)) in
6363
let rec fn = function
6464
|i when i < 0l -> ()
6565
|i ->
@@ -75,19 +75,15 @@ let _ =
7575
assert(copy_bar_d le = s1);
7676
Printf.printf "%s %s\n" (copy_foo_d be) (copy_bar_d le);
7777
(* Create sub-view and shift it back *)
78-
let be = Bigarray.(Array1.create char c_layout sizeof_foo) in
78+
let be = Cstruct.of_bigarray (Bigarray.(Array1.create char c_layout sizeof_foo)) in
7979
set_foo_a be 7;
8080
set_foo_b be 44;
8181
set_foo_c be 0xbeef_l;
8282
set_foo_d "abcdefgh" 0 be;
83-
(* shifting the base array should fail *)
84-
assert(not (Cstruct.shift_left be 1));
8583
(* get a subview *)
8684
let be2 = Cstruct.shift be 3 in
8785
assert(Cstruct.BE.get_uint32 be2 0 = 0xbeef_l);
88-
(* shift it back *)
89-
assert(Cstruct.shift_left be2 3);
90-
assert(Cstruct.BE.get_uint32 be2 3 = 0xbeef_l);
91-
assert(not (Cstruct.shift_left be2 1));
92-
assert(get_foo_b be2 = 44);
93-
assert(get_foo_a be2 = 7)
86+
assert(Cstruct.BE.get_uint32 be 3 = 0xbeef_l);
87+
assert(get_foo_b be = 44);
88+
assert(get_foo_a be = 7)
89+

lib_test/enum.ml

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,17 @@ cenum foo64 {
2222

2323
cenum foo32 {
2424
ONE32;
25-
TWO32 = 3;
25+
TWO32 = 0xfffffffel;
2626
THREE32
2727
} as uint32_t
2828

29+
cenum bar16 {
30+
ONE = 1;
31+
TWO;
32+
FOUR = 4;
33+
FIVE
34+
} as uint16_t
35+
2936
cenum foo16 {
3037
ONE16;
3138
TWO16;
@@ -47,9 +54,11 @@ let _ =
4754
ignore(foo32_to_int ONE32);
4855
ignore(foo16_to_int ONE16);
4956
ignore(foo8_to_int ONE8);
50-
assert(foo32_to_int TWO32 = 3l);
51-
assert(foo32_to_int THREE32 = 1l);
52-
assert(int_to_foo32 3l = Some (TWO32));
53-
assert(int_to_foo32 1l = Some (THREE32));
57+
assert(bar16_to_int FOUR = 4);
58+
assert(bar16_to_int FIVE = 5);
59+
assert(foo32_to_int TWO32 = 0xfffffffel);
60+
assert(foo32_to_int THREE32 = 0xffffffffl);
61+
assert(int_to_foo32 0xfffffffel = Some (TWO32));
62+
assert(int_to_foo32 0xffffffffl = Some (THREE32));
5463
assert(string_to_foo16 "ONE16" = Some ONE16);
55-
print_endline (foo8_to_string ONE8)
64+
assert(foo8_to_string ONE8 = "ONE8")

lib_test/enum.mli

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,13 @@ cenum foo32 {
2626
THREE32
2727
} as uint32_t
2828

29+
cenum bar16 {
30+
ONE = 1;
31+
TWO;
32+
FOUR = 4;
33+
FIVE
34+
} as uint16_t
35+
2936
cenum foo16 {
3037
ONE16;
3138
TWO16;

0 commit comments

Comments
 (0)