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.
This commit is contained in:
Mark Mielke 2020-06-20 06:15:39 -04:00 committed by Lauri Kasanen
parent 27d6677a31
commit 80a637c793

View 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) {