CVE-2019-15694: Out-of-bounds Write (CWE-787)
value: TigerVNC version prior to 1.10.1 is vulnerable to heap buffer overflow, which could be triggered from DecodeManager::decodeRect. Vulnerability occurs due to the signdness error in processing MemOutStream. Exploitation of this vulnerability could potentially result into remote code execution. This attack appear to be exploitable via network connectivity.
CWE description: The product writes data past the end, or before the beginning, of the intended buffer.
CVSS v3 base score: 7.2
Published: 2019-12-26T15:15Z
Repository: https://github.com/CendioOssman/tigervnc
Language: C
Files changed: common/rdr/FdInStream.cxx, common/rdr/FdInStream.h, common/rdr/FdOutStream.cxx, common/rdr/FdOutStream.h, common/rdr/FileInStream.cxx, common/rdr/FileInStream.h, common/rdr/HexInStream.cxx, common/rdr/HexInStream.h, common/rdr/HexOutStream.cxx, common/rdr/HexOutStream.h, common/rdr/InStream.h, common/rdr/MemInStream.h, common/rdr/MemOutStream.h, common/rdr/OutStream.h, common/rdr/RandomStream.cxx, common/rdr/RandomStream.h, common/rdr/TLSInStream.cxx, common/rdr/TLSInStream.h, common/rdr/TLSOutStream.cxx, common/rdr/TLSOutStream.h, common/rdr/ZlibInStream.cxx, common/rdr/ZlibInStream.h, common/rdr/ZlibOutStream.cxx, common/rdr/ZlibOutStream.h, common/rfb/Configuration.cxx, common/rfb/Configuration.h, common/rfb/Password.cxx, common/rfb/Password.h, common/rfb/util.h, tests/perf/encperf.cxx, win/rfb_win32/Registry.cxx, win/rfb_win32/Registry.h
Commit date: 2019-11-15 11:55:05 +0100
Commit message: Use size_t for lengths in stream objects

Provides safety against them accidentally becoming negative because
of bugs in the calculations.

Also does the same to CharArray and friends as they were strongly
connection to the stream objects.

Diff: diff --git a/common/rdr/FdInStream.cxx b/common/rdr/FdInStream.cxx
index 1b9a322a3..9e84ab7aa 100644
--- a/common/rdr/FdInStream.cxx
+++ b/common/rdr/FdInStream.cxx
@@ -54,22 +54,22 @@
 using namespace rdr;
 
 enum { DEFAULT_BUF_SIZE = 8192,
        MIN_BULK_SIZE = 1024 };
 
-FdInStream::FdInStream(int fd_, int timeoutms_, int bufSize_,
+FdInStream::FdInStream(int fd_, int timeoutms_, size_t bufSize_,
                        bool closeWhenDone_)
   : fd(fd_), closeWhenDone(closeWhenDone_),
     timeoutms(timeoutms_), blockCallback(0),
     timing(false), timeWaitedIn100us(5), timedKbits(0),
     bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_SIZE), offset(0)
 {
   ptr = end = start = new U8[bufSize];
 }
 
 FdInStream::FdInStream(int fd_, FdInStreamBlockCallback* blockCallback_,
-                       int bufSize_)
+                       size_t bufSize_)
   : fd(fd_), timeoutms(0), blockCallback(blockCallback_),
     timing(false), timeWaitedIn100us(5), timedKbits(0),
     bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_SIZE), offset(0)
 {
   ptr = end = start = new U8[bufSize];
@@ -90,25 +90,25 @@ void FdInStream::setBlockCallback(FdInStreamBlockCallback* blockCallback_)
 {
   blockCallback = blockCallback_;
   timeoutms = 0;
 }
 
-int FdInStream::pos()
+size_t FdInStream::pos()
 {
   return offset + ptr - start;
 }
 
-void FdInStream::readBytes(void* data, int length)
+void FdInStream::readBytes(void* data, size_t length)
 {
   if (length < MIN_BULK_SIZE) {
     InStream::readBytes(data, length);
     return;
   }
 
   U8* dataPtr = (U8*)data;
 
-  int n = end - ptr;
+  size_t n = end - ptr;
   if (n > length) n = length;
 
   memcpy(dataPtr, ptr, n);
   dataPtr += n;
   length -= n;
@@ -121,11 +121,11 @@ void FdInStream::readBytes(void* data, int length)
     offset += n;
   }
 }
 
 
-int FdInStream::overrun(int itemSize, int nItems, bool wait)
+size_t FdInStream::overrun(size_t itemSize, size_t nItems, bool wait)
 {
   if (itemSize > bufSize)
     throw Exception("FdInStream overrun: max itemSize exceeded");
 
   if (end - ptr != 0)
@@ -133,11 +133,11 @@ int FdInStream::overrun(int itemSize, int nItems, bool wait)
 
   offset += ptr - start;
   end -= ptr - start;
   ptr = start;
 
-  int bytes_to_read;
+  size_t bytes_to_read;
   while (end < start + itemSize) {
     bytes_to_read = start + bufSize - end;
     if (!timing) {
       // When not timing, we must be careful not to read too much
       // extra data into the buffer. Otherwise, the line speed
@@ -145,16 +145,16 @@ int FdInStream::overrun(int itemSize, int nItems, bool wait)
       // during timing=1 can be satisfied without calling
       // readWithTimeoutOrCallback. However, reading only 1 or 2 bytes
       // bytes is ineffecient.
       bytes_to_read = vncmin(bytes_to_read, vncmax(itemSize*nItems, 8));
     }
-    int n = readWithTimeoutOrCallback((U8*)end, bytes_to_read, wait);
+    size_t n = readWithTimeoutOrCallback((U8*)end, bytes_to_read, wait);
     if (n == 0) return 0;
     end += n;
   }
 
-  if (itemSize * nItems > end - ptr)
+  if (itemSize * nItems > (size_t)(end - ptr))
     nItems = (end - ptr) / itemSize;
 
   return nItems;
 }
 
@@ -169,11 +169,11 @@ int FdInStream::overrun(int itemSize, int nItems, bool wait)
 // this means it can be used on an fd which has been set non-blocking.  It also
 // has to cope with the annoying possibility of both select() and recv()
 // returning EINTR.
 //
 
