On Tue, Jul 9, 2024 at 1:00 PM Alex Naumov <alexander_nau...@opensuse.org> wrote: Install the last available autoconf: https://packages.fedoraproject.org/pkgs/autoconf/autoconf/
GASP! install from source onto RHEL? where's the stability in that?? lol ok, I found the solution: sudo yum install autoconf-latest of course, then you have to hunt down where it installed to... /opt/rh/autoconf271/bin ok, so, I can now ./configure; make ... found some bugs in my code, it now builds clean, 1 existing warning.
diff --git a/src/ansi.c b/src/ansi.c index 9ee4ffa..fa8252d 100644 --- a/src/ansi.c +++ b/src/ansi.c @@ -155,9 +155,10 @@ void ResetAnsiState(Window *win) } /* adds max 22 bytes */ -int GetAnsiStatus(Window *win, char *buf) +int GetAnsiStatus(Window *win, char *buf, size_t maxlen) { char *p = buf; + int max; if (win->w_state == LIT) return 0; @@ -171,8 +172,9 @@ int GetAnsiStatus(Window *win, char *buf) p += AddXChar(p, win->w_intermediate & 0xff); *p = 0; } - if (win->w_state == ASTR || win->w_state == STRESC) - sprintf(p, "-%s", string_t_string[win->w_StringType]); + if (win->w_state == ASTR || win->w_state == STRESC) { + max = snprintf(p, maxlen, "-%s", string_t_string[win->w_StringType]); REPORT_SNPRINTF(max, maxlen); + } p += strlen(p); return p - buf; } @@ -1877,8 +1879,9 @@ static void Report(Window *win, char *fmt, int n1, int n2) { int len; char rbuf[40]; /* enough room for all replys */ + int max; - sprintf(rbuf, fmt, n1, n2); + max = snprintf(rbuf, sizeof(rbuf), fmt, n1, n2); REPORT_SNPRINTF(max, sizeof(rbuf)); len = strlen(rbuf); if (W_UWP(win)) { diff --git a/src/ansi.h b/src/ansi.h index 018959a..5a44844 100644 --- a/src/ansi.h +++ b/src/ansi.h @@ -156,7 +156,7 @@ void ResetCharsets (Window *); void WriteString (Window *, char *, size_t); void ChangeAKA (Window *, char *, size_t); void SetCharsets (Window *, char *); -int GetAnsiStatus (Window *, char *); +int GetAnsiStatus (Window *, char *, size_t maxlen); void WNewAutoFlow (Window *, int); void WBell (Window *, bool); void WMsg (Window *, int, char *); diff --git a/src/attacher.c b/src/attacher.c index d8de9d4..3bcfd26 100644 --- a/src/attacher.c +++ b/src/attacher.c @@ -433,6 +433,7 @@ void SendCmdMessage(char *sty, char *match, char **av, int query) Message m; char *p; int n; + int max, bmax; if (sty == NULL) { i = FindSocket(&s, NULL, NULL, match); @@ -445,7 +446,8 @@ void SendCmdMessage(char *sty, char *match, char **av, int query) sty[FILENAME_MAX] = 0; if (strlen(sty) > 2 * MAXSTR - 1) sty[2 * MAXSTR - 1] = 0; - sprintf(SocketPath + strlen(SocketPath), "/%s", sty); + bmax = sizeof(SocketPath) - strlen(SocketPath) - 1; // +1 for / + max = snprintf(SocketPath + strlen(SocketPath), bmax, "/%s", sty); REPORT_SNPRINTF(max, bmax); if ((s = MakeClientSocket(1)) == -1) exit(1); } diff --git a/src/display.c b/src/display.c index 8a940c1..bb14f04 100644 --- a/src/display.c +++ b/src/display.c @@ -579,6 +579,8 @@ void CursorVisibility(int v) void MouseMode(int mode) { + int max; + if (!display) return; @@ -590,11 +592,11 @@ void MouseMode(int mode) if (!D_CXT) return; if (D_mouse) { - sprintf(mousebuf, "\033[?%dl", D_mouse); + max = snprintf(mousebuf, sizeof(mousebuf), "\033[?%dl", D_mouse); REPORT_SNPRINTF(max, sizeof(mousebuf)); AddStr(mousebuf); } if (mode) { - sprintf(mousebuf, "\033[?%dh", mode); + max = snprintf(mousebuf, sizeof(mousebuf), "\033[?%dh", mode); REPORT_SNPRINTF(max, sizeof(mousebuf)); AddStr(mousebuf); } D_mouse = mode; @@ -604,16 +606,18 @@ void MouseMode(int mode) void ExtMouseMode(int mode) { + int max; + if (display && D_extmouse != mode) { char mousebuf[20]; if (!D_CXT) return; if (D_extmouse) { - sprintf(mousebuf, "\033[?%dl", D_extmouse); + max = snprintf(mousebuf, sizeof(mousebuf), "\033[?%dl", D_extmouse); REPORT_SNPRINTF(max, sizeof(mousebuf)); AddStr(mousebuf); } if (mode) { - sprintf(mousebuf, "\033[?%dh", mode); + max = snprintf(mousebuf, sizeof(mousebuf),"\033[?%dh", mode); REPORT_SNPRINTF(max, sizeof(mousebuf)); AddStr(mousebuf); } D_extmouse = mode; @@ -643,6 +647,7 @@ void BracketedPasteMode(bool mode) void CursorStyle(int mode) { char buf[32]; + int max; if (!display) return; @@ -652,7 +657,7 @@ void CursorStyle(int mode) return; if (mode < 0) return; - sprintf(buf, "\033[%d q", mode); + max = snprintf(buf, sizeof(buf), "\033[%d q", mode); REPORT_SNPRINTF(max, sizeof(buf)); AddStr(buf); D_cursorstyle = mode; } diff --git a/src/encoding.c b/src/encoding.c index b9f210b..2428586 100644 --- a/src/encoding.c +++ b/src/encoding.c @@ -1490,6 +1490,7 @@ int LoadFontTranslation(int font, char *file) int fo; int x, u, c, ok; unsigned short (*p)[2], (*tab)[2]; + int max; myfile = file; if (myfile == NULL) { @@ -1497,7 +1498,7 @@ int LoadFontTranslation(int font, char *file) return -1; if (strlen(screenencodings) > ARRAY_SIZE(buf) - 10) return -1; - sprintf(buf, "%s/%02x", screenencodings, font & 0xff); + max = snprintf(buf, sizeof(buf), "%s/%02x", screenencodings, font & 0xff); REPORT_SNPRINTF(max, sizeof(buf)); myfile = buf; } if ((f = secfopen(myfile, "r")) == NULL) diff --git a/src/fileio.c b/src/fileio.c index 75db976..06b48fe 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -84,6 +84,7 @@ static char *findrcfile(char *rcfile) { char buf[256]; char *p; + int max; /* Tilde prefix support courtesy <he...@pool.math.tu-berlin.de>, * taken from a Debian patch. */ @@ -95,7 +96,7 @@ static char *findrcfile(char *rcfile) Msg(0, "%s: source: tilde expansion failed", rc_name); return NULL; } - snprintf(rcfilename_tilde_exp, MAXPATHLEN, "%s/%s", home, rcfile + 2); + max = snprintf(rcfilename_tilde_exp, MAXPATHLEN, "%s/%s", home, rcfile + 2); REPORT_SNPRINTF(max, MAXPATHLEN); } else if (slash_position) { struct passwd *p; *slash_position = 0; @@ -104,7 +105,7 @@ static char *findrcfile(char *rcfile) Msg(0, "%s: source: tilde expansion failed for user %s", rc_name, rcfile + 1); return NULL; } - snprintf(rcfilename_tilde_exp, MAXPATHLEN, "%s/%s", p->pw_dir, slash_position + 1); + max = snprintf(rcfilename_tilde_exp, MAXPATHLEN, "%s/%s", p->pw_dir, slash_position + 1); REPORT_SNPRINTF(max, MAXPATHLEN); } else { Msg(0, "%s: source: illegal tilde expression.", rc_name); return NULL; @@ -127,7 +128,7 @@ static char *findrcfile(char *rcfile) } else { if (strlen(home) > ARRAY_SIZE(buf) - 12) Panic(0, "Rc: home too large"); - sprintf(buf, "%s/.screenrc", home); + max = snprintf(buf, sizeof(buf), "%s/.screenrc", home); REPORT_SNPRINTF(max, sizeof(buf)); return SaveStr(buf); } } @@ -342,6 +343,7 @@ void WriteFile(struct acluser *user, char *fn, int dump) int public = 0; struct stat stb, stb2; int fd, exists = 0; + int max; switch (dump) { case DUMP_TERMCAP: @@ -359,10 +361,11 @@ void WriteFile(struct acluser *user, char *fn, int dump) if (fn == NULL) { if (fore == NULL) return; - if (hardcopydir && *hardcopydir && strlen(hardcopydir) < ARRAY_SIZE(fnbuf) - 21) - sprintf(fnbuf, "%s/hardcopy.%d", hardcopydir, fore->w_number); - else - sprintf(fnbuf, "hardcopy.%d", fore->w_number); + if (hardcopydir && *hardcopydir && strlen(hardcopydir) < ARRAY_SIZE(fnbuf) - 21) { + max = snprintf(fnbuf, sizeof(fnbuf), "%s/hardcopy.%d", hardcopydir, fore->w_number); REPORT_SNPRINTF(max, sizeof(fnbuf)); + } else { + max = snprintf(fnbuf, sizeof(fnbuf), "hardcopy.%d", fore->w_number); REPORT_SNPRINTF(max, sizeof(fnbuf)); + } fn = fnbuf; } if (hardcopy_append && !access(fn, W_OK)) diff --git a/src/help.c b/src/help.c index 53b6fad..1965412 100644 --- a/src/help.c +++ b/src/help.c @@ -188,6 +188,7 @@ static int helppage(void) int col, crow, n, key, x; char buf[MAXKLEN], Esc_buf[5], cbuf[512]; struct action *ktabp; + int max; helpdata = (struct helpdata *)flayer->l_data; @@ -200,8 +201,7 @@ static int helppage(void) /* Clear the help screen */ LClearAll(flayer, 0); - sprintf(cbuf, "Screen key bindings, page %d of %d.", helpdata->grow / (flayer->l_height - 5) + 1, - helpdata->numpages); + max = snprintf(cbuf, sizeof(cbuf), "Screen key bindings, page %d of %d.", helpdata->grow / (flayer->l_height - 5) + 1, helpdata->numpages); REPORT_SNPRINTF(max, sizeof(cbuf)); centerline(cbuf, 0); crow = 2; @@ -218,10 +218,11 @@ static int helppage(void) for (; crow < flayer->l_height - 3; crow++) { if (helpdata->grow < 1) { - if (ktabp == ktab) - sprintf(cbuf, "Command key: %s Literal %s: %s", Esc_buf, Esc_buf, buf); - else - sprintf(cbuf, "Command class: '%.80s'", helpdata->class); + if (ktabp == ktab) { + max = snprintf(cbuf, sizeof(cbuf), "Command key: %s Literal %s: %s", Esc_buf, Esc_buf, buf); REPORT_SNPRINTF(max, sizeof(cbuf)); + } else { + max = snprintf(cbuf, sizeof(cbuf), "Command class: '%.80s'", helpdata->class); REPORT_SNPRINTF(max, sizeof(cbuf)); + } centerline(cbuf, crow); helpdata->grow++; } else if (helpdata->grow >= 2 && helpdata->grow - 2 < helpdata->numrows) { @@ -259,7 +260,7 @@ static int helppage(void) } else helpdata->grow++; } - sprintf(cbuf, "[Press Space %s Return to end.]", helpdata->grow < helpdata->maxrow ? "for next page;" : "or"); + max = snprintf(cbuf, sizeof(cbuf), "[Press Space %s Return to end.]", helpdata->grow < helpdata->maxrow ? "for next page;" : "or"); REPORT_SNPRINTF(max, sizeof(cbuf)); centerline(cbuf, flayer->l_height - 2); LaySetCursor(); return 0; @@ -432,12 +433,13 @@ static void bindkeypage(void) int del, i, y, sl; struct action *act; char *xch, *s, *p; + int max, bmax; bindkeydata = (struct bindkeydata *)flayer->l_data; LClearAll(flayer, 0); - sprintf(tbuf, "%s key bindings, page %d of %d.", bindkeydata->title, bindkeydata->page, bindkeydata->pages); + max = snprintf(tbuf, sizeof(tbuf), "%s key bindings, page %d of %d.", bindkeydata->title, bindkeydata->page, bindkeydata->pages); REPORT_SNPRINTF(max, sizeof(tbuf)); centerline(tbuf, 0); y = 2; for (i = bindkeydata->pos; i < KMAP_KEYS + KMAP_AKEYS + kmap_extn && y < flayer->l_height - 3; i++) { @@ -476,7 +478,8 @@ static void bindkeypage(void) *p++ = ' '; while (p < tbuf + 15) *p++ = ' '; - sprintf(p, "%s -> ", xch); + bmax = sizeof(tbuf) - (p-tbuf); + max = snprintf(p, bmax, "%s -> ", xch); REPORT_SNPRINTF(max, bmax); p += 7; if (p - tbuf > flayer->l_width - 1) { tbuf[flayer->l_width - 2] = '$'; @@ -488,8 +491,7 @@ static void bindkeypage(void) } y++; bindkeydata->last = i; - sprintf(tbuf, "[Press Space %s Return to end.]", - bindkeydata->page < bindkeydata->pages ? "for next page;" : "or"); + max = snprintf(tbuf, sizeof(tbuf), "[Press Space %s Return to end.]", bindkeydata->page < bindkeydata->pages ? "for next page;" : "or"); REPORT_SNPRINTF(max, sizeof(tbuf)); centerline(tbuf, flayer->l_height - 2); LaySetCursor(); } diff --git a/src/layout.c b/src/layout.c index d81c245..e0899c3 100644 --- a/src/layout.c +++ b/src/layout.c @@ -198,6 +198,7 @@ static char *AddLayoutsInfo(char *buf, int len, int where) char *s, *ss, *t; Layout *p, **pp; int l; + int max, bmax; s = ss = buf; for (pp = laytab; pp < laytab + MAXLAY; pp++) { @@ -215,14 +216,15 @@ static char *AddLayoutsInfo(char *buf, int len, int where) *s++ = ' '; *s++ = ' '; } - sprintf(s, "%d", p->lay_number); + bmax = len - (s-buf); + max = snprintf(s, bmax, "%d", p->lay_number); REPORT_SNPRINTF(max, bmax); if (p->lay_number == where) ss = s; s += strlen(s); if (display && p == D_layout) *s++ = '*'; *s++ = ' '; - strncpy(s, t, l); + strncpy(s, t, l); // TODO: check l is updated correctly s += l; } *s = 0; diff --git a/src/list_display.c b/src/list_display.c index 2098219..0e460f3 100644 --- a/src/list_display.c +++ b/src/list_display.c @@ -86,21 +86,24 @@ static int gl_Display_row(ListData *ldata, ListRow *lrow) { Display *d = lrow->data; char tbuf[80]; + int max; static char *blockstates[5] = { "nb", "NB", "Z<", "Z>", "BL" }; Window *w = d->d_fore; struct mchar m_current = mchar_blank; m_current.attr = A_BD; - sprintf(tbuf, " %-10.10s%4dx%-4d%10.10s@%-16.16s%s", + max = snprintf(tbuf, sizeof(tbuf), " %-10.10s%4dx%-4d%10.10s@%-16.16s%s", d->d_termname, d->d_width, d->d_height, d->d_user->u_name, d->d_usertty, - (d->d_blocked || d->d_nonblock >= 0) && d->d_blocked <= 4 ? blockstates[d->d_blocked] : " "); + (d->d_blocked || d->d_nonblock >= 0) && d->d_blocked <= 4 ? blockstates[d->d_blocked] : " "); REPORT_SNPRINTF(max, sizeof(tbuf)); if (w) { + int bmax; int l = 10 - strlen(w->w_title); if (l < 0) l = 0; - sprintf(tbuf + strlen(tbuf), "%3d(%.10s)%*s%c%c%c%c", w->w_number, w->w_title, l, "", + bmax = sizeof(tbuf) - strlen(tbuf); + max = snprintf(tbuf + strlen(tbuf), bmax, "%3d(%.10s)%*s%c%c%c%c", w->w_number, w->w_title, l, "", /* w->w_dlist->next */ 0 ? '&' : ' ', /* * The rwx triple: @@ -116,7 +119,7 @@ static int gl_Display_row(ListData *ldata, ListRow *lrow) ((w->w_wlock == WLOCK_OFF) ? 'w' : ((d->d_user == w->w_wlockuser) ? 'W' : 'v'))), (AclCheckPermWin(d->d_user, ACL_READ, w) ? '-' : 'x') - ); + ); REPORT_SNPRINTF(max, bmax); } leftline(tbuf, lrow->y, lrow == ldata->selected ? &mchar_so : d == display ? &m_current : NULL); diff --git a/src/process.c b/src/process.c index 129e2dc..f052f49 100644 --- a/src/process.c +++ b/src/process.c @@ -383,6 +383,7 @@ void InitKeytab(void) { unsigned int i; char *argarr[2]; + int max; for (i = 0; i < ARRAY_SIZE(ktab); i++) { ktab[i].nr = RC_ILLEGAL; @@ -493,7 +494,7 @@ void InitKeytab(void) char *args[2], arg1[10]; args[0] = arg1; args[1] = NULL; - sprintf(arg1, "%d", i); + max = snprintf(arg1, sizeof(arg1), "%d", i); REPORT_SNPRINTF(max, sizeof(arg1)); SaveAction(ktab + '0' + i, RC_SELECT, args, NULL); } ktab['\''].nr = RC_SELECT; /* calling a window by name */ @@ -3293,6 +3294,7 @@ static void DoCommandScrollback(struct action *act) static void DoCommandSessionname(struct action *act) { char **args = act->args; + int max, bmax; if (*args == NULL) OutputMsg(0, "This session is named '%s'\n", SocketName); @@ -3308,7 +3310,8 @@ static void DoCommandSessionname(struct action *act) return; } strncpy(buf, SocketPath, SocketName - SocketPath); - sprintf(buf + (SocketName - SocketPath), "%d.%s", (int)getpid(), s); + bmax = sizeof(buf) - (SocketName - SocketPath); + max = snprintf(buf + (SocketName - SocketPath), bmax, "%d.%s", (int)getpid(), s); REPORT_SNPRINTF(max, bmax); free(s); if ((access(buf, F_OK) == 0) || (errno != ENOENT)) { OutputMsg(0, "%s: inappropriate path: '%s'.", rc_name, buf); @@ -4414,13 +4417,16 @@ static void DoCommandFocusminsize(struct action *act) focusminheight = n; } if (msgok) { - char b[2][20]; +#define B_DIM_SIZE 20 + char b[2][B_DIM_SIZE]; + int max; for (int i = 0; i < 2; i++) { n = i == 0 ? focusminwidth : focusminheight; if (n == -1) strncpy(b[i], "max", 20); - else - sprintf(b[i], "%d", n); + else { + max = snprintf(b[i], B_DIM_SIZE, "%d", n); REPORT_SNPRINTF(max, B_DIM_SIZE); + } } OutputMsg(0, "focus min size is %s %s\n", b[0], b[1]); } @@ -5984,6 +5990,7 @@ char *AddWindows(WinMsgBufContext *wmbc, int len, int flags, int where) char *cmd; char *buf = wmbc->p; int l; + int max, bmax; Window *cur; s = ss = buf; @@ -6029,7 +6036,8 @@ char *AddWindows(WinMsgBufContext *wmbc, int len, int flags, int where) rend = renditions[REND_SILENCE]; if (rend != -1) AddWinMsgRend(wmbc->buf, s, rend); - sprintf(s, "%d", win->w_number); + bmax = len - (s - buf); + max = snprintf(s, bmax, "%d", win->w_number); REPORT_SNPRINTF(max, bmax); s += strlen(s); if (!(flags & 2)) { s = AddWindowFlags(s, len, win); @@ -6166,49 +6174,72 @@ static void ShowInfo(void) char buf[512], *p; Window *wp = fore; int i; + int max, bmax; if (wp == NULL) { Msg(0, "(%d,%d)/(%d,%d) no window", D_x + 1, D_y + 1, D_width, D_height); return; } p = buf; - if (buf < (p += GetAnsiStatus(wp, p))) + if (buf < (p += GetAnsiStatus(wp, p, sizeof(buf) - (p - buf)))) *p++ = ' '; - sprintf(p, "(%d,%d)/(%d,%d)", wp->w_x + 1, wp->w_y + 1, wp->w_width, wp->w_height); - sprintf(p += strlen(p), "+%d", wp->w_histheight); - sprintf(p += strlen(p), " %c%sflow", + bmax = sizeof(buf) - (p-buf); + max = snprintf(p, bmax, "(%d,%d)/(%d,%d)", wp->w_x + 1, wp->w_y + 1, wp->w_width, wp->w_height); REPORT_SNPRINTF(max, bmax); + bmax = sizeof(buf) - (p-buf); + max = snprintf(p += strlen(p), bmax, "+%d", wp->w_histheight); REPORT_SNPRINTF(max, bmax); + bmax = sizeof(buf) - (p-buf); + max = snprintf(p += strlen(p), bmax, " %c%sflow", (wp->w_flow & FLOW_ON) ? '+' : '-', - (wp->w_flow & FLOW_AUTOFLAG) ? "" : ((wp->w_flow & FLOW_AUTO) ? "(+)" : "(-)")); - if (!wp->w_wrap) - sprintf(p += strlen(p), " -wrap"); - if (wp->w_insert) - sprintf(p += strlen(p), " ins"); - if (wp->w_origin) - sprintf(p += strlen(p), " org"); - if (wp->w_keypad) - sprintf(p += strlen(p), " app"); - if (wp->w_log) - sprintf(p += strlen(p), " log"); + (wp->w_flow & FLOW_AUTOFLAG) ? "" : ((wp->w_flow & FLOW_AUTO) ? "(+)" : "(-)")); REPORT_SNPRINTF(max, bmax); + if (!wp->w_wrap) { + bmax = sizeof(buf) - (p-buf); + max = snprintf(p += strlen(p), bmax, " -wrap"); REPORT_SNPRINTF(max, bmax); + } + if (wp->w_insert) { + bmax = sizeof(buf) - (p-buf); + max = snprintf(p += strlen(p), bmax, " ins"); REPORT_SNPRINTF(max, bmax); + } + if (wp->w_origin) { + bmax = sizeof(buf) - (p-buf); + max = snprintf(p += strlen(p), bmax, " org"); REPORT_SNPRINTF(max, bmax); + } + if (wp->w_keypad) { + bmax = sizeof(buf) - (p-buf); + max = snprintf(p += strlen(p), bmax, " app"); REPORT_SNPRINTF(max, bmax); + } + if (wp->w_log) { + bmax = sizeof(buf) - (p-buf); + max = snprintf(p += strlen(p), bmax, " log"); REPORT_SNPRINTF(max, bmax); + } if (wp->w_monitor != MON_OFF && (ACLBYTE(wp->w_mon_notify, D_user->u_id) & ACLBIT(D_user->u_id)) - ) - sprintf(p += strlen(p), " mon"); - if (wp->w_mouse) - sprintf(p += strlen(p), " mouse"); - if (!wp->w_c1) - sprintf(p += strlen(p), " -c1"); - if (wp->w_norefresh) - sprintf(p += strlen(p), " nored"); + ) { + bmax = sizeof(buf) - (p-buf); + max = snprintf(p += strlen(p), bmax, " mon"); REPORT_SNPRINTF(max, bmax); + } + if (wp->w_mouse) { + bmax = sizeof(buf) - (p-buf); + max = snprintf(p += strlen(p), bmax, " mouse"); REPORT_SNPRINTF(max, bmax); + } + if (!wp->w_c1) { + bmax = sizeof(buf) - (p-buf); + max = snprintf(p += strlen(p), bmax, " -c1"); REPORT_SNPRINTF(max, bmax); + } + if (wp->w_norefresh) { + bmax = sizeof(buf) - (p-buf); + max = snprintf(p += strlen(p), bmax, " nored"); REPORT_SNPRINTF(max, bmax); + } p += strlen(p); if (wp->w_encoding && (display == NULL || D_encoding != wp->w_encoding || EncodingDefFont(wp->w_encoding) <= 0)) { *p++ = ' '; - strcpy(p, EncodingName(wp->w_encoding)); + strcpy(p, EncodingName(wp->w_encoding)); // FIXME: strncpy() p += strlen(p); } if (wp->w_encoding != UTF8) if (display && (D_CC0 || (D_CS0 && *D_CS0))) { if (wp->w_gr == 2) { - sprintf(p, " G%c", wp->w_Charset + '0'); + bmax = sizeof(buf) - (p-buf); + max = snprintf(p, bmax, " G%c", wp->w_Charset + '0'); REPORT_SNPRINTF(max, bmax); if (wp->w_FontE >= ' ') p[3] = wp->w_FontE; else { @@ -6218,10 +6249,13 @@ static void ShowInfo(void) } p[4] = '['; p++; - } else if (wp->w_gr) - sprintf(p++, " G%c%c[", wp->w_Charset + '0', wp->w_CharsetR + '0'); - else - sprintf(p, " G%c[", wp->w_Charset + '0'); + } else if (wp->w_gr) { + bmax = sizeof(buf) - (p-buf); + max = snprintf(p++, bmax, " G%c%c[", wp->w_Charset + '0', wp->w_CharsetR + '0'); REPORT_SNPRINTF(max, bmax); + } else { + bmax = sizeof(buf) - (p-buf); + max = snprintf(p, bmax, " G%c[", wp->w_Charset + '0'); REPORT_SNPRINTF(max, bmax); + } p += 4; for (i = 0; i < 4; i++) { if (wp->w_charsets[i] == ASCII) @@ -6240,7 +6274,7 @@ static void ShowInfo(void) if (wp->w_type == W_TYPE_PLAIN) { /* add info about modem control lines */ *p++ = ' '; - TtyGetModemStatus(wp->w_ptyfd, p); + TtyGetModemStatus(wp->w_ptyfd, p, sizeof(buf) - (p-buf)); } #ifdef ENABLE_TELNET else if (wp->w_type == W_TYPE_TELNET) { @@ -6255,11 +6289,12 @@ static void ShowDInfo(void) { char buf[512], *p; int l, w; + int max; if (display == NULL) return; p = buf; l = 512; - sprintf(p, "(%d,%d)", D_width, D_height); + max = snprintf(p, sizeof(buf), "(%d,%d)", D_width, D_height); REPORT_SNPRINTF(max, sizeof(buf)); w = strlen(p); l -= w; p += w; @@ -6458,10 +6493,11 @@ static void SetenvFin2(char *buf, size_t len, void *data) static void InputSetenv(char *arg) { static char setenv_buf[50 + ARRAY_SIZE(setenv_var)]; /* need to be static here, cannot be freed */ + int max; if (arg) { strncpy(setenv_var, arg, ARRAY_SIZE(setenv_var) - 1); - sprintf(setenv_buf, "Enter value for %s: ", setenv_var); + max = snprintf(setenv_buf, sizeof(setenv_buf), "Enter value for %s: ", setenv_var); REPORT_SNPRINTF(max, sizeof(setenv_buf)); Input(setenv_buf, 30, INP_COOKED, SetenvFin2, NULL, 0); } else Input("Setenv: Enter variable name: ", 30, INP_COOKED, SetenvFin1, NULL, 0); diff --git a/src/screen.c b/src/screen.c index b5d91a6..11ca52c 100644 --- a/src/screen.c +++ b/src/screen.c @@ -306,6 +306,7 @@ int main(int argc, char **argv) char *sty = NULL; char *multi_home = NULL; bool cmdflag = 0; + int max, bmax; /* * First, close all unused descriptors @@ -781,17 +782,17 @@ int main(int argc, char **argv) } if (multiattach) { #ifndef SOCKET_DIR - sprintf(SocketPath, "%s/.screen", multi_home); + max = snprintf(SocketPath, sizeof(SocketPath), "%s/.screen", multi_home); REPORT_SNPRINTF(max, sizeof(SocketPath)); #else SocketDir = SOCKET_DIR; - sprintf(SocketPath, "%s/S-%s", SocketDir, multi); + max = snprintf(SocketPath, sizeof(SocketPath), "%s/S-%s", SocketDir, multi); REPORT_SNPRINTF(max, sizeof(SocketPath)); #endif } else { #ifndef SOCKET_DIR if (SocketDir == NULL) { if (strlen(home) > MAXPATHLEN - 8 - 1) Panic(0, "$HOME too long - sorry."); - sprintf(SocketPath, "%s/.screen", home); + max = snprintf(SocketPath, sizeof(SocketPath), "%s/.screen", home); REPORT_SNPRINTF(max, sizeof(SocketPath)); SocketDir = SocketPath; } #endif @@ -831,7 +832,7 @@ int main(int argc, char **argv) if (((int)st.st_mode & 0777) != n) Panic(0, "Directory '%s' must have mode %03o.", SocketDir, n); } - sprintf(SocketPath, "%s/S-%s", SocketDir, LoginName); + max = snprintf(SocketPath, sizeof(SocketPath), "%s/S-%s", SocketDir, LoginName); REPORT_SNPRINTF(max, sizeof(SocketPath)); if (access(SocketPath, F_OK)) { if (mkdir(SocketPath, 0700) == -1 && errno != EEXIST) Panic(errno, "Cannot make directory '%s'", SocketPath); @@ -938,16 +939,18 @@ int main(int argc, char **argv) default: if (detached) exit(0); - if (SocketMatch) - sprintf(socknamebuf, "%d.%s", MasterPid, SocketMatch); - else - sprintf(socknamebuf, "%d.%s.%s", MasterPid, stripdev(attach_tty), HostName); + if (SocketMatch) { + max = snprintf(socknamebuf, sizeof(socknamebuf), "%d.%s", MasterPid, SocketMatch); REPORT_SNPRINTF(max, sizeof(socknamebuf)); + } else { + max = snprintf(socknamebuf, sizeof(socknamebuf), "%d.%s.%s", MasterPid, stripdev(attach_tty), HostName); REPORT_SNPRINTF(max, sizeof(socknamebuf)); + } for (ap = socknamebuf; *ap; ap++) if (*ap == '/') *ap = '-'; if (strlen(socknamebuf) > FILENAME_MAX) socknamebuf[FILENAME_MAX - 1] = 0; - snprintf(SocketPath + strlen(SocketPath), sizeof(SocketPath) - strlen(SocketPath), "/%s", socknamebuf); + bmax = sizeof(SocketPath) - strlen(SocketPath); + max = snprintf(SocketPath + strlen(SocketPath), bmax, "/%s", socknamebuf); REPORT_SNPRINTF(max, bmax); SET_GUID(); Attacher(); /* NOTREACHED */ @@ -1002,9 +1005,9 @@ int main(int argc, char **argv) if (SocketMatch) { /* user started us with -S option */ - sprintf(socknamebuf, "%d.%s", (int)getpid(), SocketMatch); + max = snprintf(socknamebuf, sizeof(socknamebuf), "%d.%s", (int)getpid(), SocketMatch); REPORT_SNPRINTF(max, sizeof(socknamebuf)); } else { - sprintf(socknamebuf, "%d.%s.%s", (int)getpid(), stripdev(attach_tty), HostName); + max = snprintf(socknamebuf, sizeof(socknamebuf), "%d.%s.%s", (int)getpid(), stripdev(attach_tty), HostName); REPORT_SNPRINTF(max, sizeof(socknamebuf)); } for (ap = socknamebuf; *ap; ap++) if (*ap == '/') @@ -1012,8 +1015,8 @@ int main(int argc, char **argv) if (strlen(socknamebuf) > FILENAME_MAX) { socknamebuf[FILENAME_MAX] = 0; } - snprintf(SocketPath + strlen(SocketPath), sizeof(SocketPath) - strlen(SocketPath), "/%s", socknamebuf); - + bmax = sizeof(SocketPath) - strlen(SocketPath); + max = snprintf(SocketPath + strlen(SocketPath), bmax, "/%s", socknamebuf); REPORT_SNPRINTF(max, bmax); ServerSocket = MakeServerSocket(); #ifdef SYSTEM_SCREENRC (void)StartRc(SYSTEM_SCREENRC, 0); @@ -1154,6 +1157,7 @@ static void CoreDump(int sigsig) Display *disp; char buf[80]; + int max; (void)sigsig; /* unused */ @@ -1163,7 +1167,7 @@ static void CoreDump(int sigsig) Panic(0, "setuid"); unlink("core"); - sprintf(buf, "\r\n[screen caught a fatal signal. (core dumped)]\r\n"); + max = snprintf(buf, sizeof(buf), "\r\n[screen caught a fatal signal. (core dumped)]\r\n"); REPORT_SNPRINTF(max, sizeof(buf)); for (disp = displays; disp; disp = disp->d_next) { if (disp->d_nonblock < -1 || disp->d_nonblock > 1000000) @@ -1442,6 +1446,7 @@ void MakeNewEnv(void) { char **op, **np; static char stybuf[MAXSTR]; + int max; for (op = environ; *op; ++op) ; if (NewEnv) @@ -1449,7 +1454,7 @@ void MakeNewEnv(void) NewEnv = np = malloc((unsigned)(op - environ + 7 + 1) * sizeof(char *)); if (!NewEnv) Panic(0, "%s", strnomem); - sprintf(stybuf, "STY=%s", strlen(SocketName) <= MAXSTR - 5 ? SocketName : "?"); + max = snprintf(stybuf, sizeof(stybuf), "STY=%s", strlen(SocketName) <= MAXSTR - 5 ? SocketName : "?"); REPORT_SNPRINTF(max, sizeof(stybuf)); *np++ = stybuf; /* NewEnv[0] */ *np++ = Term; /* NewEnv[1] */ np++; /* room for SHELL */ diff --git a/src/screen.h b/src/screen.h index 5f6f373..4745b73 100644 --- a/src/screen.h +++ b/src/screen.h @@ -323,4 +323,11 @@ extern uid_t real_uid; extern struct passwd *ppp; +#define SHOW_BUF_OVERFLOW +#ifdef SHOW_BUF_OVERFLOW +#define REPORT_SNPRINTF(wr,sz) if (wr >= (int)(sz)) fprintf(stderr, "%s:%d: caught internal buffer overflow\n", __FILE__, __LINE__) +#else +#define REPORT_SNPRINTF(wr,sz) (void) +#endif // SHOW_BUF_OVERFLOW + #endif /* SCREEN_SCREEN_H */ diff --git a/src/socket.c b/src/socket.c index 78efc97..cc01985 100644 --- a/src/socket.c +++ b/src/socket.c @@ -122,6 +122,7 @@ int FindSocket(int *fdp, int *nfoundp, int *notherp, char *match) char *firstn = NULL; int nfound = 0, ngood = 0, ndead = 0, nwipe = 0, npriv = 0; int nperfect = 0; + int max, bmax; struct sent { struct sent *next; int mode; @@ -179,7 +180,8 @@ int FindSocket(int *fdp, int *nfoundp, int *notherp, char *match) } else cmatch = (*(n + matchlen) == 0); } - sprintf(SocketPath + sdirlen, "/%s", name); + bmax = sizeof(SocketPath) - sdirlen - 1; // +1 for the / + max = snprintf(SocketPath + sdirlen, bmax, "/%s", name); REPORT_SNPRINTF(max, bmax); errno = 0; if (stat(SocketPath, &st)) { @@ -320,7 +322,8 @@ int FindSocket(int *fdp, int *nfoundp, int *notherp, char *match) Msg(0, m, ndead > 1 ? "s" : "", ndead > 1 ? "" : "es"); } if (firsts != -1) { - sprintf(SocketPath + sdirlen, "/%s", firstn); + bmax = sizeof(SocketPath) - sdirlen - 1; // +1 for / + max = snprintf(SocketPath + sdirlen, bmax, "/%s", firstn); REPORT_SNPRINTF(max, bmax); *fdp = firsts; } else SocketPath[sdirlen] = 0; @@ -432,12 +435,14 @@ void SendCreateMsg(char *sty, struct NewWindow *nwin) char *p; size_t len, n; char **av; + int max, bmax; if (strlen(sty) > FILENAME_MAX) sty[FILENAME_MAX] = 0; if (strlen(sty) > 2 * MAXSTR - 1) sty[2 * MAXSTR - 1] = 0; - sprintf(SocketPath + strlen(SocketPath), "/%s", sty); + bmax = sizeof(SocketPath) - strlen(SocketPath); + max = snprintf(SocketPath + strlen(SocketPath), bmax, "/%s", sty); REPORT_SNPRINTF(max, bmax); if ((s = MakeClientSocket(1)) == -1) exit(1); memset((char *)&m, 0, sizeof(Message)); @@ -857,7 +862,7 @@ void ReceiveMsg(void) char *oldSocketPath = SaveStr(SocketPath); strncpy(SocketPath, m.m.command.writeback, ARRAY_SIZE(SocketPath)); int s = MakeClientSocket(0); - strncpy(SocketPath, oldSocketPath, ARRAY_SIZE(SocketPath)); + strncpy(SocketPath, oldSocketPath, ARRAY_SIZE(SocketPath)-1); Free(oldSocketPath); if (s >= 0) { queryflag = s; diff --git a/src/telnet.c b/src/telnet.c index 69d75ee..6372d49 100644 --- a/src/telnet.c +++ b/src/telnet.c @@ -412,7 +412,7 @@ static void TelDosub(Window *win) len = strlen(screenterm); if (len >= MAXTERMLEN) break; - sprintf(trepl, "%c%c%c%c%s%c%c", TC_IAC, TC_SB, TO_TTYPE, 0, screenterm, TC_IAC, TC_SE); + max = snprintf(trepl, sizeof(trepl), "%c%c%c%c%s%c%c", TC_IAC, TC_SB, TO_TTYPE, 0, screenterm, TC_IAC, TC_SE); REPORT_SNPRINTF(max, sizeof(trepl)); TelReply(win, trepl, len + 6); break; case TO_LFLOW: @@ -433,11 +433,12 @@ void TelBreak(Window *win) void TelWindowSize(Window *win) { char s[20], trepl[20], *t; + int max; if (win->w_width == 0 || win->w_height == 0 || !win->w_telmopts[TO_NAWS]) return; - sprintf(s, "%c%c%c%c%c%c%c%c%c", TC_SB, TC_SB, TO_NAWS, win->w_width / 256, win->w_width & 255, win->w_height / 256, - win->w_height & 255, TC_SE, TC_SE); + max = snprintf(s, sizeof(s), "%c%c%c%c%c%c%c%c%c", TC_SB, TC_SB, TO_NAWS, win->w_width / 256, win->w_width & 255, win->w_height / 256, + win->w_height & 255, TC_SE, TC_SE); REPORT_SNPRINTF(max, sizeof(s)); t = trepl; for (size_t i = 0; i < 9; i++) if ((unsigned char)(*t++ = s[i]) == TC_IAC) diff --git a/src/termcap.c b/src/termcap.c index b49818b..5cf51ed 100644 --- a/src/termcap.c +++ b/src/termcap.c @@ -657,6 +657,7 @@ char *MakeTermcap(bool aflag) char buf[TERMCAP_BUFSIZE]; char *p, *cp, *s, ch, *tname; int i, width, height; + int max, bmax; if (display) { width = D_width; @@ -668,7 +669,7 @@ char *MakeTermcap(bool aflag) tname = "vt100"; } if ((s = getenv("SCREENCAP")) && strlen(s) < TERMCAP_BUFSIZE) { - sprintf(Termcap, "TERMCAP=%s", s); + max = snprintf(Termcap, sizeof(Termcap), "TERMCAP=%s", s); REPORT_SNPRINTF(max, sizeof(Termcap)); strcpy(Term, "TERM=screen"); return Termcap; } @@ -681,12 +682,14 @@ char *MakeTermcap(bool aflag) strcpy(Term, "TERM="); p = Term + 5; if (!aflag && strlen(screenterm) + strlen(tname) < MAXSTR - 1) { - sprintf(p, "%s.%s", screenterm, tname); + bmax = sizeof(Term) - (p - Term); + max = snprintf(p, bmax, "%s.%s", screenterm, tname); REPORT_SNPRINTF(max, bmax); if (e_tgetent(buf, p) == 1) break; } if (nwin_default.bce) { - sprintf(p, "%s-bce", screenterm); + bmax = sizeof(Term) - (p - Term); + max = snprintf(p, bmax, "%s-bce", screenterm); REPORT_SNPRINTF(max, bmax); if (e_tgetent(buf, p) == 1) break; } @@ -700,7 +703,7 @@ char *MakeTermcap(bool aflag) tcLineLen = 100; /* Force NL */ if (strlen(Term) > TERMCAP_BUFSIZE - 40) strcpy(Term, "too_long"); - sprintf(Termcap, "TERMCAP=SC|%s|VT 100/ANSI X3.64 virtual terminal:", Term + 5); + max = snprintf(Termcap, sizeof(Termcap), "TERMCAP=SC|%s|VT 100/ANSI X3.64 virtual terminal:", Term + 5); REPORT_SNPRINTF(max, sizeof(Termcap)); Termcaplen = strlen(Termcap); if (extra_outcap && *extra_outcap) { for (cp = extra_outcap; (p = strchr(cp, ':')); cp = p) { @@ -715,7 +718,7 @@ char *MakeTermcap(bool aflag) strcpy(Termcap + Termcaplen, TermcapConst); Termcaplen += strlen(TermcapConst); } - sprintf(buf, "li#%d:co#%d:", height, width); + max = snprintf(buf, sizeof(buf), "li#%d:co#%d:", height, width); REPORT_SNPRINTF(max, sizeof(buf)); AddCap(buf); AddCap("am:"); if (aflag || (force_vt && !D_COP) || D_CLP || !D_AM) { @@ -844,7 +847,7 @@ char *MakeTermcap(bool aflag) case T_FLG: if (D_tcs[i].flg == 0) break; - sprintf(buf, "%s:", term[i].tcname); + max = snprintf(buf, sizeof(buf), "%s:", term[i].tcname); REPORT_SNPRINTF(max, sizeof(buf)); AddCap(buf); break; default: @@ -885,6 +888,7 @@ static void MakeString(char *cap, char *buf, int buflen, char *s) { char *p, *pmax; unsigned int c; + int max, bmax; p = buf; pmax = p + buflen - (3 + 4 + 2); @@ -908,7 +912,8 @@ static void MakeString(char *cap, char *buf, int buflen, char *s) break; default: if (c >= 200) { - sprintf(p, "\\%03o", c & 0377); + bmax = buflen - (pmax - p); + max = snprintf(p, bmax, "\\%03o", c & 0377); REPORT_SNPRINTF(max, bmax); p += 4; } else if (c < ' ') { *p++ = '^'; diff --git a/src/tty.c b/src/tty.c index de5b8cd..b1f6757 100644 --- a/src/tty.c +++ b/src/tty.c @@ -889,9 +889,10 @@ int TtyGrabConsole(int fd, bool on, char *rc_name) * Will not write more than 256 characters to buf. * Returns buf; */ -char *TtyGetModemStatus(int fd, char *buf) +char *TtyGetModemStatus(int fd, char *buf, int buflen) { char *p = buf; + int max, bmax; #ifdef TIOCGSOFTCAR unsigned int softcar; #endif @@ -965,10 +966,11 @@ char *TtyGetModemStatus(int fd, char *buf) #endif #endif { + bmax = buflen - (p - buf); #ifdef TIOCGSOFTCAR - sprintf(p, "NO-TTY? %s", softcar ? "(CD)" : "CD"); + max = snprintf(p, bmax, "NO-TTY? %s", softcar ? "(CD)" : "CD"); REPORT_SNPRINTF(max, bmax); #else - sprintf(p, "NO-TTY?"); + max = snprintf(p, bmax, "NO-TTY?"); REPORT_SNPRINTF(max, bmax); #endif p += strlen(p); } else { @@ -1061,7 +1063,8 @@ char *TtyGetModemStatus(int fd, char *buf) } #else #ifdef TIOCGSOFTCAR - sprintf(p, " %s", softcar ? "(CD)", "CD"); + bmax = buflen - (p - buf); + max = snprintf(p, bmax, " %s", softcar ? "(CD)", "CD"); REPORT_SPRINTF(max, bmax); p += strlen(p); #endif #endif diff --git a/src/tty.h b/src/tty.h index d0eee3a..bb1a1ba 100644 --- a/src/tty.h +++ b/src/tty.h @@ -12,7 +12,7 @@ void SetMode (struct mode *, struct mode *, int, int); void SetFlow (bool); void SendBreak (Window *, int, int); int TtyGrabConsole (int, bool, char *); -char *TtyGetModemStatus (int, char *); +char *TtyGetModemStatus (int, char *, int buflen); void brktty (int); int fgtty(int fd); int CheckTtyname (char *); diff --git a/src/window.c b/src/window.c index 9f5e2d4..8a54d11 100644 --- a/src/window.c +++ b/src/window.c @@ -1894,6 +1894,7 @@ int SwapWindows(int old, int dest) void WindowDied(Window *p, int wstat, int wstat_valid) { int killit = 0; + int max; if (p->w_destroyev.data == (char *)p) { wstat = p->w_exitstatus; @@ -1917,20 +1918,23 @@ void WindowDied(Window *p, int wstat, int wstat_valid) time_t now; if (wstat_valid) { - if (WIFEXITED(wstat)) - if (WEXITSTATUS(wstat)) - sprintf(reason, "terminated with exit status %d", WEXITSTATUS(wstat)); - else - sprintf(reason, "terminated normally"); - else if (WIFSIGNALED(wstat)) - sprintf(reason, "terminated with signal %d%s", WTERMSIG(wstat), + if (WIFEXITED(wstat)) { + if (WEXITSTATUS(wstat)) { + max = snprintf(reason, sizeof(reason), "terminated with exit status %d", WEXITSTATUS(wstat)); REPORT_SNPRINTF(max, sizeof(reason)); + } else { + max = snprintf(reason, sizeof(reason), "terminated normally"); REPORT_SNPRINTF(max, sizeof(reason)); + } + } else if (WIFSIGNALED(wstat)) { + max = snprintf(reason, sizeof(reason), "terminated with signal %d%s", WTERMSIG(wstat), #ifdef WCOREDUMP - WCOREDUMP(wstat) ? " (core file generated)" : ""); + WCOREDUMP(wstat) ? " (core file generated)" : ""); REPORT_SNPRINTF(max, sizeof(reason)); #else - ""); + ""); REPORT_SNPRINTF(max, sizeof(reason)); #endif - } else - sprintf(reason, "detached from window"); + } + } else { + max = snprintf(reason, sizeof(reason), "detached from window"); REPORT_SNPRINTF(max, sizeof(reason)); + } (void)time(&now); s = ctime(&now); @@ -1949,7 +1953,7 @@ void WindowDied(Window *p, int wstat, int wstat_valid) ResetWindow(p); /* p->w_y = p->w_bot; */ p->w_y = MFindUsedLine(p, p->w_bot, 1); - sprintf(buf, "\n\r=== Command %s (%s) ===", reason, s ? s : "?"); + max = snprintf(buf, sizeof(buf), "\n\r=== Command %s (%s) ===", reason, s ? s : "?"); REPORT_SNPRINTF(max, sizeof(buf)); WriteString(p, buf, strlen(buf)); if (p->w_poll_zombie_timeout) { SetTimeout(&p->w_zombieev, p->w_poll_zombie_timeout * 1000);