On 12/07/17 21:25, Todd C. Miller wrote:
> Previously, 'p' would be traversed until eol. With your diff this
> is not longer the case. Since the return value of compile_flags()
> is used to assign a new value for 'p', isn't that a problem?
>
> - todd
>
Since the w flag works to eol everything usable has been consumed. The
only use for p after compile_flags is for a semicolon check. So the only
way the position of p could have effect is when the filename starts with
"[[:space:]]*;". Since no sane person would start a filename with a
semicolon it would cause a compiletime error and stop the run, so we
could call it a feature. /joke
But you're right, although I would call it a bug more than a problem,
since this scenario would most likely never occur. Below is a revised
diff. This invalidates p, by turning it into a NUL. This is safe since
duptoeol also writes to the same string.
martijn@
Index: compile.c
===================================================================
RCS file: /cvs/src/usr.bin/sed/compile.c,v
retrieving revision 1.42
diff -u -p -u -r1.42 compile.c
--- compile.c 1 Aug 2017 18:05:53 -0000 1.42
+++ compile.c 8 Dec 2017 06:24:42 -0000
@@ -277,6 +277,8 @@ nonsel: /* Now parse the command */
pledge_rpath = 1;
p++;
EATSPACE();
+ if (*p == '\0')
+ error(COMPILE, "filename expected");
cmd->t = duptoeol(p, "read command", NULL);
break;
case BRANCH: /* b t */
@@ -539,7 +541,6 @@ compile_flags(char *p, struct s_subst *s
{
int gn; /* True if we have seen g or n */
long l;
- char wfile[PATH_MAX], *q, *eq;
s->n = 1; /* Default */
s->p = 0;
@@ -577,32 +578,17 @@ compile_flags(char *p, struct s_subst *s
continue;
case 'w':
p++;
-#ifdef HISTORIC_PRACTICE
- if (*p != ' ') {
- warning("space missing before w wfile");
- return (p);
- }
-#endif
EATSPACE();
- q = wfile;
- eq = wfile + sizeof(wfile) - 1;
- while (*p) {
- if (*p == '\n')
- break;
- if (q >= eq)
- error(COMPILE, "wfile too long");
- *q++ = *p++;
- }
- *q = '\0';
- if (q == wfile)
- error(COMPILE, "no wfile specified");
- s->wfile = strdup(wfile);
+ if (*p == '\0')
+ error(COMPILE, "filename expected");
+ s->wfile = duptoeol(p, "s command w flag", NULL);
+ *p = '\0';
if (aflag)
pledge_wpath = 1;
- else if ((s->wfd = open(wfile,
+ else if ((s->wfd = open(s->wfile,
O_WRONLY|O_APPEND|O_CREAT|O_TRUNC,
DEFFILEMODE)) == -1)
- error(FATAL, "%s: %s", wfile, strerror(errno));
+ error(FATAL, "%s: %s", s->wfile,
strerror(errno));
return (p);
default:
error(COMPILE,
Index: sed.1
===================================================================
RCS file: /cvs/src/usr.bin/sed/sed.1,v
retrieving revision 1.51
diff -u -p -u -r1.51 sed.1
--- sed.1 7 Dec 2017 09:52:26 -0000 1.51
+++ sed.1 8 Dec 2017 06:24:42 -0000
@@ -255,7 +255,7 @@ as well as the
flag to the
.Ic s
function,
-take an optional
+take a
.Ar file
parameter,
which should be separated from the function or flag by whitespace.