From 1b28c58654c049977ce08e1a87ea854f5e5fdd55 Mon Sep 17 00:00:00 2001 From: Robert Newson Date: Mon, 15 Oct 2018 17:13:05 +0100 Subject: Test correct condition for exceed_limit error Previously we were testing if Pos + TotalBytes exceeded the pread limit. This is the wrong logic entirely. We are trying to prevent an attempted call to file:pread/3 where the third parameter, the number of bytes to read, is a very large number (due to a corruption elsewhere, say). Instead we throw exceed_limit as soon as a file gets above a certain size. I switched this to an if statement to make it clear that the "read past EOF" and "try to read too many bytes" checks are quite distinct from each other. --- src/couch/src/couch_file.erl | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/couch/src/couch_file.erl b/src/couch/src/couch_file.erl index 0c6070dad..d6e4066db 100644 --- a/src/couch/src/couch_file.erl +++ b/src/couch/src/couch_file.erl @@ -614,18 +614,18 @@ read_raw_iolist_int(Fd, {Pos, _Size}, Len) -> % 0110 UPGRADE CODE read_raw_iolist_int(#file{fd = Fd, pread_limit = Limit} = F, Pos, Len) -> BlockOffset = Pos rem ?SIZE_BLOCK, TotalBytes = calculate_total_read_len(BlockOffset, Len), - case Pos + TotalBytes of - Size when Size > F#file.eof -> - couch_stats:increment_counter([pread, exceed_eof]), - {_Fd, Filepath} = get(couch_file_fd), - throw({read_beyond_eof, Filepath}); - Size when Size > Limit -> - couch_stats:increment_counter([pread, exceed_limit]), - {_Fd, Filepath} = get(couch_file_fd), - throw({exceed_pread_limit, Filepath, Limit}); - Size -> - {ok, <>} = file:pread(Fd, Pos, TotalBytes), - {remove_block_prefixes(BlockOffset, RawBin), Size} + if + (Pos + TotalBytes) > F#file.eof -> + couch_stats:increment_counter([pread, exceed_eof]), + {_Fd, Filepath} = get(couch_file_fd), + throw({read_beyond_eof, Filepath}); + TotalBytes > Limit -> + couch_stats:increment_counter([pread, exceed_limit]), + {_Fd, Filepath} = get(couch_file_fd), + throw({exceed_pread_limit, Filepath, Limit}); + true -> + {ok, <>} = file:pread(Fd, Pos, TotalBytes), + {remove_block_prefixes(BlockOffset, RawBin), Pos + TotalBytes} end. -spec extract_md5(iolist()) -> {binary(), iolist()}. -- cgit v1.2.1