aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Mielke <mark.mielke@gmail.com>2020-06-20 06:15:39 -0400
committerMark Mielke <mark.mielke@gmail.com>2020-07-07 04:29:26 -0400
commit7932f5e483f790169a0d2da2a7cc73c76ca93817 (patch)
tree5029a853bb170935858f5a8592cae04712c16449
parent38726ce083db1a9227325bf87989513499bfa698 (diff)
downloadtigervnc-7932f5e483f790169a0d2da2a7cc73c76ca93817.tar.gz
tigervnc-7932f5e483f790169a0d2da2a7cc73c76ca93817.zip
Fix division by zero exception in SSecurityPlain.
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.
-rw-r--r--common/rdr/InStream.h13
1 files changed, 11 insertions, 2 deletions
diff --git a/common/rdr/InStream.h b/common/rdr/InStream.h
index f71a4d9e..a8e515da 100644
--- a/common/rdr/InStream.h
+++ b/common/rdr/InStream.h
@@ -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) {