diff options
author | Paul Smith <psmith@gnu.org> | 2021-03-15 03:28:11 -0400 |
---|---|---|
committer | Paul Smith <psmith@gnu.org> | 2021-03-15 03:28:11 -0400 |
commit | c5319e75f5b64c972a38967a6eb5747838e914fd (patch) | |
tree | f15966e1da0e6d0e05e35358c198dfe99bad5b8c /src/function.c | |
parent | 510e5ce801d957338be764a794f1463b662a7edc (diff) | |
download | make-git-c5319e75f5b64c972a38967a6eb5747838e914fd.tar.gz |
[SV 58497] Ensure $(file <) newline removal succeeds
Keep a count of bytes read rather than comparing pointers since the
variable_buffer might get reallocated.
Bug and patch by Ken Tossell <ken@tossell.net>
Regression tests by Dmitry Goncharov <dgoncharov@users.sf.net>
Tweaked by Paul Smith <psmith@gnu.org>
* src/function.c (func_file): Use bytes read rather than a pointer.
* tests/scripts/functions/file: Provide various tests for reading
empty files, files with/without newlines, and large files.
Diffstat (limited to 'src/function.c')
-rw-r--r-- | src/function.c | 13 |
1 files changed, 7 insertions, 6 deletions
diff --git a/src/function.c b/src/function.c index d36b7951..396f1297 100644 --- a/src/function.c +++ b/src/function.c @@ -2303,7 +2303,7 @@ func_file (char *o, char **argv, const char *funcname UNUSED) } else if (fn[0] == '<') { - char *preo = o; + size_t n = 0; FILE *fp; ++fn; @@ -2327,8 +2327,10 @@ func_file (char *o, char **argv, const char *funcname UNUSED) char buf[1024]; size_t l = fread (buf, 1, sizeof (buf), fp); if (l > 0) - o = variable_buffer_output (o, buf, l); - + { + o = variable_buffer_output (o, buf, l); + n += l; + } if (ferror (fp)) if (errno != EINTR) OSS (fatal, reading_file, _("read: %s: %s"), fn, strerror (errno)); @@ -2339,9 +2341,8 @@ func_file (char *o, char **argv, const char *funcname UNUSED) OSS (fatal, reading_file, _("close: %s: %s"), fn, strerror (errno)); /* Remove trailing newline. */ - if (o > preo && o[-1] == '\n') - if (--o > preo && o[-1] == '\r') - --o; + if (n && o[-1] == '\n') + o -= 1 + (n > 1 && o[-2] == '\r'); } else OS (fatal, *expanding_var, _("file: invalid file operation: %s"), fn); |