Pending 3.7 edition of the naming overflow patch.

Like the 3.6.7 one, the original pieces have been combined into one
commit.  But it is separate from the one added to that version.
This commit is contained in:
PatR
2023-01-27 16:35:35 -08:00
parent 4575d564c7
commit b9bbf0205b
5 changed files with 151 additions and 80 deletions

View File

@@ -1,4 +1,4 @@
HDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1051 $ $NHDT-Date: 1665130022 2022/10/07 08:07:02 $ HDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1093 $ $NHDT-Date: 1672605786 2023/01/01 20:43:06 $
General Fixes and Modified Features General Fixes and Modified Features
----------------------------------- -----------------------------------
@@ -1101,6 +1101,8 @@ eating garlic makes nearby monsters flee
giants occasionally get a battle axe or a two-handed sword giants occasionally get a battle axe or a two-handed sword
give gremlin the property it stole, if possible give gremlin the property it stole, if possible
'F'orcefighting with a war hammer has a small chance of breaking iron bars 'F'orcefighting with a war hammer has a small chance of breaking iron bars
player assigned name for monsters, specific objects, or object types could be
longer than what was intented to be allowed; for 'curses', much longer
Fixes to 3.7.0-x Problems that Were Exposed Via git Repository Fixes to 3.7.0-x Problems that Were Exposed Via git Repository

View File

@@ -1,4 +1,4 @@
/* NetHack 3.7 do_name.c $NHDT-Date: 1655663780 2022/06/19 18:36:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.254 $ */ /* NetHack 3.7 do_name.c $NHDT-Date: 1672605786 2023/01/01 20:43:06 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.280 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Pasi Kallinen, 2018. */ /*-Copyright (c) Pasi Kallinen, 2018. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -19,6 +19,7 @@ static void gloc_filter_done(void);
static boolean gather_locs_interesting(coordxy, coordxy, int); static boolean gather_locs_interesting(coordxy, coordxy, int);
static void gather_locs(coord **, int *, int); static void gather_locs(coord **, int *, int);
static void truncate_to_map(int *, int *, schar, schar); static void truncate_to_map(int *, int *, schar, schar);
static char *name_from_player(char *, const char *, const char *);
static void do_mgivenname(void); static void do_mgivenname(void);
static boolean alreadynamed(struct monst *, char *, char *); static boolean alreadynamed(struct monst *, char *, char *);
static void do_oname(struct obj *); static void do_oname(struct obj *);
@@ -1180,6 +1181,34 @@ safe_oname(struct obj *obj)
return ""; return "";
} }
/* get a name for a monster or an object from player;
truncate if longer than PL_PSIZ, then return it */
static char *
name_from_player(
char *outbuf, /* output buffer, assumed to be at least BUFSZ long;
* anything longer than PL_PSIZ will be truncated */
const char *prompt,
const char *defres) /* only used if EDIT_GETLIN is enabled; only useful
* if windowport xxx's xxx_getlin() supports that */
{
outbuf[0] = '\0';
#ifdef EDIT_GETLIN
if (defres && *defres)
Strcpy(outbuf, defres); /* default response from getlin() */
#else
nhUse(defres);
#endif
getlin(prompt, outbuf);
if (!*outbuf || *outbuf == '\033')
return NULL;
/* strip leading and trailing spaces, condense internal sequences */
(void) mungspaces(outbuf);
if (strlen(outbuf) >= PL_PSIZ)
outbuf[PL_PSIZ - 1] = '\0';
return outbuf;
}
/* historical note: this returns a monster pointer because it used to /* historical note: this returns a monster pointer because it used to
allocate a new bigger block of memory to hold the monster and its name */ allocate a new bigger block of memory to hold the monster and its name */
struct monst * struct monst *
@@ -1290,17 +1319,10 @@ do_mgivenname(void)
/* special case similar to the one in lookat() */ /* special case similar to the one in lookat() */
Sprintf(qbuf, "What do you want to call %s?", Sprintf(qbuf, "What do you want to call %s?",
distant_monnam(mtmp, ARTICLE_THE, monnambuf)); distant_monnam(mtmp, ARTICLE_THE, monnambuf));
buf[0] = '\0'; /* use getlin() to get a name string from the player */
#ifdef EDIT_GETLIN if (!name_from_player(buf, qbuf,
/* if there's an existing name, make it be the default answer */ has_mgivenname(mtmp) ? MGIVENNAME(mtmp) : NULL))
if (has_mgivenname(mtmp))
Strcpy(buf, MGIVENNAME(mtmp));
#endif
getlin(qbuf, buf);
if (!*buf || *buf == '\033')
return; return;
/* strip leading and trailing spaces; unnames monster if all spaces */
(void) mungspaces(buf);
/* Unique monsters have their own specific names or titles. /* Unique monsters have their own specific names or titles.
* Shopkeepers, temple priests and other minions use alternate * Shopkeepers, temple priests and other minions use alternate
@@ -1348,17 +1370,9 @@ do_oname(struct obj *obj)
Sprintf(qbuf, "What do you want to name %s ", Sprintf(qbuf, "What do you want to name %s ",
is_plural(obj) ? "these" : "this"); is_plural(obj) ? "these" : "this");
(void) safe_qbuf(qbuf, qbuf, "?", obj, xname, simpleonames, "item"); (void) safe_qbuf(qbuf, qbuf, "?", obj, xname, simpleonames, "item");
buf[0] = '\0'; /* use getlin() to get a name string from the player */
#ifdef EDIT_GETLIN if (!name_from_player(buf, qbuf, safe_oname(obj)))
/* if there's an existing name, make it be the default answer */
if (has_oname(obj))
Strcpy(buf, ONAME(obj));
#endif
getlin(qbuf, buf);
if (!*buf || *buf == '\033')
return; return;
/* strip leading and trailing spaces; unnames item if all spaces */
(void) mungspaces(buf);
/* /*
* We don't violate illiteracy conduct here, although it is * We don't violate illiteracy conduct here, although it is
@@ -1701,14 +1715,8 @@ docall(struct obj *obj)
docall_xname, simpleonames, "thing"); docall_xname, simpleonames, "thing");
/* pointer to old name */ /* pointer to old name */
str1 = &(objects[obj->otyp].oc_uname); str1 = &(objects[obj->otyp].oc_uname);
buf[0] = '\0'; /* use getlin() to get a name string from the player */
#ifdef EDIT_GETLIN if (!name_from_player(buf, qbuf, *str1))
/* if there's an existing name, make it be the default answer */
if (*str1)
Strcpy(buf, *str1);
#endif
getlin(qbuf, buf);
if (!*buf || *buf == '\033')
return; return;
/* clear old name */ /* clear old name */

