scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | LICENSE

commit 0323e89fa2df72cf2f5beb26d254928ce234e5dd
parent 2cf6a99d4c85952c3061cc4ca60df0d441360ef4
Author: Quentin Rameau <quinq@fifth.space>
Date:   Fri, 11 Jan 2019 13:57:56 +0100

[ar] Check filenames before processing archive

Diffstat:
Msrc/cmd/ar.c | 21++++++++++++++++++---
Msrc/cmd/posix.c | 2++
Msrc/cmd/sys.h | 2++
3 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/src/cmd/ar.c b/src/cmd/ar.c @@ -119,8 +119,6 @@ archive(char *pname, FILE *to, char letter) if (vflag) printf("%c - %s\n", letter, fname); - if (strlen(fname) > 16) - fprintf(stderr, "ar: %s: name too long, truncated\n", fname); if ((from = fopen(pname, "rb")) == NULL) error("opening member '%s': %s", pname, errstr()); if (getstat(pname, &prop) < 0) @@ -548,6 +546,22 @@ ar(int key, char *argv[], int argc) } static void +checkfnames(int argc, char *argv[]) +{ + size_t l; + char *p; + + for ( ; argc-- > 0; ++argv) { + p = canonical(*argv); + l = strcspn(p, invalidchars); + if (l > 16) + error("file: '%s': name too long", *argv); + if (p[l] != '\0') + error("file: '%s': name invalid", *argv); + } +} + +static void usage(void) { fputs("ar [-drqtpmx][posname] [-vuaibcl] [posname] arfile name ...\n", @@ -628,7 +642,8 @@ main(int argc, char *argv[]) signal(SIGTERM, sigfun); arfile = *argv; - ar(key, ++argv, --argc); + checkfnames(--argc, ++argv); + ar(key, argv, argc); fflush(stdout); if (ferror(stdout)) diff --git a/src/cmd/posix.c b/src/cmd/posix.c @@ -9,6 +9,8 @@ static char sccsid[] = "@(#) ./ar/posix/driver.c"; #include "sys.h" +const char invalidchars[] = " "; + time_t totime(long long t) { diff --git a/src/cmd/sys.h b/src/cmd/sys.h @@ -6,6 +6,8 @@ struct fprop { time_t time; }; +extern const char invalidchars[]; + extern time_t totime(long long t); extern char *canonical(char *path); extern int getstat(char *fname, struct fprop *prop);