Permalink
Browse files

Fix retrieval of headers larger than 4k

Our headers start with a <<1>> and then four bytes indicating the length
of the header and its checksum. When the header is larger than 4090
bytes it will be split across multiple blocks in the file and will need
to be reassembled on read. The reassembly consists of stripping out
<<0>> from the beginning of each subsequent block in the
remove_block_prefixes/2 function. The bug here is that we tell
remove_block_prefixes that we're starting 1 byte into the current block
instead of 5, so it ends up removing one good byte from the header and
injecting one or more random <<0>>s.

Headers larger than 4k are very rare and generally require a view group
with a huge number of indexes or indexes with fairly large reductions,
which explains why this bug has gone undetected until now.

Closes COUCHDB-1319.
  • Loading branch information...
1 parent 9f734e0 commit 7c94ebbf91f2c61b109af53cdbae530e79424849 @kocolosk kocolosk committed with Robert Newson Oct 26, 2011
Showing with 9 additions and 2 deletions.
  1. +1 −1 apps/couch/src/couch_file.erl
  2. +8 −1 apps/couch/test/etap/011-file-headers.t
@@ -528,7 +528,7 @@ load_header(Fd, Block) ->
RawBin = <<RestBlock/binary, Missing/binary>>
end,
<<Md5Sig:16/binary, HeaderBin/binary>> =
- iolist_to_binary(remove_block_prefixes(1, RawBin)),
+ iolist_to_binary(remove_block_prefixes(5, RawBin)),
Md5Sig = couch_util:md5(HeaderBin),
{ok, HeaderBin}.
@@ -22,7 +22,7 @@ main(_) ->
{S1, S2, S3} = now(),
random:seed(S1, S2, S3),
- etap:plan(17),
+ etap:plan(18),
case (catch test()) of
ok ->
etap:end_tests();
@@ -68,6 +68,13 @@ test() ->
etap:is({ok, Size2}, couch_file:bytes(Fd),
"Rewriting the same second header returns the same second size."),
+ couch_file:write_header(Fd, erlang:make_tuple(5000, <<"CouchDB">>)),
+ etap:is(
+ couch_file:read_header(Fd),
+ {ok, erlang:make_tuple(5000, <<"CouchDB">>)},
+ "Headers larger than the block size can be saved (COUCHDB-1319)"
+ ),
+
ok = couch_file:close(Fd),
% Now for the fun stuff. Try corrupting the second header and see

0 comments on commit 7c94ebb

Please sign in to comment.