Do not allow zero-length reads

Since this may create pretty odd issues, since reading 0 bytes will
return 0, and some code may not be ready for this.

v0: add a check in ReadBuffer ctor
v2: Do not create empty ReadBuffer from BufferWithOwnMemory with empty size
v3:
- revert "Do not create empty ReadBuffer from BufferWithOwnMemory with empty size"
- Replace INVALID_SETTING_VALUE with LOGICAL_ERROR
- Move the check for empty buffer in ReadBuffer into reading because of MMapReadBufferFromFile
v4: replace with assert of internal_buffer.size()
v5: move assertion to implementations since there are exceptions for
    nested readers, like LimitReadBuffer and similar.
This commit is contained in:
Azat Khuzhin 2021-10-15 10:13:11 +03:00
parent 2bb586bed3
commit b0f9112696
3 changed files with 9 additions and 0 deletions

View File

@ -51,6 +51,9 @@ std::string ReadBufferFromFileDescriptor::getFileName() const
bool ReadBufferFromFileDescriptor::nextImpl() bool ReadBufferFromFileDescriptor::nextImpl()
{ {
/// If internal_buffer size is empty, then read() cannot be distinguished from EOF
assert(!internal_buffer.empty());
size_t bytes_read = 0; size_t bytes_read = 0;
while (!bytes_read) while (!bytes_read)
{ {

View File

@ -37,6 +37,9 @@ namespace ErrorCodes
std::future<IAsynchronousReader::Result> SynchronousReader::submit(Request request) std::future<IAsynchronousReader::Result> SynchronousReader::submit(Request request)
{ {
/// If size is zero, then read() cannot be distinguished from EOF
assert(request.size);
int fd = assert_cast<const LocalFileDescriptor &>(*request.descriptor).fd; int fd = assert_cast<const LocalFileDescriptor &>(*request.descriptor).fd;
#if defined(POSIX_FADV_WILLNEED) #if defined(POSIX_FADV_WILLNEED)

View File

@ -76,6 +76,9 @@ ThreadPoolReader::ThreadPoolReader(size_t pool_size, size_t queue_size_)
std::future<IAsynchronousReader::Result> ThreadPoolReader::submit(Request request) std::future<IAsynchronousReader::Result> ThreadPoolReader::submit(Request request)
{ {
/// If size is zero, then read() cannot be distinguished from EOF
assert(request.size);
int fd = assert_cast<const LocalFileDescriptor &>(*request.descriptor).fd; int fd = assert_cast<const LocalFileDescriptor &>(*request.descriptor).fd;
#if defined(__linux__) #if defined(__linux__)