Date: Tue, 14 Dec 1999 11:10:03 -0800 (PST) From: "Steven G. Kargl" <kargl@troutmask.apl.washington.edu> To: freebsd-bugs@FreeBSD.org Subject: Re: bin/15471: fsplit buffer overflow fixes Message-ID: <199912141910.LAA96935@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
The following reply was made to PR bin/15471; it has been noted by GNATS. From: "Steven G. Kargl" <kargl@troutmask.apl.washington.edu> To: sheldonh@uunet.co.za (Sheldon Hearn) Cc: FreeBSD-gnats-submit@FreeBSD.ORG Subject: Re: bin/15471: fsplit buffer overflow fixes Date: Tue, 14 Dec 1999 11:06:41 -0800 (PST) Once upon a time, Sheldon Hearn said: > > > On Mon, 13 Dec 1999 12:50:24 PST, "Steven G. Kargl" wrote: > > > * Whitespace clean up > > Can you send the diff without the whitespace changes? That's how it'd > have to be committed in any case, with whitespace changes (which are > discouraged) being committed seperately. * Added "include <stdlib.h>" for exit(3) prototype * Use getopt(3) instead of custom command line parser * Use dynamic memory allocation to allevaite buffer overflows * Update man page * Declare argc * Give int main() a return value of 0 -- Steve diff -r -u /usr/src/usr.bin/fsplit/fsplit.1 fsplit/fsplit.1 --- /usr/src/usr.bin/fsplit/fsplit.1 Mon Aug 30 08:00:49 1999 +++ fsplit/fsplit.1 Tue Dec 14 10:55:53 1999 @@ -39,7 +39,7 @@ .Os BSD 4.2 .Sh NAME .Nm fsplit -.Nd split a multi-routine Fortran file into individual files +.Nd split a multi-routine Fortran 77 file into individual files .Sh SYNOPSIS .Nm fsplit .Op Fl e Ar efile @@ -47,8 +47,8 @@ .Op Ar file .Sh DESCRIPTION .Nm Fsplit -takes as input either a file or standard input containing Fortran source code. -It attempts to split the input into separate routine files of the +takes as input either a file or standard input containing Fortran 77 source +code. It attempts to split the input into separate routine files of the form .Ar name.f , where @@ -104,3 +104,7 @@ .Fl e for unnamed main programs and block data subprograms since you must predict the created file name. +.Pp +.Nm +can be used with Fortran 77 and older source code. It understands neither +Fortran 90/95 syntax nor free form source files. diff -r -u /usr/src/usr.bin/fsplit/fsplit.c fsplit/fsplit.c --- /usr/src/usr.bin/fsplit/fsplit.c Tue Sep 7 11:59:34 1999 +++ fsplit/fsplit.c Tue Dec 14 10:59:13 1999 @@ -51,6 +51,7 @@ #include <ctype.h> #include <err.h> #include <stdio.h> +#include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> @@ -90,11 +91,8 @@ #define TRUE 1 #define FALSE 0 -int extr = FALSE, - extrknt = -1, - extrfnd[100]; -char extrbuf[1000], - *extrnames[100]; +int extr = FALSE, extrknt = -1, *extrfnd; +char **extrnames; struct stat sbuf; #define trim(p) while (*p == ' ' || *p == '\t') p++ @@ -103,58 +101,74 @@ void get_name __P((char *, int)); char *functs __P((char *)); int lend __P((void)); -int lname __P((char *)); +int lname __P((char *, int)); char *look __P((char *, char *)); int saveit __P((char *)); -int scan_name __P((char *, char *)); +int scan_name __P((char *, char *, int)); char *skiplab __P((char *)); static void usage __P((void)); int main(argc, argv) +int argc; char **argv; { + extern int optind; + extern char *optarg; + register FILE *ofp; /* output file */ register int rv; /* 1 if got card in output file, 0 otherwise */ register char *ptr; int nflag, /* 1 if got name of subprog., 0 otherwise */ retval, i; - char name[20], - *extrptr = extrbuf; + char name[20]; - /* scan -e options */ - while ( argc > 1 && argv[1][0] == '-' && argv[1][1] == 'e') { + if (argc > 2) { extr = TRUE; - ptr = argv[1] + 2; - if(!*ptr) { - argc--; - argv++; - if(argc <= 1) + + extrfnd = (int *) malloc(argc * sizeof(int)); + if (extrfnd == NULL) + errx(1, NULL); + + extrnames = (char **) malloc(argc * sizeof(char *)); + if (extrnames == NULL) + errx(1, NULL); + + while ((i = getopt(argc, argv, "e:")) != -1) { + switch (i) { + case 'e': + extrknt++; + extrfnd[extrknt] = FALSE; + extrnames[extrknt] = optarg; + break; + default: usage(); - ptr = argv[1]; + } } - extrknt = extrknt + 1; - extrnames[extrknt] = extrptr; - extrfnd[extrknt] = FALSE; - while(*ptr) *extrptr++ = *ptr++; - *extrptr++ = 0; + + argc -= optind; + argv += optind; + } else { argc--; argv++; } - if (argc > 2) + if (argc > 1) usage(); - else if (argc == 2) { - if ((ifp = fopen(argv[1], "r")) == NULL) - errx(1, "cannot open %s", argv[1]); + else if (argc == 1) { + if ((ifp = fopen(*argv, "r")) == NULL) + errx(1, "cannot open %s", *argv); } else ifp = stdin; + for(;;) { /* look for a temp file that doesn't correspond to an existing file */ get_name(x, 3); ofp = fopen(x, "w"); + if (ofp == NULL) + errx(1, "can not open %s", x); nflag = 0; rv = 0; while (getline() > 0) { @@ -163,7 +177,7 @@ if (lend()) /* look for an 'end' statement */ break; if (nflag == 0) /* if no name yet, try and find one */ - nflag = lname(name); + nflag = lname(name, 20); } fclose(ofp); if (rv == 0) { /* no lines in file, forget the file */ @@ -198,6 +212,8 @@ else unlink(x); } + + return 0; } static void @@ -293,8 +309,9 @@ name and put in arg string. invent name for unnamed block datas and main programs. */ int -lname(s) +lname(s, len) char *s; +int len; { # define LINESIZE 80 register char *ptr, *p; @@ -324,18 +341,18 @@ if ((ptr = look(line, "subroutine")) != 0 || (ptr = look(line, "function")) != 0 || (ptr = functs(line)) != 0) { - if(scan_name(s, ptr)) return(1); + if(scan_name(s, ptr, len)) return(1); strcpy( s, x); } else if((ptr = look(line, "program")) != 0) { - if(scan_name(s, ptr)) return(1); + if(scan_name(s, ptr, len)) return(1); get_name( mainp, 4); strcpy( s, mainp); } else if((ptr = look(line, "blockdata")) != 0) { - if(scan_name(s, ptr)) return(1); + if(scan_name(s, ptr, len)) return(1); get_name( blkp, 6); strcpy( s, blkp); } else if((ptr = functs(line)) != 0) { - if(scan_name(s, ptr)) return(1); + if(scan_name(s, ptr, len)) return(1); strcpy( s, x); } else { get_name( mainp, 4); @@ -345,17 +362,22 @@ } int -scan_name(s, ptr) +scan_name(s, ptr, len) char *s, *ptr; +int len; { + int cnt = 0; char *sptr; /* scan off the name */ trim(ptr); sptr = s; while (*ptr != '(' && *ptr != '\n') { - if (*ptr != ' ' && *ptr != '\t') + if (*ptr != ' ' && *ptr != '\t') { *sptr++ = *ptr; + cnt++; + if (cnt == len - 3) break; + } ptr++; } To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199912141910.LAA96935>