View File

@@ -1,4 +1,4 @@
/* NetHack 3.7 invent.c $NHDT-Date: 1661240719 2022/08/23 07:45:19 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.424 $ */ /* NetHack 3.7 invent.c $NHDT-Date: 1672827802 2023/01/04 10:23:22 $ $NHDT-Branch: naming-overflow-fix $:$NHDT-Revision: 1.439 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Derek S. Ray, 2015. */ /*-Copyright (c) Derek S. Ray, 2015. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -2567,17 +2567,21 @@ prinv(const char *prefix, struct obj *obj, long quan)
DISABLE_WARNING_FORMAT_NONLITERAL DISABLE_WARNING_FORMAT_NONLITERAL
char * char *
xprname(struct obj *obj, xprname(
const char *txt, /* text to print instead of obj */ struct obj *obj,
char let, /* inventory letter */ const char *txt, /* text to print instead of obj */
boolean dot, /* append period; (dot && cost => Iu) */ char let, /* inventory letter */
long cost, /* cost (for inventory of unpaid or expended items) */ boolean dot, /* append period; (dot && cost => Iu) */
long quan) /* if non-0, print this quantity, not obj->quan */ long cost, /* cost (for inventory of unpaid or expended items) */
long quan) /* if non-0, print this quantity, not obj->quan */
{ {
static char li[BUFSZ]; static char li[BUFSZ];
char suffix[80]; /* plenty of room for count and hallucinatory currency */
int sfxlen, txtlen; /* signed int for %*s formatting */
const char *fmt;
boolean use_invlet = (flags.invlet_constant boolean use_invlet = (flags.invlet_constant
&& let != CONTAINED_SYM && let != HANDS_SYM); && let != CONTAINED_SYM && let != HANDS_SYM);
long savequan = 0; long savequan = 0L;
if (quan && obj) { if (quan && obj) {
savequan = obj->quan; savequan = obj->quan;
@@ -2589,18 +2593,33 @@ xprname(struct obj *obj,
* * Then obj == null and we are printing a total amount. * * Then obj == null and we are printing a total amount.
* > Then the object is contained and doesn't have an inventory letter. * > Then the object is contained and doesn't have an inventory letter.
*/ */
if (cost != 0 || let == '*') { fmt = "%c - %.*s%s";
if (!txt)
txt = doname(obj);
txtlen = (int) strlen(txt);
if (cost != 0L || let == '*') {
/* if dot is true, we're doing Iu, otherwise Ix */ /* if dot is true, we're doing Iu, otherwise Ix */
Sprintf(li, if (dot && use_invlet)
iflags.menu_tab_sep ? "%c - %s\t%6ld %s" let = obj->invlet;
: "%c - %-45s %6ld %s", Sprintf(suffix, "%c%6ld %.50s", iflags.menu_tab_sep ? '\t' : ' ',
(dot && use_invlet ? obj->invlet : let), cost, currency(cost));
(txt ? txt : doname(obj)), cost, currency(cost)); if (!iflags.menu_tab_sep) {
fmt = "%c - %-45.*s%s";
if (txtlen < 45)
txtlen = 45;
}
} else { } else {
/* ordinary inventory display or pickup message */ /* ordinary inventory display or pickup message */
Sprintf(li, "%c - %s%s", (use_invlet ? obj->invlet : let), if (use_invlet)
(txt ? txt : doname(obj)), (dot ? "." : "")); let = obj->invlet;
Strcpy(suffix, dot ? "." : "");
} }
sfxlen = (int) strlen(suffix);
if (txtlen > BUFSZ - 1 - (4 + sfxlen)) /* 4: "c - " prefix */
txtlen = BUFSZ - 1 - (4 + sfxlen);
Sprintf(li, fmt, let, txtlen, txt, suffix);
if (savequan) if (savequan)
obj->quan = savequan; obj->quan = savequan;

View File

@@ -1,4 +1,4 @@
/* NetHack 3.7 o_init.c $NHDT-Date: 1646950588 2022/03/10 22:16:28 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.56 $ */ /* NetHack 3.7 o_init.c $NHDT-Date: 1672829455 2023/01/04 10:50:55 $ $NHDT-Branch: naming-overflow-fix $:$NHDT-Revision: 1.68 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2011. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -11,6 +11,7 @@ static void shuffle_all(void);
static int QSORTCALLBACK discovered_cmp(const genericptr, const genericptr); static int QSORTCALLBACK discovered_cmp(const genericptr, const genericptr);
static char *sortloot_descr(int, char *); static char *sortloot_descr(int, char *);
static char *disco_typename(int); static char *disco_typename(int);
static void disco_append_typename(char *, int);
static char *oclass_to_name(char, char *); static char *oclass_to_name(char, char *);
#ifdef TILES_IN_GLYPHMAP #ifdef TILES_IN_GLYPHMAP
@@ -651,6 +652,30 @@ disco_typename(int otyp)
return result; return result;
} }
/* append typename(dis) to buf[], possibly truncating in the process */
static void
disco_append_typename(char *buf, int dis)
{
unsigned len = (unsigned) strlen(buf);
char *p, *typnm = disco_typename(dis);
if (len + (unsigned) strlen(typnm) < BUFSZ) {
/* ordinary */
Strcat(buf, typnm);
} else if ((p = strrchr(typnm, '(')) != 0
&& p > typnm && p[-1] == ' ' && strchr(p, ')') != 0) {
/* typename() returned "really long user-applied name (actual type)"
and we want to truncate from "really long user-applied name" while
keeping " (actual type)" intact */
--p; /* back up to space in front of open paren */
(void) strncat(buf, typnm, BUFSZ - 1 - (len + (unsigned) strlen(p)));
Strcat(buf, p);
} else {
/* unexpected; just truncate from end of typename */
(void) strncat(buf, typnm, BUFSZ - 1 - len);
}
}
/* the #known command - show discovered object types */ /* the #known command - show discovered object types */
int int
dodiscovered(void) /* free after Robert Viduya */ dodiscovered(void) /* free after Robert Viduya */
@@ -734,7 +759,7 @@ dodiscovered(void) /* free after Robert Viduya */
Strcpy(buf, objects[dis].oc_pre_discovered ? "* " : " "); Strcpy(buf, objects[dis].oc_pre_discovered ? "* " : " ");
if (lootsort) if (lootsort)
(void) sortloot_descr(dis, &buf[2]); (void) sortloot_descr(dis, &buf[2]);
Strcat(buf, disco_typename(dis)); disco_append_typename(buf, dis);
if (!alphabetized && !lootsort) if (!alphabetized && !lootsort)
putstr(tmpwin, 0, buf); putstr(tmpwin, 0, buf);
@@ -966,7 +991,7 @@ doclassdisco(void)
Strcpy(buf, objects[dis].oc_pre_discovered ? "* " : " "); Strcpy(buf, objects[dis].oc_pre_discovered ? "* " : " ");
if (lootsort) if (lootsort)
(void) sortloot_descr(dis, &buf[2]); (void) sortloot_descr(dis, &buf[2]);
Strcat(buf, disco_typename(dis)); disco_append_typename(buf, dis);
if (!alphabetized && !lootsort) if (!alphabetized && !lootsort)
putstr(tmpwin, 0, buf); putstr(tmpwin, 0, buf);

View File

@@ -1,4 +1,4 @@
/* NetHack 3.7 objnam.c $NHDT-Date: 1654557302 2022/06/06 23:15:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.368 $ */ /* NetHack 3.7 objnam.c $NHDT-Date: 1672829441 2023/01/04 10:50:41 $ $NHDT-Branch: naming-overflow-fix $:$NHDT-Revision: 1.386 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2011. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -35,6 +35,7 @@ struct _readobjnam_data {
static char *strprepend(char *, const char *); static char *strprepend(char *, const char *);
static char *nextobuf(void); static char *nextobuf(void);
static void releaseobuf(char *); static void releaseobuf(char *);
static void xcalled(char *, int, const char *, const char *);
static char *xname_flags(struct obj *, unsigned); static char *xname_flags(struct obj *, unsigned);
static char *minimal_xname(struct obj *); static char *minimal_xname(struct obj *);
static void add_erosion_words(struct obj *, char *); static void add_erosion_words(struct obj *, char *);
@@ -187,6 +188,7 @@ obj_typename(int otyp)
if (!actualn) if (!actualn)
actualn = (otyp > 0 && otyp < MAXOCLASSES) ? "generic" : "object?"; actualn = (otyp > 0 && otyp < MAXOCLASSES) ? "generic" : "object?";
buf[0] = '\0'; /* redundant */
switch (ocl->oc_class) { switch (ocl->oc_class) {
case COIN_CLASS: case COIN_CLASS:
Strcpy(buf, "coin"); Strcpy(buf, "coin");
@@ -217,7 +219,7 @@ obj_typename(int otyp)
else else
Strcpy(buf, "amulet"); Strcpy(buf, "amulet");
if (un) if (un)
Sprintf(eos(buf), " called %s", un); xcalled(buf, BUFSZ - (dn ? (int) strlen(dn) + 3 : 0), "", un);
if (dn) if (dn)
Sprintf(eos(buf), " (%s)", dn); Sprintf(eos(buf), " (%s)", dn);
return buf; return buf;
@@ -226,8 +228,8 @@ obj_typename(int otyp)
Strcpy(buf, actualn); Strcpy(buf, actualn);
if (GemStone(otyp)) if (GemStone(otyp))
Strcat(buf, " stone"); Strcat(buf, " stone");
if (un) if (un) /* 3: length of " (" + ")" which will enclose 'dn' */
Sprintf(eos(buf), " called %s", un); xcalled(buf, BUFSZ - (dn ? (int) strlen(dn) + 3 : 0), "", un);
if (dn) if (dn)
Sprintf(eos(buf), " (%s)", dn); Sprintf(eos(buf), " (%s)", dn);
} else { } else {
@@ -236,7 +238,7 @@ obj_typename(int otyp)
Strcat(buf, Strcat(buf,
(ocl->oc_material == MINERAL) ? " stone" : " gem"); (ocl->oc_material == MINERAL) ? " stone" : " gem");
if (un) if (un)
Sprintf(eos(buf), " called %s", un); xcalled(buf, BUFSZ, "", un);
} }
return buf; return buf;
} }
@@ -247,8 +249,8 @@ obj_typename(int otyp)
else else
Sprintf(eos(buf), " of %s", actualn); Sprintf(eos(buf), " of %s", actualn);
} }
if (un) if (un) /* 3: length of " (" + ")" which will enclose 'dn' */
Sprintf(eos(buf), " called %s", un); xcalled(buf, BUFSZ - (dn ? (int) strlen(dn) + 3 : 0), "", un);
if (dn) if (dn)
Sprintf(eos(buf), " (%s)", dn); Sprintf(eos(buf), " (%s)", dn);
return buf; return buf;
@@ -498,6 +500,24 @@ reorder_fruit(boolean forward)
} }
} }
/* add "<pfx> called <sfx>" to end of buf, truncating if necessary */
static void
xcalled(
char *buf, /* eos(obuf) or eos(&obuf[PREFIX]) */
int siz, /* BUFSZ or BUFSZ-PREFIX */
const char *pfx, /* usually class string, sometimes more specific */
const char *sfx) /* user assigned type name */
{
int bufsiz = siz - 1 - (int) strlen(buf),
pfxlen = (int) (strlen(pfx) + sizeof " called " - sizeof "");
if (pfxlen > bufsiz)
panic("xcalled: not enough room for prefix (%d > %d)",
pfxlen, bufsiz);
Sprintf(eos(buf), "%s called %.*s", pfx, bufsiz - pfxlen, sfx);
}
char * char *
xname(struct obj* obj) xname(struct obj* obj)
{ {
@@ -530,7 +550,7 @@ xname_flags(
for those; pacify static analyzer without resorting to impossible() */ for those; pacify static analyzer without resorting to impossible() */
if (!actualn) if (!actualn)
actualn = (typ > 0 && typ < MAXOCLASSES) ? "generic" : "object?"; actualn = (typ > 0 && typ < MAXOCLASSES) ? "generic" : "object?";
/* As of 3.6.2: this used to be part of 'dn's initialization, but it /* 3.6.2: this used to be part of 'dn's initialization, but it
needs to come after possibly overriding 'actualn' */ needs to come after possibly overriding 'actualn' */
if (!dn) if (!dn)
dn = actualn; dn = actualn;
@@ -592,7 +612,7 @@ xname_flags(
else if (nn) else if (nn)
Strcpy(buf, actualn); Strcpy(buf, actualn);
else if (un) else if (un)
Sprintf(buf, "amulet called %s", un); xcalled(buf, BUFSZ - PREFIX, "amulet", un);
else else
Sprintf(buf, "%s amulet", dn); Sprintf(buf, "%s amulet", dn);
break; break;
@@ -611,11 +631,9 @@ xname_flags(
Strcat(buf, dn); Strcat(buf, dn);
else if (nn) else if (nn)
Strcat(buf, actualn); Strcat(buf, actualn);
else if (un) { else if (un)
Strcat(buf, dn); xcalled(buf, BUFSZ - PREFIX, dn, un);
Strcat(buf, " called "); else
Strcat(buf, un);
} else
Strcat(buf, dn); Strcat(buf, dn);
if (typ == FIGURINE && omndx != NON_PM) { if (typ == FIGURINE && omndx != NON_PM) {
@@ -650,7 +668,7 @@ xname_flags(
if (nn) if (nn)
Strcat(buf, actualn); Strcat(buf, actualn);
else if (un) else if (un)
Sprintf(eos(buf), "%s called %s", armor_simple_name(obj), un); xcalled(buf, BUFSZ - PREFIX, armor_simple_name(obj), un);
else else
Strcat(buf, dn); Strcat(buf, dn);
break; break;
@@ -750,8 +768,7 @@ xname_flags(
} }
Strcat(buf, actualn); Strcat(buf, actualn);
} else { } else {
Strcat(buf, " called "); xcalled(buf, BUFSZ - PREFIX, "", un);
Strcat(buf, un);
} }
} else { } else {
Strcat(buf, dn); Strcat(buf, dn);
@@ -766,8 +783,7 @@ xname_flags(
Strcat(buf, " of "); Strcat(buf, " of ");
Strcat(buf, actualn); Strcat(buf, actualn);
} else if (un) { } else if (un) {
Strcat(buf, " called "); xcalled(buf, BUFSZ - PREFIX, "", un);
Strcat(buf, un);
} else if (ocl->oc_magic) { } else if (ocl->oc_magic) {
Strcat(buf, " labeled "); Strcat(buf, " labeled ");
Strcat(buf, dn); Strcat(buf, dn);
@@ -782,7 +798,7 @@ xname_flags(
else if (nn) else if (nn)
Sprintf(buf, "wand of %s", actualn); Sprintf(buf, "wand of %s", actualn);
else if (un) else if (un)
Sprintf(buf, "wand called %s", un); xcalled(buf, BUFSZ - PREFIX, "wand", un);
else else
Sprintf(buf, "%s wand", dn); Sprintf(buf, "%s wand", dn);
break; break;
@@ -793,7 +809,7 @@ xname_flags(
else if (nn) else if (nn)
Strcpy(buf, actualn); Strcpy(buf, actualn);
else if (un) else if (un)
Sprintf(buf, "novel called %s", un); xcalled(buf, BUFSZ - PREFIX, "novel", un);
else else
Sprintf(buf, "%s book", dn); Sprintf(buf, "%s book", dn);
break; break;
@@ -805,7 +821,7 @@ xname_flags(
Strcpy(buf, "spellbook of "); Strcpy(buf, "spellbook of ");
Strcat(buf, actualn); Strcat(buf, actualn);
} else if (un) { } else if (un) {
Sprintf(buf, "spellbook called %s", un); xcalled(buf, BUFSZ - PREFIX, "spellbook", un);
} else } else
Sprintf(buf, "%s spellbook", dn); Sprintf(buf, "%s spellbook", dn);
break; break;
@@ -815,7 +831,7 @@ xname_flags(
else if (nn) else if (nn)
Sprintf(buf, "ring of %s", actualn); Sprintf(buf, "ring of %s", actualn);
else if (un) else if (un)
Sprintf(buf, "ring called %s", un); xcalled(buf, BUFSZ - PREFIX, "ring", un);
else else
Sprintf(buf, "%s ring", dn); Sprintf(buf, "%s ring", dn);
break; break;
@@ -826,7 +842,7 @@ xname_flags(
Strcpy(buf, rock); Strcpy(buf, rock);
} else if (!nn) { } else if (!nn) {
if (un) if (un)
Sprintf(buf, "%s called %s", rock, un); xcalled(buf, BUFSZ - PREFIX, rock, un);
else else
Sprintf(buf, "%s %s", dn, rock); Sprintf(buf, "%s %s", dn, rock);
} else { } else {
@@ -879,7 +895,8 @@ xname_flags(
Strcat(buf, " named "); Strcat(buf, " named ");
nameit: nameit:
obufp = eos(buf); obufp = eos(buf);
Strcat(buf, ONAME(obj)); (void) strncat(buf, ONAME(obj),
BUFSZ - 1 - PREFIX - (unsigned) strlen(buf));
/* downcase "The" in "<quest-artifact-item> named The ..." */ /* downcase "The" in "<quest-artifact-item> named The ..." */
if (obj->oartifact && !strncmp(obufp, "The ", 4)) if (obj->oartifact && !strncmp(obufp, "The ", 4))
*obufp = lowc(*obufp); /* = 't'; */ *obufp = lowc(*obufp); /* = 't'; */
@@ -1866,7 +1883,7 @@ just_an(char *outbuf, const char *str)
} }
char * char *
an(const char* str) an(const char *str)
{ {
char *buf = nextobuf(); char *buf = nextobuf();
@@ -1875,11 +1892,11 @@ an(const char* str)
return strcpy(buf, "an []"); return strcpy(buf, "an []");
} }
(void) just_an(buf, str); (void) just_an(buf, str);
return strcat(buf, str); return strncat(buf, str, BUFSZ - 1 - Strlen(buf));
} }
char * char *
An(const char* str) An(const char *str)
{ {
char *tmp = an(str); char *tmp = an(str);
@@ -1950,9 +1967,7 @@ the(const char* str)
Strcpy(buf, "the "); Strcpy(buf, "the ");
else else
buf[0] = '\0'; buf[0] = '\0';
Strcat(buf, str); return strncat(buf, str, BUFSZ - 1 - Strlen(buf));
return buf;
} }
char * char *
@@ -3846,10 +3861,12 @@ readobjnam_postparse1(struct _readobjnam_data *d)
*/ */
if ((d->p = strstri(d->bp, " named ")) != 0) { if ((d->p = strstri(d->bp, " named ")) != 0) {
*d->p = 0; *d->p = 0;
/* note: if 'name' is too long, oname() will truncate it */
d->name = d->p + 7; d->name = d->p + 7;
} }
if ((d->p = strstri(d->bp, " called ")) != 0) { if ((d->p = strstri(d->bp, " called ")) != 0) {
*d->p = 0; *d->p = 0;
/* note: if 'un' is too long, obj lookup just won't match anything */
d->un = d->p + 8; d->un = d->p + 8;
/* "helmet called telepathy" is not "helmet" (a specific type) /* "helmet called telepathy" is not "helmet" (a specific type)
* "shield called reflection" is not "shield" (a general type) * "shield called reflection" is not "shield" (a general type)