From: nhkeni Date: Mon, 7 Mar 2022 01:23:04 +0000 (-0500) Subject: Add Strlen(), a strlen(3) that panics if string is stupid long and returns unsigned. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ff1289e828816def6ff713dbc504292d291fc5f8;p=nethack Add Strlen(), a strlen(3) that panics if string is stupid long and returns unsigned. First batch of changes to use it to suppress warnings. --- diff --git a/include/extern.h b/include/extern.h index 1138db340..fa7cc5fab 100644 --- a/include/extern.h +++ b/include/extern.h @@ -968,6 +968,7 @@ extern char *strip_newline(char *); extern char *stripchars(char *, const char *, const char *); extern char *stripdigits(char *); extern char *eos(char *); +extern unsigned Strlen(const char *); extern boolean str_end_is(const char *, const char *); extern int str_lines_maxlen(const char *); extern char *strkitten(char *, char); diff --git a/src/botl.c b/src/botl.c index f12b106f4..4e6af9150 100644 --- a/src/botl.c +++ b/src/botl.c @@ -368,7 +368,7 @@ title_to_mon(const char *str, int *rank_indx, int *title_length) if (rank_indx) *rank_indx = j; if (title_length) - *title_length = strlen(roles[i].rank[j].m); + *title_length = Strlen(roles[i].rank[j].m); return roles[i].mnum; } if (roles[i].rank[j].f @@ -376,7 +376,7 @@ title_to_mon(const char *str, int *rank_indx, int *title_length) if (rank_indx) *rank_indx = j; if (title_length) - *title_length = strlen(roles[i].rank[j].f); + *title_length = Strlen(roles[i].rank[j].f); return roles[i].mnum; } } diff --git a/src/cmd.c b/src/cmd.c index b22d68fbd..32ac3e1c6 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -2550,7 +2550,7 @@ extcmds_match(const char *findstr, int ecmflags, int **matchlist) { static int retmatchlist[SIZE(extcmdlist)] = DUMMY; int i, mi = 0; - int fslen = findstr ? strlen(findstr) : 0; + int fslen = findstr ? Strlen(findstr) : 0; boolean ignoreac = (ecmflags & ECM_IGNOREAC) != 0; boolean exactmatch = (ecmflags & ECM_EXACTMATCH) != 0; boolean no1charcmd = (ecmflags & ECM_NO1CHARCMD) != 0; diff --git a/src/eat.c b/src/eat.c index 2b464802d..1985ecd14 100644 --- a/src/eat.c +++ b/src/eat.c @@ -176,9 +176,10 @@ eatmupdate(void) if (altmsg) { /* replace end-of-mimicking message */ - if (strlen(altmsg) > strlen(g.eatmbuf)) { + int amlen = Strlen(altmsg); + if (amlen > Strlen(g.eatmbuf)) { free((genericptr_t) g.eatmbuf); - g.eatmbuf = (char *) alloc(strlen(altmsg) + 1); + g.eatmbuf = (char *) alloc(amlen + 1); } g.nomovemsg = strcpy(g.eatmbuf, altmsg); /* update current image */ diff --git a/src/end.c b/src/end.c index c3b371613..0fcd8798d 100644 --- a/src/end.c +++ b/src/end.c @@ -1423,7 +1423,7 @@ really_done(int how) corpse = mk_named_object(CORPSE, &mons[mnum], u.ux, u.uy, g.plname); Sprintf(pbuf, "%s, ", g.plname); - formatkiller(eos(pbuf), sizeof pbuf - strlen(pbuf), how, TRUE); + formatkiller(eos(pbuf), sizeof pbuf - Strlen(pbuf), how, TRUE); make_grave(u.ux, u.uy, pbuf); } pbuf[0] = '\0'; /* clear grave text; also lint suppression */ diff --git a/src/engrave.c b/src/engrave.c index 7b9573781..9e6384cb2 100644 --- a/src/engrave.c +++ b/src/engrave.c @@ -388,7 +388,7 @@ void make_engr_at(int x, int y, const char *s, long e_time, xchar e_type) { struct engr *ep; - unsigned smem = strlen(s) + 1; + unsigned smem = Strlen(s) + 1; if ((ep = engr_at(x, y)) != 0) del_engr(ep); diff --git a/src/hacklib.c b/src/hacklib.c index 84856a1c9..33f01c904 100644 --- a/src/hacklib.c +++ b/src/hacklib.c @@ -24,6 +24,7 @@ char * strip_newline (char *) char * stripchars (char *, const char *, const char *) char * stripdigits (char *) + unsigned Strlen (const char *str) char * eos (char *) boolean str_end_is (const char *, const char *) int str_lines_maxlen (const char *) @@ -228,6 +229,16 @@ eos(register char *s) return s; } +/* like strlen(3) but returns unsigned and panics if string is unreasonably long */ +unsigned +Strlen(const char *str){ + size_t len = strnlen(str, LARGEST_INT); + + if (len == LARGEST_INT) + panic("string too long"); + return (unsigned) len; +} + /* determine whether 'str' ends in 'chkstr' */ boolean str_end_is(const char *str, const char *chkstr) diff --git a/src/invent.c b/src/invent.c index 1ff07a2d4..ac82b2206 100644 --- a/src/invent.c +++ b/src/invent.c @@ -3985,8 +3985,8 @@ let_to_name(char let, boolean unpaid, boolean showsym) else class_name = names[0]; - len = strlen(class_name) + (unpaid ? sizeof "unpaid_" : sizeof "") - + (oclass ? (strlen(ocsymfmt) + invbuf_sympadding) : 0); + len = Strlen(class_name) + (unpaid ? sizeof "unpaid_" : sizeof "") + + (oclass ? (Strlen(ocsymfmt) + invbuf_sympadding) : 0); if (len > g.invbufsiz) { if (g.invbuf) free((genericptr_t) g.invbuf); @@ -3999,7 +3999,7 @@ let_to_name(char let, boolean unpaid, boolean showsym) Strcpy(g.invbuf, class_name); if ((oclass != 0) && showsym) { char *bp = eos(g.invbuf); - int mlen = invbuf_sympadding - strlen(class_name); + int mlen = invbuf_sympadding - Strlen(class_name); while (--mlen > 0) { *bp = ' '; bp++; diff --git a/src/nhlua.c b/src/nhlua.c index ad8eb7756..8c3ad0f61 100644 --- a/src/nhlua.c +++ b/src/nhlua.c @@ -1382,7 +1382,7 @@ nhl_loadlua(lua_State *L, const char *fname) long buflen, ct, cnt; int llret; - altfname = (char *) alloc(strlen(fname) + 3); /* 3: '('...')\0' */ + altfname = (char *) alloc(Strlen(fname) + 3); /* 3: '('...')\0' */ /* don't know whether 'fname' is inside a dlb container; if we did, we could choose between "nhdat()" and "" but since we don't, compromise */ diff --git a/src/o_init.c b/src/o_init.c index bea7c6a75..143db6170 100644 --- a/src/o_init.c +++ b/src/o_init.c @@ -383,7 +383,7 @@ savenames(NHFILE* nhfp) for (i = 0; i < NUM_OBJECTS; i++) if (objects[i].oc_uname) { if (perform_bwrite(nhfp)) { - len = strlen(objects[i].oc_uname) + 1; + len = Strlen(objects[i].oc_uname) + 1; if (nhfp->structlevel) { bwrite(nhfp->fd, (genericptr_t)&len, sizeof len); bwrite(nhfp->fd, (genericptr_t)objects[i].oc_uname, len); diff --git a/src/objnam.c b/src/objnam.c index 28a3fc3d1..8a63159c3 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -402,7 +402,7 @@ fruit_from_name( if (!exact) { tentativef = 0; for (f = g.ffruit; f; f = f->nextf) { - k = strlen(f->fname); + k = Strlen(f->fname); if (!strncmp(f->fname, fname, k) && (!fname[k] || fname[k] == ' ') && (!tentativef || k > strlen(tentativef->fname))) @@ -422,11 +422,11 @@ fruit_from_name( } if (!f && !exact) { char fnamebuf[BUFSZ], *p; - unsigned fname_k = strlen(fname); /* length of assumed plural fname */ + unsigned fname_k = Strlen(fname); /* length of assumed plural fname */ tentativef = 0; for (f = g.ffruit; f; f = f->nextf) { - k = strlen(f->fname); + k = Strlen(f->fname); /* reload fnamebuf[] each iteration in case it gets modified; there's no need to recalculate fname_k */ Strcpy(fnamebuf, fname); @@ -441,7 +441,7 @@ fruit_from_name( if (fname_k >= k && (p = index(&fnamebuf[k], ' ')) != 0) { *p = '\0'; /* truncate at 1st space past length of f->fname */ altfname = makesingular(fnamebuf); - k = strlen(altfname); /* actually revised 'fname_k' */ + k = Strlen(altfname); /* actually revised 'fname_k' */ if (!strcmp(f->fname, altfname) && (!tentativef || k > strlen(tentativef->fname))) tentativef = f; @@ -1976,7 +1976,7 @@ yobjnam(struct obj* obj, const char *verb) if (!carried(obj) || !obj_is_pname(obj) || obj->oartifact >= ART_ORB_OF_DETECTION) { char *outbuf = shk_your(nextobuf(), obj); - int space_left = BUFSZ - 1 - strlen(outbuf); + int space_left = BUFSZ - 1 - Strlen(outbuf); s = strncat(outbuf, s, space_left); } @@ -2050,7 +2050,7 @@ yname(struct obj* obj) if (!carried(obj) || !obj_is_pname(obj) || obj->oartifact >= ART_ORB_OF_DETECTION) { char *outbuf = shk_your(nextobuf(), obj); - int space_left = BUFSZ - 1 - strlen(outbuf); + int space_left = BUFSZ - 1 - Strlen(outbuf); s = strncat(outbuf, s, space_left); } @@ -2077,7 +2077,7 @@ ysimple_name(struct obj* obj) { char *outbuf = nextobuf(); char *s = shk_your(outbuf, obj); /* assert( s == outbuf ); */ - int space_left = BUFSZ - 1 - strlen(s); + int space_left = BUFSZ - 1 - Strlen(s); return strncat(s, minimal_xname(obj), space_left); } @@ -2273,7 +2273,7 @@ vtense(const char* subj, const char* verb) /* check for special cases to avoid false matches */ len = (int) (spot - subj) + 1; for (spec = special_subjs; *spec; spec++) { - ltmp = strlen(*spec); + ltmp = Strlen(*spec); if (len == ltmp && !strncmpi(*spec, subj, len)) goto sing; /* also check for @@ -2377,7 +2377,7 @@ const char *const *alt_as_is) /* another set like as_is[] */ const struct sing_plur *sp; const char *same, *other, *const *as; int al; - int baselen = strlen(basestr); + int baselen = Strlen(basestr); for (as = as_is; *as; ++as) { al = (int) strlen(*as); @@ -2555,7 +2555,7 @@ makeplural(const char* oldstr) *(spot + 1) = '\0'; /* Now spot is the last character of the string */ - len = strlen(str); + len = Strlen(str); /* Single letters */ if (len == 1 || !letter(*spot)) { @@ -4118,7 +4118,7 @@ readobjnam_postparse1(struct _readobjnam_data *d) && strncmpi(d->bp, "food ration", 11) && strncmpi(d->bp, "meat ring", 9)) for (i = 0; i < (int) (sizeof wrpsym); i++) { - register int j = strlen(wrp[i]); + register int j = Strlen(wrp[i]); /* check for " [ of ] something" */ if (!strncmpi(d->bp, wrp[i], j)) { diff --git a/src/role.c b/src/role.c index 5f95e952a..cd3dedbe3 100644 --- a/src/role.c +++ b/src/role.c @@ -748,7 +748,7 @@ str2role(const char *str) return ROLE_NONE; /* Match as much of str as is provided */ - len = strlen(str); + len = Strlen(str); for (i = 0; roles[i].name.m; i++) { /* Does it match the male name? */ if (!strncmpi(str, roles[i].name.m, len)) @@ -878,7 +878,7 @@ str2gend(const char *str) return ROLE_NONE; /* Match as much of str as is provided */ - len = strlen(str); + len = Strlen(str); for (i = 0; i < ROLE_GENDERS; i++) { /* Does it match the adjective? */ if (!strncmpi(str, genders[i].adj, len)) @@ -941,7 +941,7 @@ str2align(const char *str) return ROLE_NONE; /* Match as much of str as is provided */ - len = strlen(str); + len = Strlen(str); for (i = 0; i < ROLE_ALIGNS; i++) { /* Does it match the adjective? */ if (!strncmpi(str, aligns[i].adj, len)) @@ -1530,7 +1530,7 @@ build_plselection_prompt( Strcat(tmpbuf, "a "); /* */ - (void) root_plselection_prompt(eos(tmpbuf), buflen - strlen(tmpbuf), + (void) root_plselection_prompt(eos(tmpbuf), buflen - Strlen(tmpbuf), rolenum, racenum, gendnum, alignnum); /* "Shall I pick a character's role, race, gender, and alignment for you?" plus " [ynaq] (y)" is a little too long for a conventional 80 columns; diff --git a/src/save.c b/src/save.c index cf3ee9116..2c0a94acb 100644 --- a/src/save.c +++ b/src/save.c @@ -243,7 +243,7 @@ save_gamelog(NHFILE *nhfp) tmp2 = tmp->next; if (perform_bwrite(nhfp)) { if (nhfp->structlevel) { - slen = strlen(tmp->text); + slen = Strlen(tmp->text); bwrite(nhfp->fd, (genericptr_t) &slen, sizeof slen); bwrite(nhfp->fd, (genericptr_t) tmp->text, slen); bwrite(nhfp->fd, (genericptr_t) tmp, diff --git a/src/sp_lev.c b/src/sp_lev.c index 5303d2c96..fb7f60b72 100644 --- a/src/sp_lev.c +++ b/src/sp_lev.c @@ -2906,8 +2906,8 @@ lspo_message(lua_State *L) msg = luaL_checkstring(L, 1); - old_n = g.lev_message ? (strlen(g.lev_message) + 1) : 0; - n = strlen(msg); + old_n = g.lev_message ? (Strlen(g.lev_message) + 1) : 0; + n = Strlen(msg); levmsg = (char *) alloc(old_n + n + 1); if (old_n) diff --git a/src/topten.c b/src/topten.c index 384731782..a5f50ae79 100644 --- a/src/topten.c +++ b/src/topten.c @@ -117,7 +117,7 @@ formatkiller( /*FALLTHRU*/ case KILLED_BY: (void) strncat(buf, killed_by_prefix[how], siz - 1); - l = strlen(buf); + l = Strlen(buf); buf += l, siz -= l; break; } diff --git a/src/weapon.c b/src/weapon.c index 935e9f058..4c158abe9 100644 --- a/src/weapon.c +++ b/src/weapon.c @@ -1170,7 +1170,7 @@ enhance_weapon_skill(void) for (longest = 0, i = 0; i < P_NUM_SKILLS; i++) { if (P_RESTRICTED(i)) continue; - if ((len = strlen(P_NAME(i))) > longest) + if ((len = Strlen(P_NAME(i))) > longest) longest = len; if (can_advance(i, speedy)) to_advance++;