file:open() with 'compressed' flag silently accepts corrupt files

Matthias Lang <>
Mon Aug 7 13:44:53 CEST 2006


Bug or a feature?

   Erlang (BEAM) emulator version 5.5 [source] [async-threads:0] [hipe]
   
   Eshell V5.5  (abort with ^G)
   1> {ok, Out} = file:open("/tmp/compressed", [write, compressed]).
   {ok,<0.34.0>}
   2> file:write(Out, "hello world"), file:close(Out).
   ok
   3> {ok, <<_, Corrupt/binary>>} = file:read_file("/tmp/compressed").
   {ok,<<31,139,8,0,0,0,0,0,0,3,203,72,205,201,201,87,40,207,47,202,73,...>>}
   4>  file:write_file("/tmp/corrupt", Corrupt).
   ok
   5> {ok, In} = file:open("/tmp/corrupt", [read, compressed]).
   {ok,<0.39.0>}
   6> file:read(In, 1000).
   {ok,[139, 8, 0, 0, 0, 0, 0, 0, 3, 203, 72, 205,...

I was expecting line 5 to fail, since the file no longer starts with
the 'gzip magic'. A bit like what gzip does:

   >gunzip -c /tmp/corrupt 
   gunzip: /tmp/corrupt: not in gzip format

The 'transparently pass file data if the gzip magic isn't present'
behaviour is inherited from the zlib code in gzio.c. It looks deliberate.

Suggestion: alter the manual page for file:open thusly:

  compressed

    Makes it possible to read and write gzip compressed files. Unlike
    with other types of files, only one of the 'read' and 'write'
    modes may be specified.

    Note that the file size obtained with read_file_info/1 will most
    probably not match the number of bytes that can be read from a
    compressed file.

    Opening a file which is not in gzip format will result in the
    compressed flag being silently ignored.

The simplest workaround for my problem is to add my own code to check
for gzip magic before calling file:open. An alternative is to use the
zlib module.

Matthias



More information about the erlang-questions mailing list