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

Failed to use Tar.read with Tar_gz.in_gzipped #160

Open
BChabanne opened this issue Jan 3, 2025 · 3 comments · Fixed by #161
Open

Failed to use Tar.read with Tar_gz.in_gzipped #160

BChabanne opened this issue Jan 3, 2025 · 3 comments · Fixed by #161

Comments

@BChabanne
Copy link

Combining Tar.read with Tar_gz.in_gzipped is failing.

I think this is because the "gzip buffer" is not being used.
Maybe there is a missing function read_through_gz here ?

| Tar.Read _len as v -> v

Or maybe it is not expected to use Tar.read and only Tar.really_read shoud be used ? 

I tried to get a minimal failing script. The following program gives me this output.
read_rec is calling reccursively Tar.read until n bytes have been read. I guess it should have the same behaviour with Tar.really_read

read_really tar...               
file:test len:8
ok
read_rec tar...
file:test len:8
ok
read_really targz...
file:test len:8
ok
read_rec targz...
error: Unexpected end of file
(* bash :
    echo content > test
    tar -cf test.tar test
    tar -czf test.tar.gz test
*)
let decompress () =
  let ( let* ) = Tar.( let* ) in

  let print_err = function
    | Ok () -> Format.printf "ok\n"
    | Error `Eof -> Format.printf "error: end of file\n"
    | Error (`Gz msg) -> Format.printf "error: gz %s\n" msg
    | Error (#Tar_unix.error as err) ->
        Format.printf "error: %a\n" Tar_unix.pp_error err
  in

  let fold f ?global:_ (header : Tar.Header.t) () =
    let* content = f (Int64.to_int header.file_size) in
    Format.printf "file:%s len:%d\n" header.file_name (String.length content);
    Tar.return (Ok ())
  in

  (* this function is failing for untargz *)
  let rec read_rec acc = function
    | 0 -> Tar.return (Ok acc)
    | n ->
        let* content = Tar.read n in
        read_rec (acc ^ content) (n - String.length content)
  in

  (* this one is ok *)
  let read_really n = Tar.really_read n in

  let unzip = Tar_gz.in_gzipped in

  Format.printf "read_really tar...\n";
  (* we don’t care to close fd for this test *)
  let tar = Unix.openfile "test.tar" [ O_RDONLY ] 0 in
  let t = Tar.fold (fold read_really) () in
  let result = Tar_unix.run t tar in
  print_err result;

  Format.printf "read_rec tar...\n";
  let t = Tar.fold (fold (read_rec "")) () in
  let tar = Unix.openfile "test.tar" [ O_RDONLY ] 0 in
  let result = Tar_unix.run t tar in
  print_err result;

  Format.printf "read_really targz...\n";
  let targz = Unix.openfile "test.tar.gz" [ O_RDONLY ] 0 in
  let t = Tar.fold (fold read_really) () in
  let result = Tar_unix.run (unzip t) targz in
  print_err result;

  (* it fails here *)
  Format.printf "read_rec targz...\n";
  let targz = Unix.openfile "test.tar.gz" [ O_RDONLY ] 0 in
  let t = Tar.fold (fold (read_rec "")) () in
  let result = Tar_unix.run (unzip t) targz in
  print_err result;

  ()
@dinosaure
Copy link
Member

Sorry, we did not imagine such a use. I've just proposed a patch (see #161) to make your code work.

@dinosaure
Copy link
Member

@BChabanne can you confirm that my proposal fix your issue? I will be able to cut a release then 👍

@dinosaure
Copy link
Member

So your example works on my side. I hope it works for you. I will merge #161 and cut a release. Thanks for your report - this issue will remains open until you decide to close it 👍.

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

Successfully merging a pull request may close this issue.

2 participants