improved regexp handling
If regex_compile() fails, free the regexp before doing anything else in case failure reason is "out of memory". Feedback to the user is highly likely to panic or crash after memory runs out; this should let the regex failure message be issued and the game continue. User sound regular expressions were never freed. This frees them when FREE_ALL_MEMORY is enabled.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 extern.h $NHDT-Date: 1588798973 2020/05/06 21:02:53 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.842 $ */
|
||||
/* NetHack 3.6 extern.h $NHDT-Date: 1590263447 2020/05/23 19:50:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.843 $ */
|
||||
/* Copyright (c) Steve Creps, 1988. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -2459,6 +2459,7 @@ E int NDECL(tiphat);
|
||||
#ifdef USER_SOUNDS
|
||||
E int FDECL(add_sound_mapping, (const char *));
|
||||
E void FDECL(play_sound_for_message, (const char *));
|
||||
E void NDECL(release_sound_mappings);
|
||||
#endif
|
||||
|
||||
/* ### sp_lev.c ### */
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.7 files.c $NHDT-Date: 1589580856 2020/05/15 22:14:16 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.313 $ */
|
||||
/* NetHack 3.7 files.c $NHDT-Date: 1590263451 2020/05/23 19:50:51 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.314 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Derek S. Ray, 2015. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -120,7 +120,7 @@ extern char *FDECL(translate_path_variables, (const char *, char *));
|
||||
#endif
|
||||
|
||||
#ifdef USER_SOUNDS
|
||||
extern char *sounddir;
|
||||
extern char *sounddir; /* defined in sounds.c */
|
||||
#endif
|
||||
|
||||
#if defined(UNIX) && defined(QT_GRAPHICS)
|
||||
@@ -2885,6 +2885,8 @@ char *origbuf;
|
||||
#endif /*AMIGA*/
|
||||
#ifdef USER_SOUNDS
|
||||
} else if (match_varname(buf, "SOUNDDIR", 8)) {
|
||||
if (sounddir)
|
||||
free((genericptr_t) sounddir);
|
||||
sounddir = dupstr(bufp);
|
||||
} else if (match_varname(buf, "SOUND", 5)) {
|
||||
add_sound_mapping(bufp);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.7 options.c $NHDT-Date: 1589326675 2020/05/12 23:37:55 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.464 $ */
|
||||
/* NetHack 3.7 options.c $NHDT-Date: 1590263453 2020/05/23 19:50:53 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.465 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Michael Allison, 2008. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -5447,7 +5447,7 @@ handler_menu_colors(VOID_ARGS)
|
||||
if (*mcbuf == '\033')
|
||||
goto menucolors_done;
|
||||
if (*mcbuf
|
||||
&& test_regex_pattern(mcbuf, (const char *)0)
|
||||
&& test_regex_pattern(mcbuf, "MENUCOLORS regex")
|
||||
&& (mcclr = query_color((char *) 0)) != -1
|
||||
&& (mcattr = query_attr((char *) 0)) != -1
|
||||
&& !add_menu_coloring_parsed(mcbuf, mcclr, mcattr)) {
|
||||
@@ -5529,7 +5529,7 @@ handler_msgtype(VOID_ARGS)
|
||||
if (*mtbuf == '\033')
|
||||
return TRUE;
|
||||
if (*mtbuf
|
||||
&& test_regex_pattern(mtbuf, (const char *)0)
|
||||
&& test_regex_pattern(mtbuf, "MSGTYPE regex")
|
||||
&& (mttyp = query_msgtype()) != -1
|
||||
&& !msgtype_add(mttyp, mtbuf)) {
|
||||
pline("Error adding the message type.");
|
||||
@@ -6671,16 +6671,20 @@ msgtype_add(typ, pattern)
|
||||
int typ;
|
||||
char *pattern;
|
||||
{
|
||||
static const char *re_error = "MSGTYPE regex error";
|
||||
struct plinemsg_type *tmp = (struct plinemsg_type *) alloc(sizeof *tmp);
|
||||
|
||||
tmp->msgtype = typ;
|
||||
tmp->regex = regex_init();
|
||||
/* test_regex_pattern() has already validated this regexp but parsing
|
||||
it again could conceivably run out of memory */
|
||||
if (!regex_compile(pattern, tmp->regex)) {
|
||||
static const char *re_error = "MSGTYPE regex error";
|
||||
const char *re_error_desc = regex_error_desc(tmp->regex);
|
||||
|
||||
config_error_add("%s: %s", re_error, regex_error_desc(tmp->regex));
|
||||
/* free first in case reason for failure was insufficient memory */
|
||||
regex_free(tmp->regex);
|
||||
free((genericptr_t) tmp);
|
||||
config_error_add("%s: %s", re_error, re_error_desc);
|
||||
return FALSE;
|
||||
}
|
||||
tmp->pattern = dupstr(pattern);
|
||||
@@ -6805,30 +6809,40 @@ char *str;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* parse 'str' as a regular expression to check whether it's valid;
|
||||
compiled regexp gets thrown away regardless of the outcome */
|
||||
static boolean
|
||||
test_regex_pattern(str, errmsg)
|
||||
const char *str;
|
||||
const char *errmsg;
|
||||
{
|
||||
static const char re_error[] = "Regex error";
|
||||
static const char def_errmsg[] = "NHregex error";
|
||||
struct nhregex *match;
|
||||
boolean retval = TRUE;
|
||||
const char *re_error_desc;
|
||||
boolean retval;
|
||||
|
||||
if (!str)
|
||||
return FALSE;
|
||||
if (!errmsg)
|
||||
errmsg = def_errmsg;
|
||||
|
||||
match = regex_init();
|
||||
if (!match) {
|
||||
config_error_add("NHregex error");
|
||||
config_error_add("%s", errmsg);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!regex_compile(str, match)) {
|
||||
config_error_add("%s: %s", errmsg ? errmsg : re_error,
|
||||
regex_error_desc(match));
|
||||
retval = FALSE;
|
||||
}
|
||||
retval = regex_compile(str, match);
|
||||
/* get potential error message before freeing regexp and free regexp
|
||||
before issuing message in case the error is "ran out of memory"
|
||||
since message delivery might need to allocate some memory */
|
||||
re_error_desc = !retval ? regex_error_desc(match) : 0;
|
||||
/* discard regexp; caller will re-parse it after validating other stuff */
|
||||
regex_free(match);
|
||||
/* if returning failure, tell player */
|
||||
if (!retval)
|
||||
config_error_add("%s: %s", errmsg, re_error_desc);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
@@ -6844,19 +6858,23 @@ int c, a;
|
||||
return FALSE;
|
||||
tmp = (struct menucoloring *) alloc(sizeof *tmp);
|
||||
tmp->match = regex_init();
|
||||
/* test_regex_pattern() has already validated this regexp but parsing
|
||||
it again could conceivably run out of memory */
|
||||
if (!regex_compile(str, tmp->match)) {
|
||||
config_error_add("%s: %s", re_error, regex_error_desc(tmp->match));
|
||||
const char *re_error_desc = regex_error_desc(tmp->match);
|
||||
|
||||
/* free first in case reason for regcomp failure was out-of-memory */
|
||||
regex_free(tmp->match);
|
||||
free(tmp);
|
||||
free((genericptr_t) tmp);
|
||||
config_error_add("%s: %s", re_error, re_error_desc);
|
||||
return FALSE;
|
||||
} else {
|
||||
tmp->next = g.menu_colorings;
|
||||
tmp->origstr = dupstr(str);
|
||||
tmp->color = c;
|
||||
tmp->attr = a;
|
||||
g.menu_colorings = tmp;
|
||||
return TRUE;
|
||||
}
|
||||
tmp->next = g.menu_colorings;
|
||||
tmp->origstr = dupstr(str);
|
||||
tmp->color = c;
|
||||
tmp->attr = a;
|
||||
g.menu_colorings = tmp;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* parse '"regex_string"=color&attr' and add it to menucoloring */
|
||||
@@ -6935,6 +6953,7 @@ free_menu_coloring()
|
||||
free((genericptr_t) tmp->origstr);
|
||||
free((genericptr_t) tmp);
|
||||
}
|
||||
g.menu_colorings = (struct menucoloring *) 0;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -7752,13 +7771,14 @@ const char *mapping;
|
||||
ape = (struct autopickup_exception *) alloc(sizeof *ape);
|
||||
ape->regex = regex_init();
|
||||
if (!regex_compile(text, ape->regex)) {
|
||||
config_error_add("%s: %s", APE_regex_error,
|
||||
regex_error_desc(ape->regex));
|
||||
const char *re_error_desc = regex_error_desc(ape->regex);
|
||||
|
||||
/* free first in case reason for failure was insufficient memory */
|
||||
regex_free(ape->regex);
|
||||
free((genericptr_t) ape);
|
||||
config_error_add("%s: %s", APE_regex_error, re_error_desc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ape->pattern = dupstr(text);
|
||||
ape->grab = grab;
|
||||
ape->next = g.apelist;
|
||||
@@ -7796,10 +7816,10 @@ free_autopickup_exceptions()
|
||||
struct autopickup_exception *ape;
|
||||
|
||||
while ((ape = g.apelist) != 0) {
|
||||
regex_free(ape->regex);
|
||||
free((genericptr_t) ape->pattern);
|
||||
g.apelist = ape->next;
|
||||
free((genericptr_t) ape);
|
||||
free((genericptr_t) ape->pattern);
|
||||
regex_free(ape->regex);
|
||||
g.apelist = ape->next;
|
||||
free((genericptr_t) ape);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 save.c $NHDT-Date: 1581886866 2020/02/16 21:01:06 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.153 $ */
|
||||
/* NetHack 3.6 save.c $NHDT-Date: 1590263454 2020/05/23 19:50:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.158 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Michael Allison, 2009. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -1058,7 +1058,8 @@ NHFILE *nhfp;
|
||||
if (nhfp->structlevel) {
|
||||
bufoff(nhfp->fd);
|
||||
/* bwrite() before bufon() uses plain write() */
|
||||
bwrite(nhfp->fd, (genericptr_t) &sfsaveinfo, (unsigned) sizeof sfsaveinfo);
|
||||
bwrite(nhfp->fd, (genericptr_t) &sfsaveinfo,
|
||||
(unsigned) sizeof sfsaveinfo);
|
||||
bufon(nhfp->fd);
|
||||
}
|
||||
return;
|
||||
@@ -1149,7 +1150,11 @@ freedynamicdata()
|
||||
/* miscellaneous */
|
||||
/* free_pickinv_cache(); -- now done from really_done()... */
|
||||
free_symsets();
|
||||
#ifdef USER_SOUNDS
|
||||
release_sound_mappings();
|
||||
#endif
|
||||
#endif /* FREE_ALL_MEMORY */
|
||||
|
||||
if (VIA_WINDOWPORT())
|
||||
status_finish();
|
||||
#ifdef DUMPLOG
|
||||
|
||||
36
src/sounds.c
36
src/sounds.c
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 sounds.c $NHDT-Date: 1582061574 2020/02/18 21:32:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.96 $ */
|
||||
/* NetHack 3.6 sounds.c $NHDT-Date: 1590263455 2020/05/23 19:50:55 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.97 $ */
|
||||
/* Copyright (c) 1989 Janet Walz, Mike Threepoint */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -1269,7 +1269,7 @@ typedef struct audio_mapping_rec {
|
||||
|
||||
static audio_mapping *soundmap = 0;
|
||||
|
||||
char *sounddir = ".";
|
||||
char *sounddir = 0; /* set in files.c */
|
||||
|
||||
/* adds a sound file mapping, returns 0 on failure, 1 on success */
|
||||
int
|
||||
@@ -1285,24 +1285,29 @@ const char *mapping;
|
||||
filename, &volume) == 3) {
|
||||
audio_mapping *new_map;
|
||||
|
||||
if (strlen(sounddir) + strlen(filename) > 254) {
|
||||
if (!sounddir)
|
||||
sounddir = dupstr(".");
|
||||
|
||||
if (strlen(sounddir) + 1 + strlen(filename) >= sizeof filespec) {
|
||||
raw_print("sound file name too long");
|
||||
return 0;
|
||||
}
|
||||
Sprintf(filespec, "%s/%s", sounddir, filename);
|
||||
|
||||
if (can_read_file(filespec)) {
|
||||
new_map = (audio_mapping *) alloc(sizeof(audio_mapping));
|
||||
new_map = (audio_mapping *) alloc(sizeof *new_map);
|
||||
new_map->regex = regex_init();
|
||||
new_map->filename = dupstr(filespec);
|
||||
new_map->volume = volume;
|
||||
new_map->next = soundmap;
|
||||
|
||||
if (!regex_compile(text, new_map->regex)) {
|
||||
raw_print(regex_error_desc(new_map->regex));
|
||||
const char *re_error_desc = regex_error_desc(new_map->regex);
|
||||
|
||||
regex_free(new_map->regex);
|
||||
free(new_map->filename);
|
||||
free(new_map);
|
||||
free((genericptr_t) new_map->filename);
|
||||
free((genericptr_t) new_map);
|
||||
raw_print(re_error_desc);
|
||||
return 0;
|
||||
} else {
|
||||
soundmap = new_map;
|
||||
@@ -1334,6 +1339,23 @@ const char *msg;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
release_sound_mappings()
|
||||
{
|
||||
audio_mapping *nextsound = 0;
|
||||
|
||||
while (soundmap) {
|
||||
nextsound = soundmap->next;
|
||||
regex_free(soundmap->regex);
|
||||
free((genericptr_t) soundmap->filename);
|
||||
free((genericptr_t) soundmap);
|
||||
soundmap = nextsound;
|
||||
}
|
||||
|
||||
if (sounddir)
|
||||
free((genericptr_t) sounddir), sounddir = 0;
|
||||
}
|
||||
|
||||
#endif /* USER_SOUNDS */
|
||||
|
||||
/*sounds.c*/
|
||||
|
||||
Reference in New Issue
Block a user