Hi all, here is some c++ code that has 3 or 4 overflow issues. Could you help me identify them??
I am currently studing architecture and security. Programing is not my forte. Any help would be greatly appreciated!
/* Buffer overflow demo */
/* Last edited on 2002-11-05 14:24:23 by stolfi */
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
/* Error in command line: prints `msg', `usage', and halts the program. */
void arg_error(char *msg);
/* Error in banner file: prints `msg' and halts the program. */
void file_error(char *msg);
/* Reads compressed banner from `filename' and displays it to `stdout': */
void show_file(char *filename, char compression, char *buf);
/* Prints current date: */
void show_date(char *msg);
/* Maximum banner name length */
#define MAXNAMELENGTH 8
/* Maximum banner dimensions */
#define MAXROWS 600
#define MAXCOLS 800
/* Banner buffer size (= MAXCOLS + 1) */
#define IMGBUFSIZE 80l
/* Maximum repeat count */
#define MAXREPEAT 10
static char *usage = "demo [ -z | -r | -n COUNT | BANNERNAME ]...";
int main(int argn, char **argc)
{
int i;
char filename[MAXNAMELENGTH];
unsigned int repeat = 1;
char compression = 'z';
char buf[IMGBUFSIZE];
int j;
/* Parse command line arguments */
for (i = 1; i < argn; i++)
{
if (strcmp(argc,"-z") == 0)
{ compression = 'z'; }
else if (strcmp(argc,"-r") == 0)
{ compression = 'r'; }
else if (strcmp(argc,"-n") == 0)
{ char *rest; double rep;
i++;
if (i >= argn) { arg_error("no repeat count"); }
rep = strtod(argc, &rest);
if ((*rest != '\0') || (rep < 0) || (rep > MAXREPEAT) || (rep != (int)rep))
{ arg_error("invalid repeat count"); }
repeat = (int)rep;
}
else
{
/* Check name length (including final '\0'): */
if (strlen(argc) > MAXNAMELENGTH+1)
{ arg_error("banner name too long"); }
else
{
strcpy(filename, argc);
strcat(filename, ".img");
if (compression == 'z') { strcat(filename, ".z"); }
for (j = 0; j < repeat; j++)
{
printf("\033[H\033[2J\n"); /* Clear screen */
printf("%s (%s)\n", argc, filename);
usleep(300000);
show_file(filename, compression, &(buf[0]));
usleep(500000);
}
}
}
}
show_date("demo finished on ");
return(0);
}
void show_file(char *filename, char compression, char *buf)
{
/*
Read a pictorial text (banner, ascii-art image, etc.)
from the given `filename' and prints it to standard out.
If the `compression' argument is `r' ("raw"), the file is printed
as is. Otherwise, the file is assumed to be in a compressed
format, and is uncompressed before being printed.
Currently, the only compression method supported is a variant of
run-length encoding (`compression = 'z''). In this encoding, each
line of the file consists of a series of "groups". Each group
consists of one "control" byte, possibly followed by a data
byte. The control byte consists of a `type' bit and a seven-bit
`val' field. If `type == 1', then the byte `val + 32'is
inserted as the next banner pixel. If `type == 0', then the
following byte is taken to be a banner pixel which is
to be replicated `val + 1' times.
The caller must provide a pixel buffer `buf', with at least
MAXCOLS+1 characters (MAXCOLS pixels plus a final `\0'). */
int c, d, type, count;
int col;
FILE *f;
f = fopen(filename, "r");
if (f == NULL) { file_error("file not found"); }
while((c = fgetc(f)) != EOF)
{ col = 0;
while(c != '\n')
{ switch(compression)
{
case 'r':
/* Raw format: */
if (col >= MAXCOLS)
{ file_error("too many pixels in row"); }
else
{ buf[col] = c; col++; }
break;
case 'z':
/* Compressed format: */
type = (c >> 7);
if (type == 1)
{ /* Verbatim pixel: */
if (col >= MAXCOLS)
{ file_error("too many pixels in row"); }
else
{ buf[col] = (c & 127) + 32; col++; }
}
else
{ /* Replication group: */
if (((d = fgetc(f)) == EOF) || ( d == '\n'))
{ file_error("premature EOF/EOL in replicated group"); }
count = (c & 127) + 1;
while(count > 0)
{ if (col >= MAXCOLS)
{ file_error("too many pixels in row"); }
else
{ buf[col] = d; col++; count--; }
}
}
break;
default:
fprintf(stderr, "compression = `%c'\n", compression);
file_error("invalid compression code");
}
c = fgetc(f);
if (c == EOF) { file_error("missing end-of-line"); }
}
buf[col] = '\000';
printf("%s\n", buf);
}
}
void show_date(char *msg)
{
time_t *now = (time_t *)malloc(sizeof(time_t));
(void)time(now);
printf("%s%s\n", msg, ctime(now));
}
void arg_error(char *msg)
{
fprintf(stderr, "** %s\n", msg);
fprintf(stderr, "usage: %s\n", usage);
exit(1);
}
void file_error(char *msg)
{
fprintf(stderr, "** %s\n", msg);
exit(1);
}