top: Prevent out-of-bounds writes in PUFF().

This patch prevents three problems:

1/ Because snprintf() returns "the number of characters (excluding the
terminating null byte) which would have been written to the final string
if enough space had been available", _eol may point past the end of _str
and write out-of-bounds (in Batch mode).

2/ _eol is never checked against _str, so "while (*(--_eol) == ' ');"
may point _eol below _str and write out-of-bounds (in Batch mode).

3/ Sanity-check Pseudo_row to protect the strcpy().
This commit is contained in:
Qualys Security Advisory 1970-01-01 00:00:00 +00:00 committed by Craig Small
parent ed8f6d9cc6
commit 059ae8b512

View File

@ -547,10 +547,11 @@ typedef struct WIN_t {
. subject to optimization, thus MAY be discarded */
#define PUFF(fmt,arg...) do { \
char _str[ROWMAXSIZ], *_eol; \
_eol = _str + snprintf(_str, sizeof(_str), fmt, ## arg); \
const int _len = snprintf(_str, sizeof(_str), fmt, ## arg); \
_eol = _str + (_len < 0 ? 0 : (size_t)_len >= sizeof(_str) ? sizeof(_str)-1 : (size_t)_len); \
if (Batch) { \
while (*(--_eol) == ' '); *(++_eol) = '\0'; putp(_str); } \
else { \
while (_eol > _str && _eol[-1] == ' ') _eol--; *_eol = '\0'; putp(_str); } \
else if (Pseudo_row >= 0 && Pseudo_row < Screen_rows) { \
char *_ptr = &Pseudo_screen[Pseudo_row * ROWMAXSIZ]; \
if (Pseudo_row + 1 < Screen_rows) ++Pseudo_row; \
if (!strcmp(_ptr, _str)) putp("\n"); \