-int FdInStream::readWithTimeoutOrCallback(void* buf, int len, bool wait)
+size_t FdInStream::readWithTimeoutOrCallback(void* buf, size_t len, bool wait)
 {
   struct timeval before, after;
   if (timing)
     gettimeofday(&before, 0);
 
diff --git a/common/rdr/FdInStream.h b/common/rdr/FdInStream.h
index b4c876538..d99ad3cec 100644
--- a/common/rdr/FdInStream.h
+++ b/common/rdr/FdInStream.h
@@ -35,43 +35,44 @@ namespace rdr {
 
   class FdInStream : public InStream {
 
   public:
 
-    FdInStream(int fd, int timeoutms=-1, int bufSize=0,
+    FdInStream(int fd, int timeoutms=-1, size_t bufSize=0,
                bool closeWhenDone_=false);
-    FdInStream(int fd, FdInStreamBlockCallback* blockCallback, int bufSize=0);
+    FdInStream(int fd, FdInStreamBlockCallback* blockCallback,
+               size_t bufSize=0);
     virtual ~FdInStream();
 
     void setTimeout(int timeoutms);
     void setBlockCallback(FdInStreamBlockCallback* blockCallback);
     int getFd() { return fd; }
-    int pos();
-    void readBytes(void* data, int length);
+    size_t pos();
+    void readBytes(void* data, size_t length);
 
     void startTiming();
     void stopTiming();
     unsigned int kbitsPerSecond();
     unsigned int timeWaited() { return timeWaitedIn100us; }
 
   protected:
-    int overrun(int itemSize, int nItems, bool wait);
+    size_t overrun(size_t itemSize, size_t nItems, bool wait);
 
   private:
-    int readWithTimeoutOrCallback(void* buf, int len, bool wait=true);
+    size_t readWithTimeoutOrCallback(void* buf, size_t len, bool wait=true);
 
     int fd;
     bool closeWhenDone;
     int timeoutms;
     FdInStreamBlockCallback* blockCallback;
 
     bool timing;
     unsigned int timeWaitedIn100us;
     unsigned int timedKbits;
 
-    int bufSize;
-    int offset;
+    size_t bufSize;
+    size_t offset;
     U8* start;
   };
 
 } // end of namespace rdr
 
diff --git a/common/rdr/FdOutStream.cxx b/common/rdr/FdOutStream.cxx
index cf857f851..1757dc35d 100644
--- a/common/rdr/FdOutStream.cxx
+++ b/common/rdr/FdOutStream.cxx
@@ -49,11 +49,11 @@
 
 using namespace rdr;
 
 enum { DEFAULT_BUF_SIZE = 16384 };
 
-FdOutStream::FdOutStream(int fd_, bool blocking_, int timeoutms_, int bufSize_)
+FdOutStream::FdOutStream(int fd_, bool blocking_, int timeoutms_, size_t bufSize_)
   : fd(fd_), blocking(blocking_), timeoutms(timeoutms_),
     bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_SIZE), offset(0)
 {
   ptr = start = sentUpTo = new U8[bufSize];
   end = start + bufSize;
@@ -77,11 +77,11 @@ void FdOutStream::setTimeout(int timeoutms_) {
 
 void FdOutStream::setBlocking(bool blocking_) {
   blocking = blocking_;
 }
 
-int FdOutStream::length()
+size_t FdOutStream::length()
 {
   return offset + ptr - sentUpTo;
 }
 
 int FdOutStream::bufferUsage()
@@ -95,13 +95,13 @@ unsigned FdOutStream::getIdleTime()
 }
 
 void FdOutStream::flush()
 {
   while (sentUpTo < ptr) {
-    int n = writeWithTimeout((const void*) sentUpTo,
-                             ptr - sentUpTo,
-                             blocking? timeoutms : 0);
+    size_t n = writeWithTimeout((const void*) sentUpTo,
+                                ptr - sentUpTo,
+                                blocking? timeoutms : 0);
 
     // Timeout?
     if (n == 0) {
       // If non-blocking then we're done here
       if (!blocking)
@@ -118,23 +118,23 @@ void FdOutStream::flush()
   if (sentUpTo == ptr)
     ptr = sentUpTo = start;
 }
 
 
-int FdOutStream::overrun(int itemSize, int nItems)
+size_t FdOutStream::overrun(size_t itemSize, size_t nItems)
 {
   if (itemSize > bufSize)
     throw Exception("FdOutStream overrun: max itemSize exceeded");
 
   // First try to get rid of the data we have
   flush();
 
   // Still not enough space?
-  if (itemSize > end - ptr) {
+  if (itemSize > (size_t)(end - ptr)) {
     // Can we shuffle things around?
     // (don't do this if it gains us less than 25%)
-    if ((sentUpTo - start > bufSize / 4) &&
+    if (((size_t)(sentUpTo - start) > bufSize / 4) &&
         (itemSize < bufSize - (ptr - sentUpTo))) {
       memmove(start, sentUpTo, ptr - sentUpTo);
       ptr = start + (ptr - sentUpTo);
       sentUpTo = start;
     } else {
@@ -148,11 +148,11 @@ int FdOutStream::overrun(int itemSize, int nItems)
       blocking = realBlocking;
     }
   }
 
   // Can we fit all the items asked for?
-  if (itemSize * nItems > end - ptr)
+  if (itemSize * nItems > (size_t)(end - ptr))
     nItems = (end - ptr) / itemSize;
 
   return nItems;
 }
 
@@ -164,11 +164,11 @@ int FdOutStream::overrun(int itemSize, int nItems)
 // the fd is writable - this means it can be used on an fd which has been set
 // non-blocking.  It also has to cope with the annoying possibility of both
 // select() and send() returning EINTR.
 //
 
-int FdOutStream::writeWithTimeout(const void* data, int length, int timeoutms)
+size_t FdOutStream::writeWithTimeout(const void* data, size_t length, int timeoutms)
 {
   int n;
 
   do {
     fd_set fds;
diff --git a/common/rdr/FdOutStream.h b/common/rdr/FdOutStream.h
index b7f6cb015..ed84fdb5f 100644
--- a/common/rdr/FdOutStream.h
+++ b/common/rdr/FdOutStream.h
@@ -32,32 +32,32 @@ namespace rdr {
 
   class FdOutStream : public OutStream {
 
   public:
 
-    FdOutStream(int fd, bool blocking=true, int timeoutms=-1, int bufSize=0);
+    FdOutStream(int fd, bool blocking=true, int timeoutms=-1, size_t bufSize=0);
     virtual ~FdOutStream();
 
     void setTimeout(int timeoutms);
     void setBlocking(bool blocking);
     int getFd() { return fd; }
 
     void flush();
-    int length();
+    size_t length();
 
     int bufferUsage();
 
     unsigned getIdleTime();
 
   private:
-    int overrun(int itemSize, int nItems);
-    int writeWithTimeout(const void* data, int length, int timeoutms);
+    size_t overrun(size_t itemSize, size_t nItems);
+    size_t writeWithTimeout(const void* data, size_t length, int timeoutms);
     int fd;
     bool blocking;
     int timeoutms;
-    int bufSize;
-    int offset;
+    size_t bufSize;
+    size_t offset;
     U8* start;
     U8* sentUpTo;
     struct timeval lastWrite;
   };
 
diff --git a/common/rdr/FileInStream.cxx b/common/rdr/FileInStream.cxx
index 3acdfd45b..94f5db882 100644
--- a/common/rdr/FileInStream.cxx
+++ b/common/rdr/FileInStream.cxx
@@ -46,21 +46,21 @@ void FileInStream::reset(void) {
   if (fseek(file, 0, SEEK_SET) != 0)
     throw SystemException("fseek", errno);
   ptr = end = b;
 }
 
-int FileInStream::pos()
+size_t FileInStream::pos()
 {
   if (!file)
     throw Exception("File is not open");
 
   return ftell(file) + ptr - b;
 }
 
-int FileInStream::overrun(int itemSize, int nItems, bool wait)
+size_t FileInStream::overrun(size_t itemSize, size_t nItems, bool wait)
 {
-  if (itemSize > (int)sizeof(b))
+  if (itemSize > sizeof(b))
     throw Exception("FileInStream overrun: max itemSize exceeded");
 
   if (end - ptr != 0)
     memmove(b, ptr, end - ptr);
 
@@ -78,10 +78,10 @@ int FileInStream::overrun(int itemSize, int nItems, bool wait)
       return 0;
     }
     end += b + sizeof(b) - end;
   }
 
-  if (itemSize * nItems > end - ptr)
+  if (itemSize * nItems > (size_t)(end - ptr))
     nItems = (end - ptr) / itemSize;
 
   return nItems;
 }
diff --git a/common/rdr/FileInStream.h b/common/rdr/FileInStream.h
index ace04f379..a33c765e4 100644
--- a/common/rdr/FileInStream.h
+++ b/common/rdr/FileInStream.h
@@ -33,14 +33,14 @@ namespace rdr {
     FileInStream(const char *fileName);
     ~FileInStream(void);
 
     void reset(void);
 
-    int pos();
+    size_t pos();
 
   protected:
-    int overrun(int itemSize, int nItems, bool wait = true);
+    size_t overrun(size_t itemSize, size_t nItems, bool wait = true);
 
   private:
     U8 b[131072];
     FILE *file;
   };
diff --git a/common/rdr/HexInStream.cxx b/common/rdr/HexInStream.cxx
index 80f8a7967..8f939889b 100644
--- a/common/rdr/HexInStream.cxx
+++ b/common/rdr/HexInStream.cxx
@@ -26,11 +26,11 @@ using namespace rdr;
 
 const int DEFAULT_BUF_LEN = 16384;
 
 static inline int min(int a, int b) {return a<b ? a : b;}
 
-HexInStream::HexInStream(InStream& is, int bufSize_)
+HexInStream::HexInStream(InStream& is, size_t bufSize_)
 : bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_LEN), offset(0), in_stream(is)
 {
   ptr = end = start = new U8[bufSize];
 }
 
@@ -48,20 +48,20 @@ bool HexInStream::readHexAndShift(char c, int* v) {
   else
     return false;
   return true;
 }
 
-bool HexInStream::hexStrToBin(const char* s, char** data, int* length) {
-  int l=strlen(s);
+bool HexInStream::hexStrToBin(const char* s, char** data, size_t* length) {
+  size_t l=strlen(s);
   if ((l % 2) == 0) {
     delete [] *data;
     *data = 0; *length = 0;
     if (l == 0)
       return true;
     *data = new char[l/2];
     *length = l/2;
-    for(int i=0;i<l;i+=2) {
+    for(size_t i=0;i<l;i+=2) {
       int byte = 0;
       if (!readHexAndShift(s[i], &byte) ||
         !readHexAndShift(s[i+1], &byte))
         goto decodeError;
       (*data)[i/2] = byte;
@@ -74,15 +74,15 @@ decodeError:
   *length = 0;
   return false;
 }
 
 
-int HexInStream::pos() {
+size_t HexInStream::pos() {
   return offset + ptr - start;
 }
 
-int HexInStream::overrun(int itemSize, int nItems, bool wait) {
+size_t HexInStream::overrun(size_t itemSize, size_t nItems, bool wait) {
   if (itemSize > bufSize)
     throw Exception("HexInStream overrun: max itemSize exceeded");
 
   if (end - ptr != 0)
     memmove(start, ptr, end - ptr);
@@ -90,28 +90,28 @@ int HexInStream::overrun(int itemSize, int nItems, bool wait) {
   end -= ptr - start;
   offset += ptr - start;
   ptr = start;
 
   while (end < ptr + itemSize) {
-    int n = in_stream.check(2, 1, wait);
+    size_t n = in_stream.check(2, 1, wait);
     if (n == 0) return 0;
     const U8* iptr = in_stream.getptr();
     const U8* eptr = in_stream.getend();
-    int length = min((eptr - iptr)/2, start + bufSize - end);
+    size_t length = min((eptr - iptr)/2, start + bufSize - end);
 
     U8* optr = (U8*) end;
-    for (int i=0; i<length; i++) {
+    for (size_t i=0; i<length; i++) {
       int v = 0;
       readHexAndShift(iptr[i*2], &v);
       readHexAndShift(iptr[i*2+1], &v);
       optr[i] = v;
     }
 
     in_stream.setptr(iptr + length*2);
     end += length;
   }
 
-  if (itemSize * nItems > end - ptr)
+  if (itemSize * nItems > (size_t)(end - ptr))
     nItems = (end - ptr) / itemSize;
 
   return nItems;
 }
diff --git a/common/rdr/HexInStream.h b/common/rdr/HexInStream.h
index 6bfb84338..8e495fbea 100644
--- a/common/rdr/HexInStream.h
+++ b/common/rdr/HexInStream.h
@@ -24,25 +24,25 @@
 namespace rdr {
 
   class HexInStream : public InStream {
   public:
 
-    HexInStream(InStream& is, int bufSize=0);
+    HexInStream(InStream& is, size_t bufSize=0);
     virtual ~HexInStream();
 
-    int pos();
+    size_t pos();
 
     static bool readHexAndShift(char c, int* v);
-    static bool hexStrToBin(const char* s, char** data, int* length);
+    static bool hexStrToBin(const char* s, char** data, size_t* length);
 
   protected:
-    int overrun(int itemSize, int nItems, bool wait);
+    size_t overrun(size_t itemSize, size_t nItems, bool wait);
 
   private:
-    int bufSize;
+    size_t bufSize;
     U8* start;
-    int offset;
+    size_t offset;
 
     InStream& in_stream;
   };
 
 } // end of namespace rdr
diff --git a/common/rdr/HexOutStream.cxx b/common/rdr/HexOutStream.cxx
index 9b0b6c4d1..7232514c5 100644
--- a/common/rdr/HexOutStream.cxx
+++ b/common/rdr/HexOutStream.cxx
@@ -21,13 +21,13 @@
 
 using namespace rdr;
 
 const int DEFAULT_BUF_LEN = 16384;
 
-static inline int min(int a, int b) {return a<b ? a : b;}
+static inline size_t min(size_t a, size_t b) {return a<b ? a : b;}
 
-HexOutStream::HexOutStream(OutStream& os, int buflen)
+HexOutStream::HexOutStream(OutStream& os, size_t buflen)
 : out_stream(os), offset(0), bufSize(buflen ? buflen : DEFAULT_BUF_LEN)
 {
   if (bufSize % 2)
     bufSize--;
   ptr = start = new U8[bufSize];
@@ -46,13 +46,13 @@ char HexOutStream::intToHex(int i) {
     return 'a'+(i-10);
   else
     throw rdr::Exception("intToHex failed");
 }
 
-char* HexOutStream::binToHexStr(const char* data, int length) {
+char* HexOutStream::binToHexStr(const char* data, size_t length) {
   char* buffer = new char[length*2+1];
-  for (int i=0; i<length; i++) {
+  for (size_t i=0; i<length; i++) {
     buffer[i*2] = intToHex((data[i] >> 4) & 15);
     buffer[i*2+1] = intToHex((data[i] & 15));
     if (!buffer[i*2] || !buffer[i*2+1]) {
       delete [] buffer;
       return 0;
@@ -68,13 +68,13 @@ HexOutStream::writeBuffer() {
   U8* pos = start;
   while (pos != ptr) {
     out_stream.check(2);
     U8* optr = out_stream.getptr();
     U8* oend = out_stream.getend();
-    int length = min(ptr-pos, (oend-optr)/2);
+    size_t length = min(ptr-pos, (oend-optr)/2);
 
-    for (int i=0; i<length; i++) {
+    for (size_t i=0; i<length; i++) {
       optr[i*2] = intToHex((pos[i] >> 4) & 0xf);
       optr[i*2+1] = intToHex(pos[i] & 0xf);
     }
 
     out_stream.setptr(optr + length*2);
@@ -82,29 +82,29 @@ HexOutStream::writeBuffer() {
   }
   offset += ptr - start;
   ptr = start;
 }
 
-int HexOutStream::length()
+size_t HexOutStream::length()
 {
   return offset + ptr - start;
 }
 
 void
 HexOutStream::flush() {
   writeBuffer();
   out_stream.flush();
 }
 
-int
-HexOutStream::overrun(int itemSize, int nItems) {
+size_t
+HexOutStream::overrun(size_t itemSize, size_t nItems) {
   if (itemSize > bufSize)
     throw Exception("HexOutStream overrun: max itemSize exceeded");
 
   writeBuffer();
 
-  if (itemSize * nItems > end - ptr)
+  if (itemSize * nItems > (size_t)(end - ptr))
     nItems = (end - ptr) / itemSize;
 
   return nItems;
 }
 
diff --git a/common/rdr/HexOutStream.h b/common/rdr/HexOutStream.h
index 10247e683..92442a727 100644
--- a/common/rdr/HexOutStream.h
+++ b/common/rdr/HexOutStream.h
@@ -24,28 +24,28 @@
 namespace rdr {
 
   class HexOutStream : public OutStream {
   public:
 
-    HexOutStream(OutStream& os, int buflen=0);
+    HexOutStream(OutStream& os, size_t buflen=0);
     virtual ~HexOutStream();
 
     void flush();
-    int length();
+    size_t length();
 
     static char intToHex(int i);
-    static char* binToHexStr(const char* data, int length);
+    static char* binToHexStr(const char* data, size_t length);
 
   private:
     void writeBuffer();
-    int overrun(int itemSize, int nItems);
+    size_t overrun(size_t itemSize, size_t nItems);
 
     OutStream& out_stream;
 
     U8* start;
-    int offset;
-    int bufSize;
+    size_t offset;
+    size_t bufSize;
   };
 
 }
 
 #endif
diff --git a/common/rdr/InStream.h b/common/rdr/InStream.h
index 212a2ec9a..14ecf0938 100644
--- a/common/rdr/InStream.h
+++ b/common/rdr/InStream.h
@@ -39,11 +39,11 @@ namespace rdr {
     // itemSize bytes.  Returns the number of items in the buffer (up to a
     // maximum of nItems).  If wait is false, then instead of blocking to wait
     // for the bytes, zero is returned if the bytes are not immediately
     // available.
 
-    inline int check(int itemSize, int nItems=1, bool wait=true)
+    inline size_t check(size_t itemSize, size_t nItems=1, bool wait=true)
     {
       if (ptr + itemSize * nItems > end) {
         if (ptr + itemSize > end)
           return overrun(itemSize, nItems, wait);
 
@@ -54,11 +54,11 @@ namespace rdr {
 
     // checkNoWait() tries to make sure that the given number of bytes can
     // be read without blocking.  It returns true if this is the case, false
     // otherwise.  The length must be "small" (less than the buffer size).
 
-    inline bool checkNoWait(int length) { return check(length, 1, false)!=0; }
+    inline bool checkNoWait(size_t length) { return check(length, 1, false)!=0; }
 
     // readU/SN() methods read unsigned and signed N-bit integers.
 
     inline U8  readU8()  { check(1); return *ptr++; }
     inline U16 readU16() { check(2); int b0 = *ptr++; int b1 = *ptr++;
@@ -80,25 +80,25 @@ namespace rdr {
     // maxStringLength protects against allocating a huge buffer.  Set it
     // higher if you need longer strings.
 
     static U32 maxStringLength;
 
-    inline void skip(int bytes) {
+    inline void skip(size_t bytes) {
       while (bytes > 0) {
-        int n = check(1, bytes);
+        size_t n = check(1, bytes);
         ptr += n;
         bytes -= n;
       }
     }
 
     // readBytes() reads an exact number of bytes.
 
-    void readBytes(void* data, int length) {
+    void readBytes(void* data, size_t length) {
       U8* dataPtr = (U8*)data;
       U8* dataEnd = dataPtr + length;
       while (dataPtr < dataEnd) {
-        int n = check(1, dataEnd - dataPtr);
+        size_t n = check(1, dataEnd - dataPtr);
         memcpy(dataPtr, ptr, n);
         ptr += n;
         dataPtr += n;
       }
     }
@@ -112,11 +112,11 @@ namespace rdr {
                                 ((U8*)&r)[1] = *ptr++; ((U8*)&r)[2] = *ptr++;
                                 ((U8*)&r)[3] = *ptr++; return r; }
 
     // pos() returns the position in the stream.
 
-    virtual int pos() = 0;
+    virtual size_t pos() = 0;
 
     // getptr(), getend() and setptr() are "dirty" methods which allow you to
     // manipulate the buffer directly.  This is useful for a stream which is a
     // wrapper around an underlying stream.
 
@@ -131,11 +131,11 @@ namespace rdr {
     // the number of items in the buffer (up to a maximum of nItems).  itemSize
     // is supposed to be "small" (a few bytes).  If wait is false, then
     // instead of blocking to wait for the bytes, zero is returned if the bytes
     // are not immediately available.
 
-    virtual int overrun(int itemSize, int nItems, bool wait=true) = 0;
+    virtual size_t overrun(size_t itemSize, size_t nItems, bool wait=true) = 0;
 
   protected:
 
     InStream() {}
     const U8* ptr;
diff --git a/common/rdr/MemInStream.h b/common/rdr/MemInStream.h
index 1a6a7982e..3e9e77bcf 100644
--- a/common/rdr/MemInStream.h
+++ b/common/rdr/MemInStream.h
@@ -34,11 +34,11 @@ namespace rdr {
 
   class MemInStream : public InStream {
 
   public:
 
-    MemInStream(const void* data, int len, bool deleteWhenDone_=false)
+    MemInStream(const void* data, size_t len, bool deleteWhenDone_=false)
       : start((const U8*)data), deleteWhenDone(deleteWhenDone_)
     {
       ptr = start;
       end = start + len;
     }
@@ -46,16 +46,16 @@ namespace rdr {
     virtual ~MemInStream() {
       if (deleteWhenDone)
         delete [] start;
     }
 
-    int pos() { return ptr - start; }
-    void reposition(int pos) { ptr = start + pos; }
+    size_t pos() { return ptr - start; }
+    void reposition(size_t pos) { ptr = start + pos; }
 
   private:
 
-    int overrun(int itemSize, int nItems, bool wait) { throw EndOfStream(); }
+    size_t overrun(size_t itemSize, size_t nItems, bool wait) { throw EndOfStream(); }
     const U8* start;
     bool deleteWhenDone;
   };
 
 }
diff --git a/common/rdr/MemOutStream.h b/common/rdr/MemOutStream.h
index 3b17e5556..4a815b300 100644
--- a/common/rdr/MemOutStream.h
+++ b/common/rdr/MemOutStream.h
@@ -38,33 +38,33 @@ namespace rdr {
 
     virtual ~MemOutStream() {
       delete [] start;
     }
 
-    void writeBytes(const void* data, int length) {
+    void writeBytes(const void* data, size_t length) {
       check(length);
       memcpy(ptr, data, length);
       ptr += length;
     }
 
-    int length() { return ptr - start; }
+    size_t length() { return ptr - start; }
     void clear() { ptr = start; };
     void clearAndZero() { memset(start, 0, ptr-start); clear(); }
-    void reposition(int pos) { ptr = start + pos; }
+    void reposition(size_t pos) { ptr = start + pos; }
 
     // data() returns a pointer to the buffer.
 
     const void* data() { return (const void*)start; }
 
   protected:
 
     // overrun() either doubles the buffer or adds enough space for nItems of
     // size itemSize bytes.
 
-    int overrun(int itemSize, int nItems) {
-      int len = ptr - start + itemSize * nItems;
-      if (len < (end - start) * 2)
+    size_t overrun(size_t itemSize, size_t nItems) {
+      size_t len = ptr - start + itemSize * nItems;
+      if (len < (size_t)(end - start) * 2)
         len = (end - start) * 2;
 
       U8* newStart = new U8[len];
       memcpy(newStart, start, ptr - start);
       ptr = newStart + (ptr - start);
diff --git a/common/rdr/OutStream.h b/common/rdr/OutStream.h
index a749a208a..11aafd2d9 100644
--- a/common/rdr/OutStream.h
+++ b/common/rdr/OutStream.h
@@ -42,11 +42,11 @@ namespace rdr {
 
     // check() ensures there is buffer space for at least one item of size
     // itemSize bytes.  Returns the number of items which fit (up to a maximum
     // of nItems).
 
-    inline int check(int itemSize, int nItems=1)
+    inline size_t check(size_t itemSize, size_t nItems=1)
     {
       if (ptr + itemSize * nItems > end) {
         if (ptr + itemSize > end)
           return overrun(itemSize, nItems);
 
@@ -74,40 +74,40 @@ namespace rdr {
       U32 len = strlen(str);
       writeU32(len);
       writeBytes(str, len);
     }
 
-    inline void pad(int bytes) {
+    inline void pad(size_t bytes) {
       while (bytes-- > 0) writeU8(0);
     }
 
-    inline void skip(int bytes) {
+    inline void skip(size_t bytes) {
       while (bytes > 0) {
-        int n = check(1, bytes);
+        size_t n = check(1, bytes);
         ptr += n;
         bytes -= n;
       }
     }
 
     // writeBytes() writes an exact number of bytes.
 
-    void writeBytes(const void* data, int length) {
+    void writeBytes(const void* data, size_t length) {
       const U8* dataPtr = (const U8*)data;
       const U8* dataEnd = dataPtr + length;
       while (dataPtr < dataEnd) {
-        int n = check(1, dataEnd - dataPtr);
+        size_t n = check(1, dataEnd - dataPtr);
         memcpy(ptr, dataPtr, n);
         ptr += n;
         dataPtr += n;
       }
     }
 
     // copyBytes() efficiently transfers data between streams
 
-    void copyBytes(InStream* is, int length) {
+    void copyBytes(InStream* is, size_t length) {
       while (length > 0) {
-        int n = check(1, length);
+        size_t n = check(1, length);
         is->readBytes(ptr, n);
         ptr += n;
         length -= n;
       }
     }
@@ -122,11 +122,11 @@ namespace rdr {
                                        *ptr++ = ((U8*)&u)[2];
                                        *ptr++ = ((U8*)&u)[3]; }
 
     // length() returns the length of the stream.
 
-    virtual int length() = 0;
+    virtual size_t length() = 0;
 
     // flush() requests that the stream be flushed.
 
     virtual void flush() {}
 
@@ -143,11 +143,11 @@ namespace rdr {
     // overrun() is implemented by a derived class to cope with buffer overrun.
     // It ensures there are at least itemSize bytes of buffer space.  Returns
     // the number of items which fit (up to a maximum of nItems).  itemSize is
     // supposed to be "small" (a few bytes).
 
-    virtual int overrun(int itemSize, int nItems) = 0;
+    virtual size_t overrun(size_t itemSize, size_t nItems) = 0;
 
   protected:
 
     U8* ptr;
     U8* end;
diff --git a/common/rdr/RandomStream.cxx b/common/rdr/RandomStream.cxx
index e22da3d07..d5f1cc853 100644
--- a/common/rdr/RandomStream.cxx
+++ b/common/rdr/RandomStream.cxx
@@ -33,11 +33,11 @@
 
 static rfb::LogWriter vlog("RandomStream");
 
 using namespace rdr;
 
-const int DEFAULT_BUF_LEN = 256;
+const size_t DEFAULT_BUF_LEN = 256;
 
 unsigned int RandomStream::seed;
 
 RandomStream::RandomStream()
   : offset(0)
@@ -84,50 +84,50 @@ RandomStream::~RandomStream() {
 #ifndef WIN32
   if (fp) fclose(fp);
 #endif
 }
 
-int RandomStream::pos() {
+size_t RandomStream::pos() {
   return offset + ptr - start;
 }
 
-int RandomStream::overrun(int itemSize, int nItems, bool wait) {
+size_t RandomStream::overrun(size_t itemSize, size_t nItems, bool wait) {
   if (itemSize > DEFAULT_BUF_LEN)
     throw Exception("RandomStream overrun: max itemSize exceeded");
 
   if (end - ptr != 0)
     memmove(start, ptr, end - ptr);
 
   end -= ptr - start;
   offset += ptr - start;
   ptr = start;
 
-  int length = start + DEFAULT_BUF_LEN - end;
+  size_t length = start + DEFAULT_BUF_LEN - end;
 
 #ifdef RFB_HAVE_WINCRYPT
   if (provider) {
     if (!CryptGenRandom(provider, length, (U8*)end))
       throw rdr::SystemException("unable to CryptGenRandom", GetLastError());
     end += length;
   } else {
 #else
 #ifndef WIN32
   if (fp) {
-    int n = fread((U8*)end, length, 1, fp);
+    size_t n = fread((U8*)end, length, 1, fp);
     if (n != 1)
       throw rdr::SystemException("reading /dev/urandom or /dev/random failed",
                                  errno);
     end += length;
   } else {
 #else
   {
 #endif
 #endif
-    for (int i=0; i<length; i++)
+    for (size_t i=0; i<length; i++)
       *(U8*)end++ = (int) (256.0*rand()/(RAND_MAX+1.0));
   }
 
-  if (itemSize * nItems > end - ptr)
+  if (itemSize * nItems > (size_t)(end - ptr))
     nItems = (end - ptr) / itemSize;
 
   return nItems;
 }
diff --git a/common/rdr/RandomStream.h b/common/rdr/RandomStream.h
index c33360d73..80b389b2e 100644
--- a/common/rdr/RandomStream.h
+++ b/common/rdr/RandomStream.h
@@ -37,18 +37,18 @@ namespace rdr {
   public:
 
     RandomStream();
     virtual ~RandomStream();
 
-    int pos();
+    size_t pos();
 
   protected:
-    int overrun(int itemSize, int nItems, bool wait);
+    size_t overrun(size_t itemSize, size_t nItems, bool wait);
 
   private:
     U8* start;
-    int offset;
+    size_t offset;
 
     static unsigned int seed;
 #ifdef RFB_HAVE_WINCRYPT
     HCRYPTPROV provider;
 #endif
diff --git a/common/rdr/TLSInStream.cxx b/common/rdr/TLSInStream.cxx
index 77b16729b..d0f94263c 100644
--- a/common/rdr/TLSInStream.cxx
+++ b/common/rdr/TLSInStream.cxx
@@ -73,16 +73,16 @@ TLSInStream::~TLSInStream()
   gnutls_transport_set_pull_function(session, NULL);
 
   delete[] start;
 }
 
-int TLSInStream::pos()
+size_t TLSInStream::pos()
 {
   return offset + ptr - start;
 }
 
-int TLSInStream::overrun(int itemSize, int nItems, bool wait)
+size_t TLSInStream::overrun(size_t itemSize, size_t nItems, bool wait)
 {
   if (itemSize > bufSize)
     throw Exception("TLSInStream overrun: max itemSize exceeded");
 
   if (end - ptr != 0)
@@ -91,23 +91,23 @@ int TLSInStream::overrun(int itemSize, int nItems, bool wait)
   offset += ptr - start;
   end -= ptr - start;
   ptr = start;
 
   while (end < start + itemSize) {
-    int n = readTLS((U8*) end, start + bufSize - end, wait);
+    size_t n = readTLS((U8*) end, start + bufSize - end, wait);
     if (!wait && n == 0)
       return 0;
     end += n;
   }
 
-  if (itemSize * nItems > end - ptr)
+  if (itemSize * nItems > (size_t)(end - ptr))
     nItems = (end - ptr) / itemSize;
 
   return nItems;
 }
 
-int TLSInStream::readTLS(U8* buf, int len, bool wait)
+size_t TLSInStream::readTLS(U8* buf, size_t len, bool wait)
 {
   int n;
 
   n = in->check(1, 1, wait);
   if (n == 0)
diff --git a/common/rdr/TLSInStream.h b/common/rdr/TLSInStream.h
index b16d9f5a2..5f9dee7f2 100644
--- a/common/rdr/TLSInStream.h
+++ b/common/rdr/TLSInStream.h
@@ -34,21 +34,21 @@ namespace rdr {
   class TLSInStream : public InStream {
   public:
     TLSInStream(InStream* in, gnutls_session_t session);
     virtual ~TLSInStream();
 
-    int pos();
+    size_t pos();
 
   private:
-    int overrun(int itemSize, int nItems, bool wait);
-    int readTLS(U8* buf, int len, bool wait);
+    size_t overrun(size_t itemSize, size_t nItems, bool wait);
+    size_t readTLS(U8* buf, size_t len, bool wait);
     static ssize_t pull(gnutls_transport_ptr_t str, void* data, size_t size);
 
     gnutls_session_t session;
     InStream* in;
-    int bufSize;
-    int offset;
+    size_t bufSize;
+    size_t offset;
     U8* start;
   };
 };
 
 #endif
diff --git a/common/rdr/TLSOutStream.cxx b/common/rdr/TLSOutStream.cxx
index 44d2d9f33..30c456fe0 100644
--- a/common/rdr/TLSOutStream.cxx
+++ b/common/rdr/TLSOutStream.cxx
@@ -73,42 +73,42 @@ TLSOutStream::~TLSOutStream()
   gnutls_transport_set_push_function(session, NULL);
 
   delete [] start;
 }
 
-int TLSOutStream::length()
+size_t TLSOutStream::length()
 {
   return offset + ptr - start;
 }
 
 void TLSOutStream::flush()
 {
   U8* sentUpTo = start;
   while (sentUpTo < ptr) {
-    int n = writeTLS(sentUpTo, ptr - sentUpTo);
+    size_t n = writeTLS(sentUpTo, ptr - sentUpTo);
     sentUpTo += n;
     offset += n;
   }
 
   ptr = start;
   out->flush();
 }
 
-int TLSOutStream::overrun(int itemSize, int nItems)
+size_t TLSOutStream::overrun(size_t itemSize, size_t nItems)
 {
   if (itemSize > bufSize)
     throw Exception("TLSOutStream overrun: max itemSize exceeded");
 
   flush();
 
-  if (itemSize * nItems > end - ptr)
+  if (itemSize * nItems > (size_t)(end - ptr))
     nItems = (end - ptr) / itemSize;
 
   return nItems;
 }
 
-int TLSOutStream::writeTLS(const U8* data, int length)
+size_t TLSOutStream::writeTLS(const U8* data, size_t length)
 {
   int n;
 
   n = gnutls_record_send(session, data, length);
   if (n == GNUTLS_E_INTERRUPTED || n == GNUTLS_E_AGAIN)
diff --git a/common/rdr/TLSOutStream.h b/common/rdr/TLSOutStream.h
index 81dd237a9..71a7f3bff 100644
--- a/common/rdr/TLSOutStream.h
+++ b/common/rdr/TLSOutStream.h
@@ -34,24 +34,24 @@ namespace rdr {
   public:
     TLSOutStream(OutStream* out, gnutls_session_t session);
     virtual ~TLSOutStream();
 
     void flush();
-    int length();
+    size_t length();
 
   protected:
-    int overrun(int itemSize, int nItems);
+    size_t overrun(size_t itemSize, size_t nItems);
 
   private:
-    int writeTLS(const U8* data, int length);
+    size_t writeTLS(const U8* data, size_t length);
     static ssize_t push(gnutls_transport_ptr_t str, const void* data, size_t size);
 
     gnutls_session_t session;
     OutStream* out;
-    int bufSize;
+    size_t bufSize;
     U8* start;
-    int offset;
+    size_t offset;
   };
 };
 
 #endif
 #endif
diff --git a/common/rdr/ZlibInStream.cxx b/common/rdr/ZlibInStream.cxx
index a361010cf..e2f971c7d 100644
--- a/common/rdr/ZlibInStream.cxx
+++ b/common/rdr/ZlibInStream.cxx
@@ -24,11 +24,11 @@
 
 using namespace rdr;
 
 enum { DEFAULT_BUF_SIZE = 16384 };
 
-ZlibInStream::ZlibInStream(int bufSize_)
+ZlibInStream::ZlibInStream(size_t bufSize_)
   : underlying(0), bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_SIZE), offset(0),
     zs(NULL), bytesIn(0)
 {
   ptr = end = start = new U8[bufSize];
   init();
@@ -38,18 +38,18 @@ ZlibInStream::~ZlibInStream()
 {
   deinit();
   delete [] start;
 }
 
-void ZlibInStream::setUnderlying(InStream* is, int bytesIn_)
+void ZlibInStream::setUnderlying(InStream* is, size_t bytesIn_)
 {
   underlying = is;
   bytesIn = bytesIn_;
   ptr = end = start;
 }
 
-int ZlibInStream::pos()
+size_t ZlibInStream::pos()
 {
   return offset + ptr - start;
 }
 
 void ZlibInStream::flushUnderlying()
@@ -94,11 +94,11 @@ void ZlibInStream::deinit()
   inflateEnd(zs);
   delete zs;
   zs = NULL;
 }
 
-int ZlibInStream::overrun(int itemSize, int nItems, bool wait)
+size_t ZlibInStream::overrun(size_t itemSize, size_t nItems, bool wait)
 {
   if (itemSize > bufSize)
     throw Exception("ZlibInStream overrun: max itemSize exceeded");
 
   if (end - ptr != 0)
@@ -106,16 +106,16 @@ int ZlibInStream::overrun(int itemSize, int nItems, bool wait)
 
   offset += ptr - start;
   end -= ptr - start;
   ptr = start;
 
-  while (end - ptr < itemSize) {
+  while ((size_t)(end - ptr) < itemSize) {
     if (!decompress(wait))
       return 0;
   }
 
-  if (itemSize * nItems > end - ptr)
+  if (itemSize * nItems > (size_t)(end - ptr))
     nItems = (end - ptr) / itemSize;
 
   return nItems;
 }
 
@@ -129,15 +129,15 @@ bool ZlibInStream::decompress(bool wait)
     throw Exception("ZlibInStream overrun: no underlying stream");
 
   zs->next_out = (U8*)end;
   zs->avail_out = start + bufSize - end;
 
-  int n = underlying->check(1, 1, wait);
+  size_t n = underlying->check(1, 1, wait);
   if (n == 0) return false;
   zs->next_in = (U8*)underlying->getptr();
   zs->avail_in = underlying->getend() - underlying->getptr();
-  if ((int)zs->avail_in > bytesIn)
+  if (zs->avail_in > bytesIn)
     zs->avail_in = bytesIn;
 
   int rc = inflate(zs, Z_SYNC_FLUSH);
   if (rc != Z_OK) {
     throw Exception("ZlibInStream: inflate failed");
diff --git a/common/rdr/ZlibInStream.h b/common/rdr/ZlibInStream.h
index 86ba1ff14..08784b0f1 100644
--- a/common/rdr/ZlibInStream.h
+++ b/common/rdr/ZlibInStream.h
@@ -32,31 +32,31 @@ namespace rdr {
 
   class ZlibInStream : public InStream {
 
   public:
 
-    ZlibInStream(int bufSize=0);
+    ZlibInStream(size_t bufSize=0);
     virtual ~ZlibInStream();
 
-    void setUnderlying(InStream* is, int bytesIn);
+    void setUnderlying(InStream* is, size_t bytesIn);
     void flushUnderlying();
-    int pos();
+    size_t pos();
     void reset();
 
   private:
 
     void init();
     void deinit();
 
-    int overrun(int itemSize, int nItems, bool wait);
+    size_t overrun(size_t itemSize, size_t nItems, bool wait);
     bool decompress(bool wait);
 
     InStream* underlying;
-    int bufSize;
-    int offset;
+    size_t bufSize;
+    size_t offset;
     z_stream_s* zs;
-    int bytesIn;
+    size_t bytesIn;
     U8* start;
   };
 
 } // end of namespace rdr
 
diff --git a/common/rdr/ZlibOutStream.cxx b/common/rdr/ZlibOutStream.cxx
index dd3c2367b..26a113159 100644
--- a/common/rdr/ZlibOutStream.cxx
+++ b/common/rdr/ZlibOutStream.cxx
@@ -31,11 +31,11 @@ static rfb::LogWriter vlog("ZlibOutStream");
 
 using namespace rdr;
 
 enum { DEFAULT_BUF_SIZE = 16384 };
 
-ZlibOutStream::ZlibOutStream(OutStream* os, int bufSize_, int compressLevel)
+ZlibOutStream::ZlibOutStream(OutStream* os, size_t bufSize_, int compressLevel)
   : underlying(os), compressionLevel(compressLevel), newLevel(compressLevel),
     bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_SIZE), offset(0)
 {
   zs = new z_stream;
   zs->zalloc    = Z_NULL;
@@ -73,11 +73,11 @@ void ZlibOutStream::setCompressionLevel(int level)
     level = -1;                 // Z_DEFAULT_COMPRESSION
 
   newLevel = level;
 }
 
-int ZlibOutStream::length()
+size_t ZlibOutStream::length()
 {
   return offset + ptr - start;
 }
 
 void ZlibOutStream::flush()
@@ -96,22 +96,22 @@ void ZlibOutStream::flush()
 
   offset += ptr - start;
   ptr = start;
 }
 
-int ZlibOutStream::overrun(int itemSize, int nItems)
+size_t ZlibOutStream::overrun(size_t itemSize, size_t nItems)
 {
 #ifdef ZLIBOUT_DEBUG
   vlog.debug("overrun");
 #endif
 
   if (itemSize > bufSize)
     throw Exception("ZlibOutStream overrun: max itemSize exceeded");
 
   checkCompressionLevel();
 
-  while (end - ptr < itemSize) {
+  while ((size_t)(end - ptr) < itemSize) {
     zs->next_in = start;
     zs->avail_in = ptr - start;
 
     deflate(Z_NO_FLUSH);
 
@@ -128,11 +128,11 @@ int ZlibOutStream::overrun(int itemSize, int nItems)
       offset += zs->next_in - start;
       ptr -= zs->next_in - start;
     }
   }
 
-  if (itemSize * nItems > end - ptr)
+  if (itemSize * nItems > (size_t)(end - ptr))
     nItems = (end - ptr) / itemSize;
 
   return nItems;
 }
 
diff --git a/common/rdr/ZlibOutStream.h b/common/rdr/ZlibOutStream.h
index 2d82a13bc..11bb04681 100644
--- a/common/rdr/ZlibOutStream.h
+++ b/common/rdr/ZlibOutStream.h
@@ -33,29 +33,29 @@ namespace rdr {
 
   class ZlibOutStream : public OutStream {
 
   public:
 
-    ZlibOutStream(OutStream* os=0, int bufSize=0, int compressionLevel=-1);
+    ZlibOutStream(OutStream* os=0, size_t bufSize=0, int compressionLevel=-1);
     virtual ~ZlibOutStream();
 
     void setUnderlying(OutStream* os);
     void setCompressionLevel(int level=-1);
     void flush();
-    int length();
+    size_t length();
 
   private:
 
-    int overrun(int itemSize, int nItems);
+    size_t overrun(size_t itemSize, size_t nItems);
     void deflate(int flush);
     void checkCompressionLevel();
 
     OutStream* underlying;
     int compressionLevel;
     int newLevel;
-    int bufSize;
-    int offset;
+    size_t bufSize;
+    size_t offset;
     z_stream_s* zs;
     U8* start;
   };
 
 } // end of namespace rdr
diff --git a/common/rfb/Configuration.cxx b/common/rfb/Configuration.cxx
index ea0006001..ceaefccb2 100644
--- a/common/rfb/Configuration.cxx
+++ b/common/rfb/Configuration.cxx
@@ -419,11 +419,11 @@ StringParameter::operator const char *() const {
 }
 
 // -=- BinaryParameter
 
 BinaryParameter::BinaryParameter(const char* name_, const char* desc_,
-				 const void* v, int l, ConfigurationObject co)
+				 const void* v, size_t l, ConfigurationObject co)
 : VoidParameter(name_, desc_, co), value(0), length(0), def_value((char*)v), def_length(l) {
   if (l) {
     value = new char[l];
     length = l;
     memcpy(value, v, l);
@@ -439,11 +439,11 @@ bool BinaryParameter::setParam(const char* v) {
   if (immutable) return true;
   vlog.debug("set %s(Binary) to %s", getName(), v);
   return rdr::HexInStream::hexStrToBin(v, &value, &length);
 }
 
-void BinaryParameter::setParam(const void* v, int len) {
+void BinaryParameter::setParam(const void* v, size_t len) {
   LOCK_CONFIG;
   if (immutable) return; 
   vlog.debug("set %s(Binary)", getName());
   delete [] value; value = 0;
   if (len) {
@@ -460,11 +460,11 @@ char* BinaryParameter::getDefaultStr() const {
 char* BinaryParameter::getValueStr() const {
   LOCK_CONFIG;
   return rdr::HexOutStream::binToHexStr(value, length);
 }
 
-void BinaryParameter::getData(void** data_, int* length_) const {
+void BinaryParameter::getData(void** data_, size_t* length_) const {
   LOCK_CONFIG;
   if (length_) *length_ = length;
   if (data_) {
     *data_ = new char[length];
     memcpy(*data_, value, length);
diff --git a/common/rfb/Configuration.h b/common/rfb/Configuration.h
index 6197317b5..e23e8a512 100644
--- a/common/rfb/Configuration.h
+++ b/common/rfb/Configuration.h
@@ -254,28 +254,29 @@ namespace rfb {
     const char* def_value;
   };
 
   class BinaryParameter : public VoidParameter {
   public:
-    BinaryParameter(const char* name_, const char* desc_, const void* v, int l,
-		    ConfigurationObject co=ConfGlobal);
+    BinaryParameter(const char* name_, const char* desc_,
+                    const void* v, size_t l,
+                    ConfigurationObject co=ConfGlobal);
     using VoidParameter::setParam;
     virtual ~BinaryParameter();
     virtual bool setParam(const char* value);
-    virtual void setParam(const void* v, int l);
+    virtual void setParam(const void* v, size_t l);
     virtual char* getDefaultStr() const;
     virtual char* getValueStr() const;
 
     // getData() will return length zero if there is no data
     // NB: data may be set to zero, OR set to a zero-length buffer
-    void getData(void** data, int* length) const;
+    void getData(void** data, size_t* length) const;
 
   protected:
     char* value;
-    int length;
+    size_t length;
     char* def_value;
-    int def_length;
+    size_t def_length;
   };
 
   // -=- ParameterIterator
   //     Iterates over all enabled parameters (global + server/viewer).
   //     Current Parameter is accessed via param, the current Configuration
diff --git a/common/rfb/Password.cxx b/common/rfb/Password.cxx
index 240c9d4ff..e4a508c8b 100644
--- a/common/rfb/Password.cxx
+++ b/common/rfb/Password.cxx
@@ -36,11 +36,11 @@ static unsigned char d3desObfuscationKey[] = {23,82,107,6,35,78,88,7};
 PlainPasswd::PlainPasswd() {}
 
 PlainPasswd::PlainPasswd(char* pwd) : CharArray(pwd) {
 }
 
-PlainPasswd::PlainPasswd(int len) : CharArray(len) {
+PlainPasswd::PlainPasswd(size_t len) : CharArray(len) {
 }
 
 PlainPasswd::PlainPasswd(const ObfuscatedPasswd& obfPwd) : CharArray(9) {
   if (obfPwd.length < 8)
     throw rdr::Exception("bad obfuscated password length");
@@ -61,15 +61,15 @@ void PlainPasswd::replaceBuf(char* b) {
 
 
 ObfuscatedPasswd::ObfuscatedPasswd() : length(0) {
 }
 
-ObfuscatedPasswd::ObfuscatedPasswd(int len) : CharArray(len), length(len) {
+ObfuscatedPasswd::ObfuscatedPasswd(size_t len) : CharArray(len), length(len) {
 }
 
 ObfuscatedPasswd::ObfuscatedPasswd(const PlainPasswd& plainPwd) : CharArray(8), length(8) {
-  int l = strlen(plainPwd.buf), i;
+  size_t l = strlen(plainPwd.buf), i;
   for (i=0; i<8; i++)
     buf[i] = i<l ? plainPwd.buf[i] : 0;
   deskey(d3desObfuscationKey, EN0);
   des((rdr::U8*)buf, (rdr::U8*)buf);
 }
diff --git a/common/rfb/Password.h b/common/rfb/Password.h
index e5196ee04..712bc8139 100644
--- a/common/rfb/Password.h
+++ b/common/rfb/Password.h
@@ -26,22 +26,22 @@ namespace rfb {
 
   class PlainPasswd : public CharArray {
   public:
     PlainPasswd();
     PlainPasswd(char* pwd);
-    PlainPasswd(int len);
+    PlainPasswd(size_t len);
     PlainPasswd(const ObfuscatedPasswd& obfPwd);
     ~PlainPasswd();
     void replaceBuf(char* b);
   };
 
   class ObfuscatedPasswd : public CharArray {
   public:
     ObfuscatedPasswd();
-    ObfuscatedPasswd(int l);
+    ObfuscatedPasswd(size_t l);
     ObfuscatedPasswd(const PlainPasswd& plainPwd);
     ~ObfuscatedPasswd();
-    int length;
+    size_t length;
   };
 
 }
 #endif
diff --git a/common/rfb/util.h b/common/rfb/util.h
index 8503519d4..3100f90fd 100644
--- a/common/rfb/util.h
+++ b/common/rfb/util.h
@@ -48,11 +48,11 @@ namespace rfb {
   // -=- Class to handle cleanup of arrays of characters
   class CharArray {
   public:
     CharArray() : buf(0) {}
     CharArray(char* str) : buf(str) {} // note: assumes ownership
-    CharArray(int len) {
+    CharArray(size_t len) {
       buf = new char[len]();
     }
     ~CharArray() {
       delete [] buf;
     }
diff --git a/tests/perf/encperf.cxx b/tests/perf/encperf.cxx
index e461197ef..171564d1a 100644
--- a/tests/perf/encperf.cxx
+++ b/tests/perf/encperf.cxx
@@ -69,15 +69,15 @@ static const rdr::S32 encodings[] = {
 
 class DummyOutStream : public rdr::OutStream {
 public:
   DummyOutStream();
 
-  virtual int length();
+  virtual size_t length();
   virtual void flush();
 
 private:
-  virtual int overrun(int itemSize, int nItems);
+  virtual size_t overrun(size_t itemSize, size_t nItems);
 
   int offset;
   rdr::U8 buf[131072];
 };
 
@@ -139,11 +139,11 @@ DummyOutStream::DummyOutStream()
   offset = 0;
   ptr = buf;
   end = buf + sizeof(buf);
 }
 
-int DummyOutStream::length()
+size_t DummyOutStream::length()
 {
   flush();
   return offset;
 }
 
@@ -151,14 +151,14 @@ void DummyOutStream::flush()
 {
   offset += ptr - buf;
   ptr = buf;
 }
 
-int DummyOutStream::overrun(int itemSize, int nItems)
+size_t DummyOutStream::overrun(size_t itemSize, size_t nItems)
 {
   flush();
-  if (itemSize * nItems > end - ptr)
+  if (itemSize * nItems > (size_t)(end - ptr))
     nItems = (end - ptr) / itemSize;
   return nItems;
 }
 
 CConn::CConn(const char *filename)
diff --git a/win/rfb_win32/Registry.cxx b/win/rfb_win32/Registry.cxx
index 9cd501842..5d78c4c4c 100644
--- a/win/rfb_win32/Registry.cxx
+++ b/win/rfb_win32/Registry.cxx
@@ -144,11 +144,11 @@ void RegKey::setExpandString(const TCHAR* valname, const TCHAR* value) const {
 void RegKey::setString(const TCHAR* valname, const TCHAR* value) const {
   LONG result = RegSetValueEx(key, valname, 0, REG_SZ, (const BYTE*)value, (_tcslen(value)+1)*sizeof(TCHAR));
   if (result != ERROR_SUCCESS) throw rdr::SystemException("setString", result);
 }
 
-void RegKey::setBinary(const TCHAR* valname, const void* value, int length) const {
+void RegKey::setBinary(const TCHAR* valname, const void* value, size_t length) const {
   LONG result = RegSetValueEx(key, valname, 0, REG_BINARY, (const BYTE*)value, length);
   if (result != ERROR_SUCCESS) throw rdr::SystemException("setBinary", result);
 }
 
 void RegKey::setInt(const TCHAR* valname, int value) const {
@@ -167,16 +167,16 @@ TCHAR* RegKey::getString(const TCHAR* valname, const TCHAR* def) const {
   } catch(rdr::Exception&) {
     return tstrDup(def);
   }
 }
 
-void RegKey::getBinary(const TCHAR* valname, void** data, int* length) const {
+void RegKey::getBinary(const TCHAR* valname, void** data, size_t* length) const {
   TCharArray hex(getRepresentation(valname));
   if (!rdr::HexInStream::hexStrToBin(CStr(hex.buf), (char**)data, length))
     throw rdr::Exception("getBinary failed");
 }
-void RegKey::getBinary(const TCHAR* valname, void** data, int* length, void* def, int deflen) const {
+void RegKey::getBinary(const TCHAR* valname, void** data, size_t* length, void* def, size_t deflen) const {
   try {
     getBinary(valname, data, length);
   } catch(rdr::Exception&) {
     if (deflen) {
       *data = new char[deflen];
diff --git a/win/rfb_win32/Registry.h b/win/rfb_win32/Registry.h
index 68d535cdb..2bb16911d 100644
--- a/win/rfb_win32/Registry.h
+++ b/win/rfb_win32/Registry.h
@@ -69,19 +69,19 @@ namespace rfb {
       // event when there is a change, if specified
       void awaitChange(bool watchSubTree, DWORD filter, HANDLE event=0) const;
 
       void setExpandString(const TCHAR* valname, const TCHAR* s) const;
       void setString(const TCHAR* valname, const TCHAR* s) const;
-      void setBinary(const TCHAR* valname, const void* data, int length) const;
+      void setBinary(const TCHAR* valname, const void* data, size_t length) const;
       void setInt(const TCHAR* valname, int i) const;
       void setBool(const TCHAR* valname, bool b) const;
 
       TCHAR* getString(const TCHAR* valname) const;
       TCHAR* getString(const TCHAR* valname, const TCHAR* def) const;
 
-      void getBinary(const TCHAR* valname, void** data, int* length) const;
-      void getBinary(const TCHAR* valname, void** data, int* length, void* def, int deflength) const;
+      void getBinary(const TCHAR* valname, void** data, size_t* length) const;
+      void getBinary(const TCHAR* valname, void** data, size_t* length, void* def, size_t deflength) const;
 
       int getInt(const TCHAR* valname) const;
       int getInt(const TCHAR* valname, int def) const;
 
       bool getBool(const TCHAR* valname) const;

Vulnerable code: FdInStream::FdInStream(int fd_, int timeoutms_, int bufSize_,
                       int bufSize_)
int FdInStream::pos()
void FdInStream::readBytes(void* data, int length)
  int n = end - ptr;
int FdInStream::overrun(int itemSize, int nItems, bool wait)
  int bytes_to_read;
    int n = readWithTimeoutOrCallback((U8*)end, bytes_to_read, wait);
  if (itemSize * nItems > end - ptr)
int FdInStream::readWithTimeoutOrCallback(void* buf, int len, bool wait)
    FdInStream(int fd, int timeoutms=-1, int bufSize=0,
    FdInStream(int fd, FdInStreamBlockCallback* blockCallback, int bufSize=0);
    int pos();
    void readBytes(void* data, int length);
    int overrun(int itemSize, int nItems, bool wait);
    int readWithTimeoutOrCallback(void* buf, int len, bool wait=true);
    int bufSize;
    int offset;
FdOutStream::FdOutStream(int fd_, bool blocking_, int timeoutms_, int bufSize_)
int FdOutStream::length()
    int n = writeWithTimeout((const void*) sentUpTo,
                             ptr - sentUpTo,
                             blocking? timeoutms : 0);
int FdOutStream::overrun(int itemSize, int nItems)
  if (itemSize > end - ptr) {
    if ((sentUpTo - start > bufSize / 4) &&
  if (itemSize * nItems > end - ptr)
int FdOutStream::writeWithTimeout(const void* data, int length, int timeoutms)
    FdOutStream(int fd, bool blocking=true, int timeoutms=-1, int bufSize=0);
    int length();
    int overrun(int itemSize, int nItems);
    int writeWithTimeout(const void* data, int length, int timeoutms);
    int bufSize;
    int offset;
int FileInStream::pos()
int FileInStream::overrun(int itemSize, int nItems, bool wait)
  if (itemSize > (int)sizeof(b))
  if (itemSize * nItems > end - ptr)
    int pos();
    int overrun(int itemSize, int nItems, bool wait = true);
HexInStream::HexInStream(InStream& is, int bufSize_)
bool HexInStream::hexStrToBin(const char* s, char** data, int* length) {
  int l=strlen(s);
    for(int i=0;i<l;i+=2) {
int HexInStream::pos() {
int HexInStream::overrun(int itemSize, int nItems, bool wait) {
    int n = in_stream.check(2, 1, wait);
    int length = min((eptr - iptr)/2, start + bufSize - end);
    for (int i=0; i<length; i++) {
  if (itemSize * nItems > end - ptr)
    HexInStream(InStream& is, int bufSize=0);
    int pos();
    static bool hexStrToBin(const char* s, char** data, int* length);
    int overrun(int itemSize, int nItems, bool wait);
    int bufSize;
    int offset;
static inline int min(int a, int b) {return a<b ? a : b;}
HexOutStream::HexOutStream(OutStream& os, int buflen)
char* HexOutStream::binToHexStr(const char* data, int length) {
  for (int i=0; i<length; i++) {
    int length = min(ptr-pos, (oend-optr)/2);
    for (int i=0; i<length; i++) {
int HexOutStream::length()
int
HexOutStream::overrun(int itemSize, int nItems) {
  if (itemSize * nItems > end - ptr)
    HexOutStream(OutStream& os, int buflen=0);
    int length();
    static char* binToHexStr(const char* data, int length);
    int overrun(int itemSize, int nItems);
    int offset;
    int bufSize;
    inline int check(int itemSize, int nItems=1, bool wait=true)
    inline bool checkNoWait(int length) { return check(length, 1, false)!=0; }
    inline void skip(int bytes) {
        int n = check(1, bytes);
    void readBytes(void* data, int length) {
        int n = check(1, dataEnd - dataPtr);
    virtual int pos() = 0;
    virtual int overrun(int itemSize, int nItems, bool wait=true) = 0;
    MemInStream(const void* data, int len, bool deleteWhenDone_=false)
    int pos() { return ptr - start; }
    void reposition(int pos) { ptr = start + pos; }
    int overrun(int itemSize, int nItems, bool wait) { throw EndOfStream(); }
    void writeBytes(const void* data, int length) {
    int length() { return ptr - start; }
    void reposition(int pos) { ptr = start + pos; }
    int overrun(int itemSize, int nItems) {
      int len = ptr - start + itemSize * nItems;
      if (len < (end - start) * 2)
    inline int check(int itemSize, int nItems=1)
    inline void pad(int bytes) {
    inline void skip(int bytes) {
        int n = check(1, bytes);
    void writeBytes(const void* data, int length) {
        int n = check(1, dataEnd - dataPtr);
    void copyBytes(InStream* is, int length) {
        int n = check(1, length);
    virtual int length() = 0;
    virtual int overrun(int itemSize, int nItems) = 0;
const int DEFAULT_BUF_LEN = 256;
int RandomStream::pos() {
int RandomStream::overrun(int itemSize, int nItems, bool wait) {
  int length = start + DEFAULT_BUF_LEN - end;
    int n = fread((U8*)end, length, 1, fp);
    for (int i=0; i<length; i++)
  if (itemSize * nItems > end - ptr)
    int pos();
    int overrun(int itemSize, int nItems, bool wait);
    int offset;
int TLSInStream::pos()
int TLSInStream::overrun(int itemSize, int nItems, bool wait)
    int n = readTLS((U8*) end, start + bufSize - end, wait);
  if (itemSize * nItems > end - ptr)
int TLSInStream::readTLS(U8* buf, int len, bool wait)
    int pos();
    int overrun(int itemSize, int nItems, bool wait);
    int readTLS(U8* buf, int len, bool wait);
    int bufSize;
    int offset;
int TLSOutStream::length()
    int n = writeTLS(sentUpTo, ptr - sentUpTo);
int TLSOutStream::overrun(int itemSize, int nItems)
  if (itemSize * nItems > end - ptr)
int TLSOutStream::writeTLS(const U8* data, int length)
    int length();
    int overrun(int itemSize, int nItems);
    int writeTLS(const U8* data, int length);
    int bufSize;
    int offset;
ZlibInStream::ZlibInStream(int bufSize_)
void ZlibInStream::setUnderlying(InStream* is, int bytesIn_)
int ZlibInStream::pos()
int ZlibInStream::overrun(int itemSize, int nItems, bool wait)
  while (end - ptr < itemSize) {
  if (itemSize * nItems > end - ptr)
  int n = underlying->check(1, 1, wait);
  if ((int)zs->avail_in > bytesIn)
    ZlibInStream(int bufSize=0);
    void setUnderlying(InStream* is, int bytesIn);
    int pos();
    int overrun(int itemSize, int nItems, bool wait);
    int bufSize;
    int offset;
    int bytesIn;
ZlibOutStream::ZlibOutStream(OutStream* os, int bufSize_, int compressLevel)
int ZlibOutStream::length()
int ZlibOutStream::overrun(int itemSize, int nItems)
  while (end - ptr < itemSize) {
  if (itemSize * nItems > end - ptr)
    ZlibOutStream(OutStream* os=0, int bufSize=0, int compressionLevel=-1);
    int length();
    int overrun(int itemSize, int nItems);
    int bufSize;
    int offset;
				 const void* v, int l, ConfigurationObject co)
void BinaryParameter::setParam(const void* v, int len) {
void BinaryParameter::getData(void** data_, int* length_) const {
    BinaryParameter(const char* name_, const char* desc_, const void* v, int l,
		    ConfigurationObject co=ConfGlobal);
    virtual void setParam(const void* v, int l);
    void getData(void** data, int* length) const;
    int length;
    int def_length;
PlainPasswd::PlainPasswd(int len) : CharArray(len) {
ObfuscatedPasswd::ObfuscatedPasswd(int len) : CharArray(len), length(len) {
  int l = strlen(plainPwd.buf), i;
    PlainPasswd(int len);
    ObfuscatedPasswd(int l);
    int length;
    CharArray(int len) {
  virtual int length();
  virtual int overrun(int itemSize, int nItems);
int DummyOutStream::length()
int DummyOutStream::overrun(int itemSize, int nItems)
  if (itemSize * nItems > end - ptr)
void RegKey::setBinary(const TCHAR* valname, const void* value, int length) const {
void RegKey::getBinary(const TCHAR* valname, void** data, int* length) const {
void RegKey::getBinary(const TCHAR* valname, void** data, int* length, void* def, int deflen) const {
      void setBinary(const TCHAR* valname, const void* data, int length) const;
      void getBinary(const TCHAR* valname, void** data, int* length) const;
      void getBinary(const TCHAR* valname, void** data, int* length, void* def, int deflength) const;
Fixed code: FdInStream::FdInStream(int fd_, int timeoutms_, size_t bufSize_,
                       size_t bufSize_)
size_t FdInStream::pos()
void FdInStream::readBytes(void* data, size_t length)
  size_t n = end - ptr;
size_t FdInStream::overrun(size_t itemSize, size_t nItems, bool wait)
  size_t bytes_to_read;
    size_t n = readWithTimeoutOrCallback((U8*)end, bytes_to_read, wait);
  if (itemSize * nItems > (size_t)(end - ptr))
size_t FdInStream::readWithTimeoutOrCallback(void* buf, size_t len, bool wait)
    FdInStream(int fd, int timeoutms=-1, size_t bufSize=0,
    FdInStream(int fd, FdInStreamBlockCallback* blockCallback,
               size_t bufSize=0);
    size_t pos();
    void readBytes(void* data, size_t length);
    size_t overrun(size_t itemSize, size_t nItems, bool wait);
    size_t readWithTimeoutOrCallback(void* buf, size_t len, bool wait=true);
    size_t bufSize;
    size_t offset;
FdOutStream::FdOutStream(int fd_, bool blocking_, int timeoutms_, size_t bufSize_)
size_t FdOutStream::length()
    size_t n = writeWithTimeout((const void*) sentUpTo,
                                ptr - sentUpTo,
                                blocking? timeoutms : 0);
size_t FdOutStream::overrun(size_t itemSize, size_t nItems)
  if (itemSize > (size_t)(end - ptr)) {
    if (((size_t)(sentUpTo - start) > bufSize / 4) &&
  if (itemSize * nItems > (size_t)(end - ptr))
size_t FdOutStream::writeWithTimeout(const void* data, size_t length, int timeoutms)
    FdOutStream(int fd, bool blocking=true, int timeoutms=-1, size_t bufSize=0);
    size_t length();
    size_t overrun(size_t itemSize, size_t nItems);
    size_t writeWithTimeout(const void* data, size_t length, int timeoutms);
    size_t bufSize;
    size_t offset;
size_t FileInStream::pos()
size_t FileInStream::overrun(size_t itemSize, size_t nItems, bool wait)
  if (itemSize > sizeof(b))
  if (itemSize * nItems > (size_t)(end - ptr))
    size_t pos();
    size_t overrun(size_t itemSize, size_t nItems, bool wait = true);
HexInStream::HexInStream(InStream& is, size_t bufSize_)
bool HexInStream::hexStrToBin(const char* s, char** data, size_t* length) {
  size_t l=strlen(s);
    for(size_t i=0;i<l;i+=2) {
size_t HexInStream::pos() {
size_t HexInStream::overrun(size_t itemSize, size_t nItems, bool wait) {
    size_t n = in_stream.check(2, 1, wait);
    size_t length = min((eptr - iptr)/2, start + bufSize - end);
    for (size_t i=0; i<length; i++) {
  if (itemSize * nItems > (size_t)(end - ptr))
    HexInStream(InStream& is, size_t bufSize=0);
    size_t pos();
    static bool hexStrToBin(const char* s, char** data, size_t* length);
    size_t overrun(size_t itemSize, size_t nItems, bool wait);
    size_t bufSize;
    size_t offset;
static inline size_t min(size_t a, size_t b) {return a<b ? a : b;}
HexOutStream::HexOutStream(OutStream& os, size_t buflen)
char* HexOutStream::binToHexStr(const char* data, size_t length) {
  for (size_t i=0; i<length; i++) {
    size_t length = min(ptr-pos, (oend-optr)/2);
    for (size_t i=0; i<length; i++) {
size_t HexOutStream::length()
size_t
HexOutStream::overrun(size_t itemSize, size_t nItems) {
  if (itemSize * nItems > (size_t)(end - ptr))
    HexOutStream(OutStream& os, size_t buflen=0);
    size_t length();
    static char* binToHexStr(const char* data, size_t length);
    size_t overrun(size_t itemSize, size_t nItems);
    size_t offset;
    size_t bufSize;
    inline size_t check(size_t itemSize, size_t nItems=1, bool wait=true)
    inline bool checkNoWait(size_t length) { return check(length, 1, false)!=0; }
    inline void skip(size_t bytes) {
        size_t n = check(1, bytes);
    void readBytes(void* data, size_t length) {
        size_t n = check(1, dataEnd - dataPtr);
    virtual size_t pos() = 0;
    virtual size_t overrun(size_t itemSize, size_t nItems, bool wait=true) = 0;
    MemInStream(const void* data, size_t len, bool deleteWhenDone_=false)
    size_t pos() { return ptr - start; }
    void reposition(size_t pos) { ptr = start + pos; }
    size_t overrun(size_t itemSize, size_t nItems, bool wait) { throw EndOfStream(); }
    void writeBytes(const void* data, size_t length) {
    size_t length() { return ptr - start; }
    void reposition(size_t pos) { ptr = start + pos; }
    size_t overrun(size_t itemSize, size_t nItems) {
      size_t len = ptr - start + itemSize * nItems;
      if (len < (size_t)(end - start) * 2)
    inline size_t check(size_t itemSize, size_t nItems=1)
    inline void pad(size_t bytes) {
    inline void skip(size_t bytes) {
        size_t n = check(1, bytes);
    void writeBytes(const void* data, size_t length) {
        size_t n = check(1, dataEnd - dataPtr);
    void copyBytes(InStream* is, size_t length) {
        size_t n = check(1, length);
    virtual size_t length() = 0;
    virtual size_t overrun(size_t itemSize, size_t nItems) = 0;
const size_t DEFAULT_BUF_LEN = 256;
size_t RandomStream::pos() {
size_t RandomStream::overrun(size_t itemSize, size_t nItems, bool wait) {
  size_t length = start + DEFAULT_BUF_LEN - end;
    size_t n = fread((U8*)end, length, 1, fp);
    for (size_t i=0; i<length; i++)
  if (itemSize * nItems > (size_t)(end - ptr))
    size_t pos();
    size_t overrun(size_t itemSize, size_t nItems, bool wait);
    size_t offset;
size_t TLSInStream::pos()
size_t TLSInStream::overrun(size_t itemSize, size_t nItems, bool wait)
    size_t n = readTLS((U8*) end, start + bufSize - end, wait);
  if (itemSize * nItems > (size_t)(end - ptr))
size_t TLSInStream::readTLS(U8* buf, size_t len, bool wait)
    size_t pos();
    size_t overrun(size_t itemSize, size_t nItems, bool wait);
    size_t readTLS(U8* buf, size_t len, bool wait);
    size_t bufSize;
    size_t offset;
size_t TLSOutStream::length()
    size_t n = writeTLS(sentUpTo, ptr - sentUpTo);
size_t TLSOutStream::overrun(size_t itemSize, size_t nItems)
  if (itemSize * nItems > (size_t)(end - ptr))
size_t TLSOutStream::writeTLS(const U8* data, size_t length)
    size_t length();
    size_t overrun(size_t itemSize, size_t nItems);
    size_t writeTLS(const U8* data, size_t length);
    size_t bufSize;
    size_t offset;
ZlibInStream::ZlibInStream(size_t bufSize_)
void ZlibInStream::setUnderlying(InStream* is, size_t bytesIn_)
size_t ZlibInStream::pos()
size_t ZlibInStream::overrun(size_t itemSize, size_t nItems, bool wait)
  while ((size_t)(end - ptr) < itemSize) {
  if (itemSize * nItems > (size_t)(end - ptr))
  size_t n = underlying->check(1, 1, wait);
  if (zs->avail_in > bytesIn)
    ZlibInStream(size_t bufSize=0);
    void setUnderlying(InStream* is, size_t bytesIn);
    size_t pos();
    size_t overrun(size_t itemSize, size_t nItems, bool wait);
    size_t bufSize;
    size_t offset;
    size_t bytesIn;
ZlibOutStream::ZlibOutStream(OutStream* os, size_t bufSize_, int compressLevel)
size_t ZlibOutStream::length()
size_t ZlibOutStream::overrun(size_t itemSize, size_t nItems)
  while ((size_t)(end - ptr) < itemSize) {
  if (itemSize * nItems > (size_t)(end - ptr))
    ZlibOutStream(OutStream* os=0, size_t bufSize=0, int compressionLevel=-1);
    size_t length();
    size_t overrun(size_t itemSize, size_t nItems);
    size_t bufSize;
    size_t offset;
				 const void* v, size_t l, ConfigurationObject co)
void BinaryParameter::setParam(const void* v, size_t len) {
void BinaryParameter::getData(void** data_, size_t* length_) const {
    BinaryParameter(const char* name_, const char* desc_,
                    const void* v, size_t l,
                    ConfigurationObject co=ConfGlobal);
    virtual void setParam(const void* v, size_t l);
    void getData(void** data, size_t* length) const;
    size_t length;
    size_t def_length;
PlainPasswd::PlainPasswd(size_t len) : CharArray(len) {
ObfuscatedPasswd::ObfuscatedPasswd(size_t len) : CharArray(len), length(len) {
  size_t l = strlen(plainPwd.buf), i;
    PlainPasswd(size_t len);
    ObfuscatedPasswd(size_t l);
    size_t length;
    CharArray(size_t len) {
  virtual size_t length();
  virtual size_t overrun(size_t itemSize, size_t nItems);
size_t DummyOutStream::length()
size_t DummyOutStream::overrun(size_t itemSize, size_t nItems)
  if (itemSize * nItems > (size_t)(end - ptr))
void RegKey::setBinary(const TCHAR* valname, const void* value, size_t length) const {
void RegKey::getBinary(const TCHAR* valname, void** data, size_t* length) const {
void RegKey::getBinary(const TCHAR* valname, void** data, size_t* length, void* def, size_t deflen) const {
      void setBinary(const TCHAR* valname, const void* data, size_t length) const;
      void getBinary(const TCHAR* valname, void** data, size_t* length) const;
      void getBinary(const TCHAR* valname, void** data, size_t* length, void* def, size_t deflength) const;