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:
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);