diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2021-11-18 13:30:03 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2021-11-18 13:30:03 +0200 |
commit | c6c8162e6d81fdd5994007f4407de4305f4778bf (patch) | |
tree | a3ec0d127c717e1582fde4861d35a6eeff76e462 | |
parent | f3c7872fed5e0782438d186ac88c63035a637462 (diff) | |
download | gdbm-c6c8162e6d81fdd5994007f4407de4305f4778bf.tar.gz |
Fix shell command in gdbmtool
Trailing whitespace was erroneously recognized as argument.
* src/lex.l (string_end): Optionally return NULL if the collected
string is of zero length.
When leaving the SHELL condition, don't return T_WORD for trailing
whitespace.
* src/gdbmshell.c (shell_handler): Perror after failed execv.
-rw-r--r-- | src/gdbmshell.c | 1 | ||||
-rw-r--r-- | src/lex.l | 42 |
2 files changed, 27 insertions, 16 deletions
diff --git a/src/gdbmshell.c b/src/gdbmshell.c index 96b5844..6e4d8ff 100644 --- a/src/gdbmshell.c +++ b/src/gdbmshell.c @@ -1771,6 +1771,7 @@ shell_handler (struct command_param *param, if (pid == 0) { execv (argv[0], argv); + perror (argv[0]); _exit (127); } @@ -64,7 +64,7 @@ advance_line (void) void string_begin (void); void string_add (const char *s, int l); void string_addc (int c); -char *string_end (void); +char *string_end (int empty_null); int unescape (int c); struct file_name @@ -341,7 +341,7 @@ pad { return T_PAD; } <STR,MLSTR>{ [^\\\"\n]*\" { if (yyleng > 1) string_add (yytext, yyleng - 1); - yylval.string = string_end (); + yylval.string = string_end (FALSE); BEGIN (CMD); return T_WORD; } [^\\\"\n]*\\\n { advance_line (); @@ -376,8 +376,8 @@ pad { return T_PAD; } BEGIN (INITIAL); advance_line (); yyless (0); - yylval.string = string_end (); - return T_WORD; + if ((yylval.string = string_end (TRUE)) != NULL) + return T_WORD; } . string_addc (yytext[0]); } @@ -475,28 +475,38 @@ string_addc (int c) strseg_attach (seg); } +/* + * Compose the collected string segments into a nul-terminated string. + * Return the allocated string. + * If EMPTY_NULL is TRUE and the resulting string length is 0, return + * NULL instead. + */ char * -string_end (void) +string_end (int empty_null) { - int len = 1; + int len = 0; struct strseg *seg; char *ret, *p; for (seg = strseg_head; seg; seg = seg->next) len += seg->len; - ret = emalloc (len); - p = ret; - for (seg = strseg_head; seg; ) + if (len == 0 && empty_null) + ret = NULL; + else { - struct strseg *next = seg->next; - memcpy (p, seg->ptr, seg->len); - p += seg->len; - free (seg); - seg = next; + ret = emalloc (len + 1); + p = ret; + for (seg = strseg_head; seg; ) + { + struct strseg *next = seg->next; + memcpy (p, seg->ptr, seg->len); + p += seg->len; + free (seg); + seg = next; + } + *p = 0; } - *p = 0; - strseg_head = strseg_tail = NULL; return ret; |