]> source.dussan.org Git - tigervnc.git/commitdiff
Fix division by zero exception in SSecurityPlain. 1048/head
authorMark Mielke <mark.mielke@gmail.com>
Sat, 20 Jun 2020 10:15:39 +0000 (06:15 -0400)
committerMark Mielke <mark.mielke@gmail.com>
Tue, 7 Jul 2020 08:29:26 +0000 (04:29 -0400)
If using SSecurityPlain and the user specifies an empty username
and password, it will invoke InStream::checkNoWait(0) which will
cause a division by zero when calculating the number of available
items.

Enhance InStream::check() to behave properly when asked for
zero items, or zero sized items.

Add comments to InStream::check(), InStream::checkNoWait(),
and InStream::readBytes() to document expected behaviour
when requested to check or read zero items, or an item with
zero size.

common/rdr/InStream.h

index f71a4d9e35a189deafdf849714c653b4586eee00..a8e515daade33227ef67472ee2fcb9b371022fc5 100644 (file)
@@ -39,15 +39,19 @@ 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.
+    // available. If itemSize or nItems is zero, check() will return zero.
 
     inline size_t check(size_t itemSize, size_t nItems=1, bool wait=true)
     {
       size_t nAvail;
 
+      if (itemSize == 0 || nItems == 0)
+        return 0;
+
       if (itemSize > (size_t)(end - ptr))
         return overrun(itemSize, nItems, wait);
 
+      // itemSize cannot be zero at this point
       nAvail = (end - ptr) / itemSize;
       if (nAvail < nItems)
         return nAvail;
@@ -58,8 +62,12 @@ 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).
+    // If length is zero, checkNoWait() will return true.
 
-    inline bool checkNoWait(size_t length) { return check(length, 1, false)!=0; }
+    inline bool checkNoWait(size_t length)
+    {
+      return length == 0 || check(length, 1, false) > 0;
+    }
 
     // readU/SN() methods read unsigned and signed N-bit integers.
 
@@ -94,6 +102,7 @@ namespace rdr {
     }
 
     // readBytes() reads an exact number of bytes.
+    // If length is zero, readBytes() will return immediately.
 
     void readBytes(void* data, size_t length) {
       while (length > 0) {