[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [bug-gawk] Segfault on invalid program
From: |
arnold |
Subject: |
Re: [bug-gawk] Segfault on invalid program |
Date: |
Wed, 17 Apr 2019 00:54:49 -0600 |
User-agent: |
Heirloom mailx 12.5 7/5/10 |
Hi.
The fix for the segfault is below.
Thanks,
Arnold
Steve Kemp <address@hidden> wrote:
> A couple of years ago I went through a phase
> of fuzz-testing gawk.
>
> Having seen the recent announcement of GNU
> awk 5.0 I gave it a go, but at least one issue
> I reported to debian remains unfixed:
>
> https://bugs.debian.org/816277
>
> From the bug-report this is my sample program:
>
> gawk -e "for (i = ) in foo bar baz"
>
> Simple patch attached to the bug-report, though
> it might not be the best. I appreciate invalid
> programs are invalid, but I think a segfault is
> something we should prevent.
>
> Steve
> --
------------------------------------------
diff --git a/awk.h b/awk.h
index 2d87d5af..19a5eb5f 100644
--- a/awk.h
+++ b/awk.h
@@ -1116,6 +1116,7 @@ extern NODE *Null_field;
extern NODE **fields_arr;
extern int sourceline;
extern char *source;
+extern int errcount;
extern int (*interpret)(INSTRUCTION *); /* interpreter routine */
extern NODE *(*make_number)(double); /* double instead of AWKNUM on purpose
*/
extern NODE *(*str2number)(NODE *);
diff --git a/awkgram.y b/awkgram.y
index 87570dfa..08bd096e 100644
--- a/awkgram.y
+++ b/awkgram.y
@@ -154,7 +154,7 @@ static int continue_allowed; /* kludge for continue
*/
static char *tokstart = NULL;
static char *tok = NULL;
static char *tokend;
-static int errcount = 0;
+int errcount = 0;
extern char *source;
extern int sourceline;
diff --git a/command.y b/command.y
index 1af3ad12..6d2c9ef2 100644
--- a/command.y
+++ b/command.y
@@ -44,7 +44,7 @@ static bool want_nodeval = false;
static int cmd_idx = -1; /* index of current command in cmd
table */
static int repeat_idx = -1; /* index of last repeatable command in
command table */
static CMDARG *arg_list = NULL; /* list of arguments */
-static long errcount = 0;
+static long dbg_errcount = 0;
static char *lexptr_begin = NULL;
static bool in_commands = false;
static int num_dim;
@@ -128,7 +128,7 @@ line
: nls
| command nls
{
- if (errcount == 0 && cmd_idx >= 0) {
+ if (dbg_errcount == 0 && cmd_idx >= 0) {
Func_cmd cmdfunc;
bool terminate = false;
CMDARG *args;
@@ -217,7 +217,7 @@ set_want_nodeval
eval_prologue
: D_EVAL set_want_nodeval opt_param_list nls
{
- if (errcount == 0) {
+ if (dbg_errcount == 0) {
/* don't free arg_list; passed on to statement_list
* non-terminal (empty rule action). See below.
*/
@@ -335,7 +335,7 @@ command
if ($2 != NULL)
num = $2->a_int;
- if (errcount != 0)
+ if (dbg_errcount != 0)
;
else if (in_commands)
yyerror(_("Can't use command `commands' for
breakpoint/watchpoint commands"));
@@ -1017,7 +1017,7 @@ yyerror(const char *mesg, ...)
vfprintf(out_fp, mesg, args);
fprintf(out_fp, "\n");
va_end(args);
- errcount++;
+ dbg_errcount++;
repeat_idx = -1;
}
@@ -1039,9 +1039,9 @@ yylex(void)
yylval = (CMDARG *) NULL;
- if (errcount > 0 && lexptr_begin == NULL) {
+ if (dbg_errcount > 0 && lexptr_begin == NULL) {
/* fake a new line */
- errcount = 0;
+ dbg_errcount = 0;
return '\n';
}
diff --git a/main.c b/main.c
index d6e34266..8327cc74 100644
--- a/main.c
+++ b/main.c
@@ -1262,6 +1262,9 @@ catchsig(int sig)
|| sig == SIGBUS
#endif
) {
+ if (errcount > 0) // assume a syntax error corrupted our
data structures
+ exit(EXIT_FATAL);
+
set_loc(__FILE__, __LINE__);
msg(_("fatal error: internal error"));
/* fatal won't abort() if not compiled for debugging */
@@ -1279,6 +1282,9 @@ catchsig(int sig)
static int
catchsegv(void *fault_address, int serious)
{
+ if (errcount > 0) // assume a syntax error corrupted our data
structures
+ exit(EXIT_FATAL);
+
set_loc(__FILE__, __LINE__);
msg(_("fatal error: internal error: segfault"));
fflush(NULL);