append_str(pager.c) again

More for issue #524.

The revised append_str() was still vulnerable to unsigned subtraction
overflowing from small negative value to huge positive one, if caller
ever passed an outbuf buffer which already had more than BUFSZ
characters in it.

Also the semantics were changed.  If there wasn't room for the whole
" or "+string to be appended, it used to add as much as would fit.
The revised version changed that to all-or-nothing.  This changes it
back, although players will probably never know the difference.
This commit is contained in:
PatR
2021-05-31 15:28:19 -07:00
parent 6fb8434ec9
commit ffddb3ecf9

View File

@@ -52,27 +52,32 @@ is_swallow_sym(int c)
return FALSE; return FALSE;
} }
/* /* Append " or "+new_str to the end of buf if new_str doesn't already exist
* Append new_str to the end of buf if new_str doesn't already exist as as a substring of buf. Return 1 if the string was appended, 0 otherwise.
* a substring of buf. Return 1 if the string was appended, 0 otherwise. It is expected that buf is of size BUFSZ. */
* It is expected that buf is of size BUFSZ.
*/
static int static int
append_str(char *buf, const char *new_str) append_str(char *buf, const char *new_str)
{ {
size_t size2append, space_left; static const char sep[] = " or ";
const char sep[] = " or "; size_t oldlen, space_left;
if (strstri(buf, new_str)) if (strstri(buf, new_str))
return 0; return 0; /* already present */
space_left = BUFSZ - strlen(buf); /* space remaining in buf */ oldlen = strlen(buf);
size2append = strlen(new_str) + sizeof sep; /* latter includes '\0' */ if (oldlen >= BUFSZ - 1) {
if (space_left < size2append) if (oldlen > BUFSZ - 1)
return 0; impossible("append_str: 'buf' contains %lu characters.",
Strcat(buf, sep); (unsigned long) oldlen);
Strcat(buf, new_str); return 0; /* no space available */
return 1; }
/* some space available, but not necessarily enough for full append */
space_left = BUFSZ - 1 - oldlen; /* space remaining in buf */
(void) strncat(buf, sep, space_left);
if (space_left > sizeof sep - 1)
(void) strncat(buf, new_str, space_left - (sizeof sep - 1));
return 1; /* something was appended, possibly just part of " or " */
} }
/* shared by monster probing (via query_objlist!) as well as lookat() */ /* shared by monster probing (via query_objlist!) as well as lookat() */