From 0ae1557ed9a7f8b46b6d7e2feaf2fad4cc2c3b3d Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Tue, 23 Aug 2022 17:09:40 +0200 Subject: [PATCH] Make BufferedInStream allocation more available Allow subclasses to call it, instead of it being strictly internal. This is useful when a subclass can only provide data in minimum sized chunks. --- common/rdr/BufferedInStream.cxx | 18 ++++++++++++++++-- common/rdr/BufferedInStream.h | 7 ++++++- common/rdr/FdInStream.cxx | 4 ++-- common/rdr/FdInStream.h | 2 +- common/rdr/FileInStream.cxx | 4 ++-- common/rdr/FileInStream.h | 2 +- common/rdr/HexInStream.cxx | 4 ++-- common/rdr/HexInStream.h | 2 +- common/rdr/RandomStream.cxx | 10 +++++----- common/rdr/RandomStream.h | 2 +- common/rdr/TLSInStream.cxx | 4 ++-- common/rdr/TLSInStream.h | 2 +- common/rdr/ZlibInStream.cxx | 4 ++-- common/rdr/ZlibInStream.h | 2 +- 14 files changed, 43 insertions(+), 24 deletions(-) diff --git a/common/rdr/BufferedInStream.cxx b/common/rdr/BufferedInStream.cxx index d322793d4f..9972e13e6a 100644 --- a/common/rdr/BufferedInStream.cxx +++ b/common/rdr/BufferedInStream.cxx @@ -21,6 +21,8 @@ #include #endif +#include + #include #include @@ -47,10 +49,15 @@ size_t BufferedInStream::pos() return offset + ptr - start; } -bool BufferedInStream::overrun(size_t needed) +void BufferedInStream::ensureSpace(size_t needed) { struct timeval now; + // Given argument is how much free space is needed, but for allocation + // purposes we need to now how much space everything needs, including + // any existing data already in the buffer + needed += avail(); + if (needed > bufSize) { size_t newSize; U8* newBuffer; @@ -110,9 +117,16 @@ bool BufferedInStream::overrun(size_t needed) end -= ptr - start; ptr = start; } +} + +bool BufferedInStream::overrun(size_t needed) +{ + // Make sure fillBuffer() has room for all the requested data + assert(needed > avail()); + ensureSpace(needed - avail()); while (avail() < needed) { - if (!fillBuffer(start + bufSize - end)) + if (!fillBuffer()) return false; } diff --git a/common/rdr/BufferedInStream.h b/common/rdr/BufferedInStream.h index 84405255e1..05f7231ea4 100644 --- a/common/rdr/BufferedInStream.h +++ b/common/rdr/BufferedInStream.h @@ -37,8 +37,13 @@ namespace rdr { virtual size_t pos(); + protected: + size_t availSpace() { return start + bufSize - end; } + + void ensureSpace(size_t needed); + private: - virtual bool fillBuffer(size_t maxSize) = 0; + virtual bool fillBuffer() = 0; virtual bool overrun(size_t needed); diff --git a/common/rdr/FdInStream.cxx b/common/rdr/FdInStream.cxx index ecc34ecdcb..e0174a8fc3 100644 --- a/common/rdr/FdInStream.cxx +++ b/common/rdr/FdInStream.cxx @@ -57,9 +57,9 @@ FdInStream::~FdInStream() } -bool FdInStream::fillBuffer(size_t maxSize) +bool FdInStream::fillBuffer() { - size_t n = readFd((U8*)end, maxSize); + size_t n = readFd((U8*)end, availSpace()); if (n == 0) return false; end += n; diff --git a/common/rdr/FdInStream.h b/common/rdr/FdInStream.h index 0ae419a9fb..71370a59c8 100644 --- a/common/rdr/FdInStream.h +++ b/common/rdr/FdInStream.h @@ -37,7 +37,7 @@ namespace rdr { int getFd() { return fd; } private: - virtual bool fillBuffer(size_t maxSize); + virtual bool fillBuffer(); size_t readFd(void* buf, size_t len); diff --git a/common/rdr/FileInStream.cxx b/common/rdr/FileInStream.cxx index 198b9ab9c8..43f9ea4ca3 100644 --- a/common/rdr/FileInStream.cxx +++ b/common/rdr/FileInStream.cxx @@ -43,9 +43,9 @@ FileInStream::~FileInStream(void) { } } -bool FileInStream::fillBuffer(size_t maxSize) +bool FileInStream::fillBuffer() { - size_t n = fread((U8 *)end, 1, maxSize, file); + size_t n = fread((U8 *)end, 1, availSpace(), file); if (n == 0) { if (ferror(file)) throw SystemException("fread", errno); diff --git a/common/rdr/FileInStream.h b/common/rdr/FileInStream.h index 619397f0e9..e13596ce8e 100644 --- a/common/rdr/FileInStream.h +++ b/common/rdr/FileInStream.h @@ -34,7 +34,7 @@ namespace rdr { ~FileInStream(void); private: - virtual bool fillBuffer(size_t maxSize); + virtual bool fillBuffer(); private: FILE *file; diff --git a/common/rdr/HexInStream.cxx b/common/rdr/HexInStream.cxx index 9f871f1a2b..3eac9d2e15 100644 --- a/common/rdr/HexInStream.cxx +++ b/common/rdr/HexInStream.cxx @@ -76,11 +76,11 @@ bool HexInStream::hexStrToBin(const char* s, char** data, size_t* length) { } -bool HexInStream::fillBuffer(size_t maxSize) { +bool HexInStream::fillBuffer() { if (!in_stream.hasData(2)) return false; - size_t length = min(in_stream.avail()/2, maxSize); + size_t length = min(in_stream.avail()/2, availSpace()); const U8* iptr = in_stream.getptr(length*2); U8* optr = (U8*) end; diff --git a/common/rdr/HexInStream.h b/common/rdr/HexInStream.h index bd7ca30589..4ce6f7fd04 100644 --- a/common/rdr/HexInStream.h +++ b/common/rdr/HexInStream.h @@ -33,7 +33,7 @@ namespace rdr { static bool hexStrToBin(const char* s, char** data, size_t* length); private: - virtual bool fillBuffer(size_t maxSize); + virtual bool fillBuffer(); private: InStream& in_stream; diff --git a/common/rdr/RandomStream.cxx b/common/rdr/RandomStream.cxx index ec3672120c..c9be704c90 100644 --- a/common/rdr/RandomStream.cxx +++ b/common/rdr/RandomStream.cxx @@ -83,17 +83,17 @@ RandomStream::~RandomStream() { #endif } -bool RandomStream::fillBuffer(size_t maxSize) { +bool RandomStream::fillBuffer() { #ifdef RFB_HAVE_WINCRYPT if (provider) { - if (!CryptGenRandom(provider, maxSize, (U8*)end)) + if (!CryptGenRandom(provider, availSpace(), (U8*)end)) throw rdr::SystemException("unable to CryptGenRandom", GetLastError()); - end += maxSize; + end += availSpace(); } else { #else #ifndef WIN32 if (fp) { - size_t n = fread((U8*)end, 1, maxSize, fp); + size_t n = fread((U8*)end, 1, availSpace(), fp); if (n <= 0) throw rdr::SystemException("reading /dev/urandom or /dev/random failed", errno); @@ -103,7 +103,7 @@ bool RandomStream::fillBuffer(size_t maxSize) { { #endif #endif - for (size_t i=0; i0; i--) *(U8*)end++ = (int) (256.0*rand()/(RAND_MAX+1.0)); } diff --git a/common/rdr/RandomStream.h b/common/rdr/RandomStream.h index 58986433b4..521012e07f 100644 --- a/common/rdr/RandomStream.h +++ b/common/rdr/RandomStream.h @@ -40,7 +40,7 @@ namespace rdr { virtual ~RandomStream(); private: - virtual bool fillBuffer(size_t maxSize); + virtual bool fillBuffer(); private: static unsigned int seed; diff --git a/common/rdr/TLSInStream.cxx b/common/rdr/TLSInStream.cxx index 014789e316..aa552e8697 100644 --- a/common/rdr/TLSInStream.cxx +++ b/common/rdr/TLSInStream.cxx @@ -88,9 +88,9 @@ TLSInStream::~TLSInStream() delete saved_exception; } -bool TLSInStream::fillBuffer(size_t maxSize) +bool TLSInStream::fillBuffer() { - size_t n = readTLS((U8*) end, maxSize); + size_t n = readTLS((U8*) end, availSpace()); if (n == 0) return false; end += n; diff --git a/common/rdr/TLSInStream.h b/common/rdr/TLSInStream.h index 46779d4ca3..397a7b3de2 100644 --- a/common/rdr/TLSInStream.h +++ b/common/rdr/TLSInStream.h @@ -33,7 +33,7 @@ namespace rdr { virtual ~TLSInStream(); private: - virtual bool fillBuffer(size_t maxSize); + virtual bool fillBuffer(); size_t readTLS(U8* buf, size_t len); static ssize_t pull(gnutls_transport_ptr_t str, void* data, size_t size); diff --git a/common/rdr/ZlibInStream.cxx b/common/rdr/ZlibInStream.cxx index 377147ac76..03df10cce6 100644 --- a/common/rdr/ZlibInStream.cxx +++ b/common/rdr/ZlibInStream.cxx @@ -89,13 +89,13 @@ void ZlibInStream::deinit() zs = NULL; } -bool ZlibInStream::fillBuffer(size_t maxSize) +bool ZlibInStream::fillBuffer() { if (!underlying) throw Exception("ZlibInStream overrun: no underlying stream"); zs->next_out = (U8*)end; - zs->avail_out = maxSize; + zs->avail_out = availSpace(); if (!underlying->hasData(1)) return false; diff --git a/common/rdr/ZlibInStream.h b/common/rdr/ZlibInStream.h index 302c99d888..cce6a6e0e1 100644 --- a/common/rdr/ZlibInStream.h +++ b/common/rdr/ZlibInStream.h @@ -44,7 +44,7 @@ namespace rdr { void init(); void deinit(); - virtual bool fillBuffer(size_t maxSize); + virtual bool fillBuffer(); private: InStream* underlying;