ref: 0c6b04d3013c4dd19b64803c89e20ace6517d38b
parent: f252835dfc4dcd929a86547da426b5c5ab4df65b
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Tue Feb 13 09:59:57 EST 2018
[ar] Add valid() This makes the code of run() easier and it centralizes all the check work.
--- a/ar/main.c
+++ b/ar/main.c
@@ -24,6 +24,8 @@
struct ar_hdr hdr;
char *fname;
long size;
+ long mode;
+ long long date;
};
static void
@@ -168,31 +170,15 @@
}
static char *
-perms(struct ar_hdr *hdr)
+perms(struct arop *op)
{
- size_t siz;
- int c;
- long val;
- char *p, *q;
static char buf[10];
- static char digits[] = "01234567";
- siz = sizeof(hdr->ar_mode);
- p = hdr->ar_mode;
- for (val = 0; siz-- > 0; val += c) {
- if ((c = *p++) == ' ')
- break;
- if ((q = strchr(digits, c)) == NULL) {
- fputs("ar: corrupted header\n", stderr);
- exit(1);
- }
- val *= 8;
- c = q - digits;
- }
- letters(val >> 6, buf);
- letters(val >> 3, buf+3);
- letters(val, buf +6);
+ letters(op->mode >> 6, buf);
+ letters(op->mode >> 3, buf+3);
+ letters(op->mode, buf +6);
buf[9] = '\0';
+
return buf;
}
@@ -265,15 +251,10 @@
if (!vflag) {
printf("%s\n", op->fname);
} else {
- val = atoll(hdr->ar_date);
- if (val < 0) {
- fputs("ar:corrupted member\n", stderr);
- exit(1);
- }
- t = totime(val);
+ t = totime(op->date);
strftime(mtime, sizeof(mtime), "%c", localtime(&t));
printf("%s %d/%d\t%s %s\n",
- perms(hdr),
+ perms(op),
atol(hdr->ar_uid),
atol(hdr->ar_gid),
mtime,
@@ -305,6 +286,48 @@
return fname;
}
+static long long
+getnum(char *s, int size, int base)
+{
+ int c;
+ long long val;
+ char *p, *q;
+ static char digits[] = "0123456789";
+
+ for (val = 0; size-- > 0; val += c) {
+ if ((c = *p++) == ' ')
+ break;
+ if ((q = strchr(digits, c)) == NULL)
+ return -1;
+ if ((c = q - digits) >= base)
+ return -1;
+ val *= base;
+ }
+
+ if (size > 0) {
+ while (size-- > 0 && *p++ != ' ')
+ ;
+ }
+ return (size == 0) ? val : -1;
+}
+
+static int
+valid(struct arop *op)
+{
+ struct ar_hdr *hdr = &op->hdr;
+
+ op->fname = getfname(&op->hdr);
+ op->size = getnum(hdr->ar_size, sizeof(hdr->ar_size), 10);
+ op->mode = getnum(hdr->ar_mode, sizeof(hdr->ar_mode), 8);
+ op->date = getnum(hdr->ar_date, sizeof(hdr->ar_date), 10);
+
+ if (strncmp(hdr->ar_fmag, ARFMAG, sizeof(hdr->ar_fmag)) ||
+ op->size < 0 || op->mode < 0 || op->date < 0) {
+ return 0;
+ }
+ return 1;
+}
+
static void
run(FILE *fp, FILE *tmp, char *files[], void (*fun)(struct arop *, char *files[]))
{
@@ -315,12 +338,12 @@
while (!ferror(fp) && fread(&op.hdr, sizeof(op.hdr), 1, fp) == 1) {
fpos_t pos;
- if (strncmp(op.hdr.ar_fmag, ARFMAG, sizeof(op.hdr.ar_fmag)) ||
- (op.size = atol(op.hdr.ar_size)) < 0) {
- fputs("ar:corrupted member\n", stderr);
+ if (!valid(&op)) {
+ fprintf(stderr,
+ "ar:corrupted member '%s'\n",
+ op.fname);
exit(1);
}
- op.fname = getfname(&op.hdr);
fgetpos(fp, &pos);
(*fun)(&op, files);
fsetpos(fp, &pos);