From b0f9112696eb0ab583cb69eb709d2b6d1b09e01f Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Fri, 15 Oct 2021 10:13:11 +0300 Subject: [PATCH] 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. --- src/IO/ReadBufferFromFileDescriptor.cpp | 3 +++ src/IO/SynchronousReader.cpp | 3 +++ src/IO/ThreadPoolReader.cpp | 3 +++ 3 files changed, 9 insertions(+) diff --git a/src/IO/ReadBufferFromFileDescriptor.cpp b/src/IO/ReadBufferFromFileDescriptor.cpp index a710dfe33fb..ed8eba62f04 100644 --- a/src/IO/ReadBufferFromFileDescriptor.cpp +++ b/src/IO/ReadBufferFromFileDescriptor.cpp @@ -51,6 +51,9 @@ std::string ReadBufferFromFileDescriptor::getFileName() const 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; while (!bytes_read) { diff --git a/src/IO/SynchronousReader.cpp b/src/IO/SynchronousReader.cpp index 82f29da7d91..e47ed48b7f4 100644 --- a/src/IO/SynchronousReader.cpp +++ b/src/IO/SynchronousReader.cpp @@ -37,6 +37,9 @@ namespace ErrorCodes std::future SynchronousReader::submit(Request request) { + /// If size is zero, then read() cannot be distinguished from EOF + assert(request.size); + int fd = assert_cast(*request.descriptor).fd; #if defined(POSIX_FADV_WILLNEED) diff --git a/src/IO/ThreadPoolReader.cpp b/src/IO/ThreadPoolReader.cpp index 701fa759848..273778df37c 100644 --- a/src/IO/ThreadPoolReader.cpp +++ b/src/IO/ThreadPoolReader.cpp @@ -76,6 +76,9 @@ ThreadPoolReader::ThreadPoolReader(size_t pool_size, size_t queue_size_) std::future ThreadPoolReader::submit(Request request) { + /// If size is zero, then read() cannot be distinguished from EOF + assert(request.size); + int fd = assert_cast(*request.descriptor).fd; #if defined(__linux__)