I forgot to update the length of the new string.
============================

$OpenBSD$

Index: ex/ex_source.c
--- ex/ex_source.c.orig
+++ ex/ex_source.c
@@ -38,8 +38,8 @@ int
 ex_source(SCR *sp, EXCMD *cmdp)
 {
        struct stat sb;
-       int fd, len;
-       char *bp;
+       int fd, len, i;
+       char *bp, c;
        char *name, *np;
        size_t nlen;
        CHAR_T *wp;
@@ -64,8 +64,19 @@ ex_source(SCR *sp, EXCMD *cmdp)
                errno = ENOMEM;
                goto err;
        }
-
-       MALLOC(sp, bp, char *, (size_t)sb.st_size + 1);
+       i = 0;
+       for (len = 0; len < sb.st_size; ++len) {
+               if ((rc = read(fd, &c, 1)) <= 0) {
+                       if (rc == 0)
+                               errno = EIO;
+                       (void)close(fd);
+                       goto err;
+               }
+               if (c == '|')
+                       ++i;
+       }
+       lseek(fd, 0, SEEK_SET);
+       MALLOC(sp, bp, char *, (size_t)sb.st_size + 1 + i);
        if (bp == NULL) {
                (void)close(fd);
                return (1);
@@ -73,18 +84,28 @@ ex_source(SCR *sp, EXCMD *cmdp)
        bp[sb.st_size] = '\0';

        /* Read the file into memory. */
-       len = read(fd, bp, (int)sb.st_size);
+       np = bp;
+       for (len = 0; len < sb.st_size; ++len, ++np) {
+               if ((rc = read(fd, np, 1)) <= 0) {
+                       len = rc;
+                       if (len == 0)
+                               errno = EIO;
+                       break;
+               }
+               if (*np == '|') {
+                       *np = CH_LITERAL;
+                       *++np = '|';
+               }
+       }
        (void)close(fd);
-       if (len == -1 || len != sb.st_size) {
-               if (len != sb.st_size)
-                       errno = EIO;
+       if (len != sb.st_size) {
                free(bp);
 err:           msgq_str(sp, M_SYSERR, name, "%s");
                return (1);
-       }
+       }

        np = strdup(name);
-       if (CHAR2INT(sp, bp, (size_t)sb.st_size + 1, wp, wlen))
+       if (CHAR2INT(sp, bp, (size_t)sb.st_size + 1 + i, wp, wlen))
                msgq(sp, M_ERR, "323|Invalid input. Truncated.");
        /* Put it on the ex queue. */
        rc = ex_run_str(sp, np, wp, wlen - 1, 1, 0);

Reply via email to