summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Newson <rnewson@apache.org>2018-10-15 17:13:05 +0100
committerRobert Newson <rnewson@apache.org>2018-10-15 17:15:31 +0100
commit1b28c58654c049977ce08e1a87ea854f5e5fdd55 (patch)
tree3c121290cd45661cd9c05e0df82cc20dfef5d045
parentadebd386ee55f65c1b58b3fab232dda9f351c739 (diff)
downloadcouchdb-fix_exceed_limit.tar.gz
Test correct condition for exceed_limit errorfix_exceed_limit
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.
-rw-r--r--src/couch/src/couch_file.erl24
1 files 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, <<RawBin:TotalBytes/binary>>} = 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, <<RawBin:TotalBytes/binary>>} = file:pread(Fd, Pos, TotalBytes),
+ {remove_block_prefixes(BlockOffset, RawBin), Pos + TotalBytes}
end.
-spec extract_md5(iolist()) -> {binary(), iolist()}.