bug-texinfo
[Top][All Lists]
Advanced

[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;



reply via email to

[Prev in Thread] Current Thread [Next in Thread]