Create and use a snprintf wrapper in the core code

Use a wrapper around snprintf to consilidate all use, add
error checking, and remove gcc 9 warnings about not checking
the result.

Replace the prevous use of snprintf added to weapon.c with the
new scheme.

Update a second spot that has a gcc sprintf warning.  While
there, simplify the code.
This commit is contained in:
Dean Luick
2021-01-15 11:30:02 -06:00
parent 35f9115fae
commit 8143d55d76
4 changed files with 67 additions and 22 deletions

View File

@@ -953,6 +953,12 @@ E void FDECL(strbuf_nl_to_crlf, (strbuf_t *));
E char *FDECL(nonconst, (const char *, char *));
E int FDECL(swapbits, (int, int, int));
E void FDECL(shuffle_int_array, (int *, int));
/* note: the snprintf CPP wrapper includes the "fmt" argument in "..."
(__VA_ARGS__) to allow for zero arguments after fmt */
#define Snprintf(str, size, ...) \
nh_snprintf(__func__, __LINE__, str, size, __VA_ARGS__)
extern void nh_snprintf(const char *func, int line, char *str, size_t size,
const char *fmt, ...);
/* ### insight.c ### */

View File

@@ -74,6 +74,8 @@
char * nonconst (const char *, char *)
int swapbits (int, int, int)
void shuffle_int_array (int *, int)
void nh_snprintf (const char *, int, char *, size_t,
const char *, ...)
=*/
#ifdef LINT
#define Static /* pacify lint */
@@ -1319,4 +1321,39 @@ int count;
}
}
/*
* Wrap snprintf for use in the main code.
*
* Wrap reasons:
* 1. If there are any platform issues, we have one spot to fix them -
* snprintf is a routine with a troubling history of bad implementations.
* 2. Add combersome error checking in one spot. Problems with text wrangling
* do not have to be fatal.
* 3. Gcc 9+ will issue a warning unless the return value is used.
* Annoyingly, explicitly casting to void does not remove the error.
* So, use the result - see reason #2.
*/
void
nh_snprintf(const char *func, int line, char *str, size_t size,
const char *fmt, ...)
{
va_list ap;
int n;
va_start(ap, fmt);
#ifdef NO_VSNPRINTF
n = vsprintf(str, fmt, ap);
#else
n = vsnprintf(str, size, fmt, ap);
#endif
va_end(ap);
if (n < 0 || (size_t)n >= size) { /* is there a problem? */
impossible("snprintf %s: func %s, file line %d",
n < 0 ? "format error"
: "overflow",
func, line);
str[size-1] = 0; /* make sure it is nul terminated */
}
}
/*hacklib.c*/

View File

@@ -251,19 +251,23 @@ void
early_version_info(pastebuf)
boolean pastebuf;
{
char buf[BUFSZ], buf2[BUFSZ];
char *tmp = getversionstring(buf);
char buf1[BUFSZ], buf2[BUFSZ];
char *buf, *tmp;
/* this is early enough that we have to do
our own line-splitting */
Snprintf(buf1, sizeof(buf1), "test");
/* this is early enough that we have to do our own line-splitting */
getversionstring(buf1);
tmp = strstri(buf1, " ("); /* split at start of version info */
if (tmp) {
tmp = strstri(buf," (");
if (tmp) *tmp++ = '\0';
/* retain one buffer so that it all goes into the paste buffer */
*tmp++ = '\0';
Snprintf(buf2, sizeof(buf2), "%s\n%s", buf1, tmp);
buf = buf2;
} else {
buf = buf1;
}
Sprintf(buf2, "%s\n", buf);
if (tmp) Sprintf(eos(buf2), "%s\n", tmp);
raw_printf("%s", buf2);
raw_printf("%s", buf);
if (pastebuf) {
#if defined(RUNTIME_PASTEBUF_SUPPORT) && !defined(LIBNH)
@@ -272,7 +276,7 @@ boolean pastebuf;
* version information into a paste buffer. Useful for
* easy inclusion in bug reports.
*/
port_insert_pastebuf(buf2);
port_insert_pastebuf(buf);
#else
raw_printf("%s", "Paste buffer copy is not available.\n");
#endif

View File

@@ -1271,23 +1271,21 @@ enhance_weapon_skill()
(void) skill_level_name(i, sklnambuf);
if (wizard) {
if (!iflags.menu_tab_sep)
n = snprintf(buf, sizeof(buf), " %s%-*s %-12s %5d(%4d)", prefix,
longest, P_NAME(i), sklnambuf, P_ADVANCE(i),
practice_needed_to_advance(P_SKILL(i)));
Snprintf(buf, sizeof(buf), " %s%-*s %-12s %5d(%4d)", prefix,
longest, P_NAME(i), sklnambuf, P_ADVANCE(i),
practice_needed_to_advance(P_SKILL(i)));
else
n = snprintf(buf, sizeof(buf), " %s%s\t%s\t%5d(%4d)", prefix, P_NAME(i),
sklnambuf, P_ADVANCE(i),
practice_needed_to_advance(P_SKILL(i)));
Snprintf(buf, sizeof(buf), " %s%s\t%s\t%5d(%4d)", prefix, P_NAME(i),
sklnambuf, P_ADVANCE(i),
practice_needed_to_advance(P_SKILL(i)));
} else {
if (!iflags.menu_tab_sep)
n = snprintf(buf, sizeof(buf), " %s %-*s [%s]", prefix, longest,
P_NAME(i), sklnambuf);
Snprintf(buf, sizeof(buf), " %s %-*s [%s]", prefix, longest,
P_NAME(i), sklnambuf);
else
n = snprintf(buf, sizeof(buf), " %s%s\t[%s]", prefix, P_NAME(i),
sklnambuf);
Snprintf(buf, sizeof(buf), " %s%s\t[%s]", prefix, P_NAME(i),
sklnambuf);
}
if (n >= sizeof(buf)) /* check for overflow */
buf[sizeof(buf)-1] = 0; /* terminate string */
any.a_int = can_advance(i, speedy) ? i + 1 : 0;
add_menu(win, &nul_glyphinfo, &any, 0, 0,
ATR_NONE, buf, MENU_ITEMFLAGS_NONE);