xavierleroy / cryptokit

A library of cryptographic primitives (ciphers, hashes, etc) for OCaml
Other
97 stars 24 forks source link

zlib failure in utop #7

Closed hcarty closed 5 years ago

hcarty commented 6 years ago

Example from a fresh utop/toplevel session using cryptokit 1.12 from opam on a 64bit Linux VM:

let c = Cryptokit.Zlib.compress ();;
let s' = Cryptokit.transform_string c "x";;

The last line raises:

Exception: Cryptokit.Error (Cryptokit.Compression_error ("Zlib.deflate", "")).

The same exception is raised when compiling with ocamlopt.

The following works, however:

let s' = Cryptokit.transform_string (Cryptokit.Zlib.compress ()) (String.make 1 'x');;
xavierleroy commented 6 years ago

I haven't been able to reproduce the issue so far. This is what I'm doing (with OCaml 4.06.0 on Ubuntu 16.04 x86-64):

$ cat bug.ml
let c = Cryptokit.Zlib.compress ();;
let s' = Cryptokit.transform_string c "x";;
let _ = print_endline (String.escaped s');;
$ ocamlfind ocamlopt -linkpkg -package cryptokit bug.ml
$ ./a.out
\171\000\000

No Cryptokit.Error exception.

Is there any way you could narrow down the issue? Because I can't.

hcarty commented 6 years ago

I can't reproduce the failure I was getting when compiling with ocamlopt.

I can reproduce the failure under utop but not with vanilla ocaml.

For utop:

utop -init /dev/null

#require "cryptokit";;
let c = Cryptokit.Zlib.compress ();;
let s' = Cryptokit.transform_string c "x";;
(* Exception: Cryptokit.Error (Cryptokit.Compression_error ("Zlib.deflate", "")). *)

For ocaml:


ocaml

#use "topfind";;
#require "cryptokit";;
let c = Cryptokit.Zlib.compress ();;
let s' = Cryptokit.transform_string c "x";;
(* val s' : string = "?\000\000" *)
hcarty commented 6 years ago

I think this is the failure I saw previously under ocamlopt, though I don't know if it's related to the failure under utop:

let () =
  ignore
    (Cryptokit.transform_string
       (Cryptokit.Zlib.uncompress ())
       (Cryptokit.transform_string
          (Cryptokit.Zlib.compress ())
          (String.make 10_000_000 'x')))

dies with Fatal error: exception Cryptokit.Error(_)

UnixJunkie commented 6 years ago

I also see a problem with compress. Though the cryptokit in opam is lagging one version behind the released one (I sent a PR in opam-repository to try to fix that). I will report if I manage to pinpoint better the Zlib compress problem. It happens in utop and in compiled programs too.

UnixJunkie commented 6 years ago
zlib1g:amd64 1:1.2.11.dfsg-0ubuntu2
zlib1g-dev:amd64 1:1.2.11.dfsg-0ubuntu2
UnixJunkie commented 6 years ago

The following crashes at a random point in both utop and \ocaml:

#use "topfind";;
#require "cryptokit";;

let compress str =
  let gzip = Cryptokit.Zlib.compress ~level:1 () in
  gzip#put_string str;
  gzip#flush;
  gzip#get_string

let () =
  for i = 1 to 1_000_000 do
    Printf.printf "%d\n%!" i;
    ignore (compress (string_of_int i))
  done

Does someone else also see this crashing?

UnixJunkie commented 6 years ago

changing the compression level doesn't make the problem go away

UnixJunkie commented 6 years ago
Fatal error: exception Cryptokit.Error(_)
Raised by primitive operation at file "src/cryptokit.ml", line 1907, characters 10-134
UnixJunkie commented 6 years ago

I wanted to do this:

module M = struct
  let gzip = Cryptokit.Zlib.compress ~level:1 ()
  let compress str =
    gzip#put_string str;
    gzip#flush;
    gzip#get_string
end

Because this is not for crypto. I don't want to wipe the transform and have to recreate one every time.

UnixJunkie commented 6 years ago

@hcarty can you reliably reproduce the problem with the script I sent? I'm using 4.06.1 but not sure if it matters.

hcarty commented 6 years ago

@UnixJunkie I get failure from the code in https://github.com/xavierleroy/cryptokit/issues/7#issuecomment-398616557 as well under 4.06.0

mfp commented 5 years ago

16 is a very likely culprit for this.

UnixJunkie commented 5 years ago

I think this can be closed based on the recent PR that was merged. Maybe a test is in order though.