On Wed, Dec 10, 2014 at 02:09:10PM +0100, Sébastien Marie wrote:
> Hi Jonathan,
> 
> I think there is a mistake in pointer comparaison (q + 1 >= eq): it
> results we keep two chars at end (whereas only one is necessary for
> '\0').
> 
> - eq points to the last cell in array before out-of-bound.
>   eq = wfile + sizeof(wfile) - 1;
> 
> - q points to the cell that would receive a new character.
> 
> The err terminaison should be: when q points to eq (because if we do it,
> there is no more place for '\0').
> 
> Actually it is "if (q + 1 >= eq)", so we stop when q+1 points to the
> last cell, or when q points to the cell before the last cell. As it would
> never write to it (we stop): we keep two cells at end.
> 
> 
> As simple test, defining wfile to "char wfile[2]", don't permit to save
> to any filename, whereas one-char filename should be ok.
> 
> $ echo | sed -e s/a//w_
> sed: 1: "s/a//w_": wfile too long
> 
> I think the test should be "if (q >= eq)".

Yes, I agree.  I plan to commit this version:

Index: compile.c
===================================================================
RCS file: /cvs/src/usr.bin/sed/compile.c,v
retrieving revision 1.36
diff -u -p -r1.36 compile.c
--- compile.c   8 Oct 2014 04:19:08 -0000       1.36
+++ compile.c   11 Dec 2014 05:32:42 -0000
@@ -538,7 +538,7 @@ 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;
+       char wfile[PATH_MAX], *q, *eq;
 
        s->n = 1;                               /* Default */
        s->p = 0;
@@ -584,9 +584,12 @@ compile_flags(char *p, struct s_subst *s
 #endif
                        EATSPACE();
                        q = wfile;
+                       eq = wfile + sizeof(wfile) - 1;
                        while (*p) {
                                if (*p == '\n')
                                        break;
+                               if (q >= eq)
+                                       err(COMPILE, "wfile too long");
                                *q++ = *p++;
                        }
                        *q = '\0';

Reply via email to