Fix concatenation of non-aligned bitstrings (thanks Phil Tomson).
authorRichard W.M. Jones <rich@annexia.org>
Tue, 17 Jan 2012 13:20:53 +0000 (13:20 +0000)
committerRichard W.M. Jones <rich@annexia.org>
Tue, 17 Jan 2012 13:20:53 +0000 (13:20 +0000)
This commit includes a regression test.

bitstring.ml
tests/test_91_concat.ml [new file with mode: 0644]

index 831c3b2..1044d89 100644 (file)
@@ -853,7 +853,8 @@ module Buffer = struct
           *)
          let slenbytes = slen lsr 3 in
          if slenbytes > 0 then Buffer.add_substring buf str 0 slenbytes;
-         let last = Char.code str.[slenbytes] in (* last char *)
+         let lastidx = min slenbytes (String.length str - 1) in
+         let last = Char.code str.[lastidx] in (* last char *)
          let mask = 0xff lsl (8 - (slen land 7)) in
          t.last <- last land mask
        );
@@ -992,7 +993,7 @@ let construct_bitstring buf (data, off, len) =
     if blen = 0 then (off, len)
     else (
       let b = extract_bit data off len 1
-      and off = off + 1 and len = len + 1 in
+      and off = off + 1 and len = len - 1 in
       Buffer.add_bit buf b;
       loop off len (blen-1)
     )
diff --git a/tests/test_91_concat.ml b/tests/test_91_concat.ml
new file mode 100644 (file)
index 0000000..b0ab911
--- /dev/null
@@ -0,0 +1,74 @@
+(* Regression test for bug in concatenation found by Phil Tomson.
+ * $Id$
+ *)
+
+open Printf
+open Bitstring
+
+let errors = ref 0
+
+let () =
+  let bs_256 = ones_bitstring 256 in
+  assert (bitstring_length bs_256 = 256);
+
+  let bs2 =
+    BITSTRING {
+      false : 1;
+      (subbitstring bs_256 0 66) : 66 : bitstring
+    } in
+  let len = bitstring_length bs2 in
+  if len <> 67 then (
+    eprintf "invalid length of bs2: len = %d, expected 67\n" len;
+    hexdump_bitstring stderr bs2;
+    incr errors
+  );
+
+  let bs3 =
+    BITSTRING {
+      false : 1;
+      (subbitstring bs_256 0 66) : 66 : bitstring;
+      (subbitstring bs_256 66 67) : 67 : bitstring
+    } in
+  let len = bitstring_length bs3 in
+  if len <> 134 then (
+    eprintf "invalid length of bs3: len = %d, expected 134\n" len;
+    hexdump_bitstring stderr bs3;
+    incr errors
+  );
+
+  let bs4 =
+    BITSTRING {
+      (subbitstring bs_256 66 67) : 67 : bitstring
+    } in
+  let len = bitstring_length bs4 in
+  if len <> 67 then (
+    eprintf "invalid length of bs4: len = %d, expected 67\n" len;
+    hexdump_bitstring stderr bs4;
+    incr errors
+  );
+
+  let bs5 = concat [subbitstring bs_256 0 66; subbitstring bs_256 66 67] in
+  let len = bitstring_length bs5 in
+  if len <> 133 then (
+    eprintf "invalid length of bs5: len = %d, expected 133\n" len;
+    hexdump_bitstring stderr bs5;
+    incr errors
+  );
+
+  let bs6 = concat [ subbitstring bs_256 0 64; subbitstring bs_256 64 64] in
+  let len = bitstring_length bs6 in
+  if len <> 128 then (
+    eprintf "invalid length of bs6: len = %d, expected 128\n" len;
+    hexdump_bitstring stderr bs6;
+    incr errors
+  );
+
+  let bs7 = concat [ subbitstring bs_256 0 65; subbitstring bs_256 65 64] in
+  let len = bitstring_length bs7 in
+  if len <> 129 then (
+    eprintf "invalid length of bs7: len = %d, expected 129\n" len;
+    hexdump_bitstring stderr bs7;
+    incr errors
+  );
+
+  if !errors <> 0 then exit 1