diff --git a/usr.bin/uudecode/uudecode.c b/usr.bin/uudecode/uudecode.c index 3112b9f76e83..39a8cf650042 100644 --- a/usr.bin/uudecode/uudecode.c +++ b/usr.bin/uudecode/uudecode.c @@ -50,6 +50,7 @@ static char sccsid[] = "@(#)uudecode.c 8.2 (Berkeley) 4/2/94"; #include #include +#include #include #include #include @@ -135,6 +136,7 @@ decode2(flag) register char ch, *p; int mode, n1; char buf[MAXPATHLEN]; + char buffn[MAXPATHLEN]; /* file name buffer */ /* search for header line */ @@ -147,7 +149,9 @@ decode2(flag) "uudecode: %s: no \"begin\" line\n", filename); return(1); } - } while (strncmp(buf, "begin ", 6)); + } while (strncmp(buf, "begin ", 6) || + fnmatch("begin [0-7]* *", buf, 0)); + (void)sscanf(buf, "begin %o %s", &mode, buf); /* handle ~user/file format */ @@ -185,6 +189,7 @@ decode2(flag) filename, strerror(errno)); return(1); } + strcpy(buffn, buf); /* store file name from header line */ /* for each input line */ for (;;) { @@ -194,6 +199,18 @@ decode2(flag) return(1); } #define DEC(c) (((c) - ' ') & 077) /* single character decode */ +#define IS_DEC(c) ( (((c) - ' ') > 0) && (((c) - ' ') <= 077 + 1) ) +/* #define IS_DEC(c) (1) */ + +#define OUT_OF_RANGE \ +{ \ + (void)fprintf(stderr, \ + "uudecode:\n\tinput file: %s\n\tencoded file: %s\n\t%s: [%d-%d]\n", \ + filename, buffn, "character out of range", 1 + ' ', 077 + ' ' + 1); \ + return(1); \ +} + + /* * `n' is used to avoid writing out all the characters * at the end of the file. @@ -202,23 +219,37 @@ decode2(flag) break; for (++p; n > 0; p += 4, n -= 3) if (n >= 3) { + if (!(IS_DEC(*p) && IS_DEC(*(p + 1)) && + IS_DEC(*(p + 2)) && IS_DEC(*(p + 3)))) + OUT_OF_RANGE + ch = DEC(p[0]) << 2 | DEC(p[1]) >> 4; putchar(ch); ch = DEC(p[1]) << 4 | DEC(p[2]) >> 2; putchar(ch); ch = DEC(p[2]) << 6 | DEC(p[3]); putchar(ch); + } else { if (n >= 1) { + if (!(IS_DEC(*p) && IS_DEC(*(p + 1)))) + OUT_OF_RANGE ch = DEC(p[0]) << 2 | DEC(p[1]) >> 4; putchar(ch); } if (n >= 2) { + if (!(IS_DEC(*(p + 1)) && + IS_DEC(*(p + 2)))) + OUT_OF_RANGE + ch = DEC(p[1]) << 4 | DEC(p[2]) >> 2; putchar(ch); } if (n >= 3) { + if (!(IS_DEC(*(p + 2)) && + IS_DEC(*(p + 3)))) + OUT_OF_RANGE ch = DEC(p[2]) << 6 | DEC(p[3]); putchar(ch); }