summaryrefslogtreecommitdiffstats
path: root/contrib/patch/inp.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/patch/inp.c')
-rw-r--r--contrib/patch/inp.c68
1 files changed, 44 insertions, 24 deletions
diff --git a/contrib/patch/inp.c b/contrib/patch/inp.c
index ebc2a03..880b90e 100644
--- a/contrib/patch/inp.c
+++ b/contrib/patch/inp.c
@@ -1,6 +1,6 @@
/* inputting files to be patched */
-/* $Id: inp.c,v 1.16 1997/06/13 06:28:37 eggert Exp $ */
+/* $Id: inp.c,v 1.18 1997/07/21 17:59:46 eggert Exp $ */
/*
Copyright 1986, 1988 Larry Wall
@@ -33,6 +33,7 @@ If not, write to the Free Software Foundation,
/* Input-file-with-indexable-lines abstract type */
+static char *i_buffer; /* plan A buffer */
static char const **i_ptr; /* pointers to lines in plan A buffer */
static size_t tibufsize; /* size of plan b buffers */
@@ -49,6 +50,7 @@ static size_t last_line_size; /* size of last input line */
static bool plan_a PARAMS ((char const *));/* yield FALSE if memory runs out */
static void plan_b PARAMS ((char const *));
static void report_revision PARAMS ((int));
+static void too_many_lines PARAMS ((char const *)) __attribute__((noreturn));
/* New patch--prepare to edit another file. */
@@ -56,10 +58,8 @@ void
re_input()
{
if (using_plan_a) {
- if (i_ptr) {
- free (i_ptr);
- i_ptr = 0;
- }
+ free (i_buffer);
+ free (i_ptr);
}
else {
close (tifd);
@@ -128,6 +128,14 @@ report_revision (found_revision)
}
+static void
+too_many_lines (filename)
+ char const *filename;
+{
+ fatal ("File `%s' has too many lines.", filename);
+}
+
+
void
get_input_file (filename, outname)
char const *filename;
@@ -210,19 +218,13 @@ plan_a(filename)
register char *buffer;
register LINENUM iline;
size_t size = instat.st_size;
- size_t allocated_bytes_per_input_byte = sizeof *i_ptr + sizeof (char);
- size_t allocated_bytes = (size + 2) * allocated_bytes_per_input_byte;
- /* Fail if arithmetic overflow occurs during size calculations,
+ /* Fail if the file size doesn't fit in a size_t,
or if storage isn't available. */
- if (size != instat.st_size
- || size + 2 < 2
- || allocated_bytes / allocated_bytes_per_input_byte != size + 2
- || ! (ptr = (char const **) malloc (allocated_bytes)))
+ if (! (size == instat.st_size
+ && (buffer = malloc (size ? size : (size_t) 1))))
return FALSE;
- buffer = (char *) (ptr + (size + 2));
-
/* Read the input file, but don't bother reading it if it's empty.
When creating files, the files do not actually exist. */
if (size)
@@ -231,30 +233,45 @@ plan_a(filename)
size_t buffered = 0, n;
if (ifd < 0)
pfatal ("can't open file `%s'", filename);
- while (size - buffered != 0
- && (n = read (ifd, buffer + buffered, size - buffered)) != 0)
+
+ while (size - buffered != 0)
{
- if (n == -1)
+ n = read (ifd, buffer + buffered, size - buffered);
+ if (n == 0)
+ {
+ /* Some non-POSIX hosts exaggerate st_size in text mode;
+ or the file may have shrunk! */
+ size = buffered;
+ break;
+ }
+ if (n == (size_t) -1)
{
/* Perhaps size is too large for this host. */
close (ifd);
- free (ptr);
+ free (buffer);
return FALSE;
}
buffered += n;
}
- /* Some non-POSIX hosts exaggerate st_size in text mode;
- or the file may have shrunk! */
- size = buffered;
-
if (close (ifd) != 0)
read_fatal ();
}
/* Scan the buffer and build array of pointers to lines. */
- iline = 0;
lim = buffer + size;
+ iline = 3; /* 1 unused, 1 for SOF, 1 for EOF if last line is incomplete */
+ for (s = buffer; (s = (char *) memchr (s, '\n', lim - s)); s++)
+ if (++iline < 0)
+ too_many_lines (filename);
+ if (! (iline == (size_t) iline
+ && (size_t) iline * sizeof *ptr / sizeof *ptr == (size_t) iline
+ && (ptr = (char const **) malloc ((size_t) iline * sizeof *ptr))))
+ {
+ free (buffer);
+ return FALSE;
+ }
+ iline = 0;
for (s = buffer; ; s++)
{
ptr[++iline] = s;
@@ -290,6 +307,7 @@ plan_a(filename)
}
/* Plan A will work. */
+ i_buffer = buffer;
i_ptr = ptr;
return TRUE;
}
@@ -308,7 +326,7 @@ plan_b(filename)
register size_t i;
register char const *rev;
register size_t revlen;
- register LINENUM line;
+ register LINENUM line = 1;
if (instat.st_size == 0)
filename = NULL_DEVICE;
@@ -328,6 +346,8 @@ plan_b(filename)
if (c == '\n')
{
+ if (++line < 0)
+ too_many_lines (filename);
if (maxlen < len)
maxlen = len;
len = 0;
OpenPOWER on IntegriCloud