[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
4 bugs in texindex.c
From: |
Christopher League |
Subject: |
4 bugs in texindex.c |
Date: |
26 Apr 2002 22:45:45 -0400 |
User-agent: |
Gnus/5.09 (Gnus v5.9.0) Emacs/21.2 |
Something about my application seems to be exposing bugs in
texinfo... :)
I was having trouble with "texindex" from texinfo-4.2 on
powerpc-apple-darwin5.4. For ANY non-empty index file, it would say
texindex: foo.cp: not a texinfo index file
Even if foo.cp just contained one line:
\entry{license}{1}{license}
(I indented that line for display; it was flush left in the file.)
I traced this to what seemed to be a memory problem in sort_in_core
of texindex.c. It allocated 1762+1 bytes for the contents of
foo.cp, then read the entire contents into tho data buffer. I
checked the buffer in gdb and it looked fine.
But then I got down to the next xmalloc, for the linearray. As soon
as I execute the xmalloc, the data buffer now contains just
"\entry{license"
and the rest has been truncated!
I couldn't imagine there being so serious a memory-trashing error in
this simple application, but I tried again, this time stepping into
the xmalloc function both times.
Anyway, I'll cut to the chase.
BUG #1
On this platform, sizeof(off_t) == 8 and sizeof(int) == 4. In
sort_in_core, the "total" number of characters is of type off_t
(because it came from lseek()). This number is passed to xmalloc(),
which only expects an int. So while "total" in sort_in_core equals
1762, when I pass 1762+1 into xmalloc(), it appears as some garbage
integer there. Proper function prototypes would have caught
this... sigh.
Here is my fix: since sort_in_core is reserved for small file sizes,
its total size should not be off_t, but rather int. Then we should
do an explicit cast before calling sort_in_core.
BUG #2
Just for kicks, I artificially created an absurdly large index file
(3Mb) on this platform. This exposed a bug, which can be summarized
as follows:
void sort_offline (infile, nfiles, total, outfile)
char *infile;
int nfiles;
off_t total;
char *outfile;
{ ... }
int main (argc, argv)
{ ...
sort_offline(infiles[i], ptr, outfile);
... }
Yes, there are four arguments in the definition and three arguments
in the call. sort_offline doesn't use "nfiles", so it can just be
deleted. Maybe this was just a cut and paste error?
BUG #3
That fixed, now there is a problem when sort_offline calls
sort_in_core. The first argument is &tempfiles[i], but it should be
just tempfiles[i].
BUG #4
Now, my large index file is split into several temporary files, and
they are each sorted and output again using sort_in_core. Next, we
merge the files, but there is a problem. sort_in_core not only
sorted the entries but also output the \initial{a} before each group
of entries. Now, in merging the files I get the following error:
texindex: No page number in \initial {a}
I'm not sure what the intent is here. indexify() happens at two
levels, because sort_offline calls sort_in_core. They seem to be
stepping on one another's toes. I didn't fix this bug.
Below is a patch to fix bugs 1, 2, and 3. I believe all three would
have been found easily by the compiler if we used proper function
prototypes. I know that GNU tries very hard to support all manner
of systems, even without ansi C compilers. Maybe a preprocessor
trick that includes the full prototypes on ansi C systems (and
removes them otherwise) would be helpful...
Thanks
--Chris
diff -ur texinfo-4.2/util/texindex.c texinfo-fix/util/texindex.c
--- texinfo-4.2/util/texindex.c Mon Mar 11 14:55:46 2002
+++ texinfo-fix/util/texindex.c Fri Apr 26 22:05:00 2002
@@ -219,7 +219,7 @@
if (ptr < MAX_IN_CORE_SORT)
/* Sort a small amount of data. */
- sort_in_core (infiles[i], ptr, outfile);
+ sort_in_core (infiles[i], (int)ptr, outfile);
else
sort_offline (infiles[i], ptr, outfile);
}
@@ -861,9 +861,8 @@
/* Sort an input file too big to sort in core. */
void
-sort_offline (infile, nfiles, total, outfile)
+sort_offline (infile, total, outfile)
char *infile;
- int nfiles;
off_t total;
char *outfile;
{
@@ -942,7 +941,7 @@
for (i = 0; i < ntemps; i++)
{
char *newtemp = maketempname (++tempcount);
- sort_in_core (&tempfiles[i], MAX_IN_CORE_SORT, newtemp);
+ sort_in_core (tempfiles[i], MAX_IN_CORE_SORT, newtemp);
if (!keep_tempfiles)
unlink (tempfiles[i]);
tempfiles[i] = newtemp;
@@ -963,7 +962,7 @@
void
sort_in_core (infile, total, outfile)
char *infile;
- off_t total;
+ int total;
char *outfile;
{
char **nextline;