Author: robert Date: 2007-08-10 13:35:39 -0600 (Fri, 10 Aug 2007) New Revision: 1861
Added: trunk/texinfo/texinfo-4.9-nokeep-1.patch Log: Added -keep/-nokeep removal backport for Texinfo Added: trunk/texinfo/texinfo-4.9-nokeep-1.patch =================================================================== --- trunk/texinfo/texinfo-4.9-nokeep-1.patch (rev 0) +++ trunk/texinfo/texinfo-4.9-nokeep-1.patch 2007-08-10 19:35:39 UTC (rev 1861) @@ -0,0 +1,647 @@ +Submitted By: Robert Connolly <robert at linuxfromscratch dot org> (ashes) +Date: 2007-08-10 +Initial Package Version: texinfo-4.9 +Upstream Status: From Upstream +Origin: http://cvs.savannah.gnu.org/viewvc/*checkout*/texinfo/texinfo/ + util/texindex.c?revision=1.22 +Description: This patch removes the '-keep' and '-no-keep' options from the +'texindex' program to abolish the temporary file vulnerabilities associated +with this option. The options still work for reverse compatability, but do +nothing. + Revision 1.18 - remove (broken) offline sorting in texindex; from + [EMAIL PROTECTED] + +This patch also includes a couple other fixes: + Revision 1.14 - avoid race condition + Revision 1.17 - realloc better + Revision 1.19 - program_name non-static for non-glibc + +diff -Naur texinfo-4.9.orig/util/texindex.c texinfo-4.9/util/texindex.c +--- texinfo-4.9.orig/util/texindex.c 2007-06-27 17:11:08.000000000 +0000 ++++ texinfo-4.9/util/texindex.c 2007-08-10 19:13:29.000000000 +0000 +@@ -1,13 +1,13 @@ + /* texindex -- sort TeX index dribble output into an actual index. +- $Id: texindex.c,v 1.11.2.2 2007/06/27 17:11:08 karl Exp $ ++ $Id: texindex.c,v 1.22 2007/07/01 21:20:34 karl Exp $ + + Copyright (C) 1987, 1991, 1992, 1996, 1997, 1998, 1999, 2000, 2001, +- 2002, 2003, 2004, 2007 Free Software Foundation, Inc. ++ 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. + +- This program is free software; you can redistribute it and/or modify ++ This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by +- the Free Software Foundation; either version 3, or (at your option) +- any later version. ++ the Free Software Foundation, either version 3 of the License, or ++ (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of +@@ -15,13 +15,12 @@ + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License +- along with this program; if not, write to the Free Software +- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307. */ ++ along with this program. If not, see <http://www.gnu.org/licenses/>. */ + + #include "system.h" + #include <getopt.h> + +-static char *program_name = "texindex"; ++char *program_name = "texindex"; + + #if defined (emacs) + # include "../src/config.h" +@@ -37,16 +36,12 @@ + #define memset(ptr, ignore, count) bzero (ptr, count) + #endif + +-char *mktemp (char *); +- + #if !defined (SEEK_SET) + # define SEEK_SET 0 + # define SEEK_CUR 1 + # define SEEK_END 2 + #endif /* !SEEK_SET */ + +-struct linebuffer; +- + /* When sorting in core, this structure describes one line + and the position and length of its first keyfield. */ + struct lineinfo +@@ -96,16 +91,6 @@ + /* The allocated length of `linearray'. */ + long nlines; + +-/* Directory to use for temporary files. On Unix, it ends with a slash. */ +-char *tempdir; +- +-/* Number of last temporary file. */ +-int tempcount; +- +-/* Number of last temporary file already deleted. +- Temporary files are deleted by `flush_tempfiles' in order of creation. */ +-int last_deleted_tempcount; +- + /* During in-core sort, this points to the base of the data block + which contains all the lines of data. */ + char *text_base; +@@ -117,15 +102,9 @@ + determine whether we need initials in the sorted form. */ + char first_initial; + +-/* Additional command switches .*/ +- +-/* Nonzero means do not delete tempfiles -- for debugging. */ +-int keep_tempfiles; +- + /* Forward declarations of functions in this file. */ + void decode_command (int argc, char **argv); + void sort_in_core (char *infile, int total, char *outfile); +-void sort_offline (char *infile, off_t total, char *outfile); + char **parsefile (char *filename, char **nextline, char *data, long int size); + char *find_field (struct keyfield *keyfield, char *str, long int *lengthptr); + char *find_pos (char *str, int words, int chars, int ignore_blanks); +@@ -137,26 +116,17 @@ + long int length1, long int pos1, char *start2, + long int length2, long int pos2); + int compare_full (const void *, const void *); +-long readline (struct linebuffer *linebuffer, FILE *stream); +-int merge_files (char **infiles, int nfiles, char *outfile); +-int merge_direct (char **infiles, int nfiles, char *outfile); + void pfatal_with_name (const char *name); + void fatal (const char *format, const char *arg); + void error (const char *format, const char *arg); + void *xmalloc (), *xrealloc (); +-char *concat (char *s1, char *s2); +-void flush_tempfiles (int to_count); ++static char *concat3 (const char *, const char *, const char *); + +-#define MAX_IN_CORE_SORT 500000 +- + int + main (int argc, char **argv) + { + int i; + +- tempcount = 0; +- last_deleted_tempcount = 0; +- + #ifdef HAVE_SETLOCALE + /* Set locale via LC_ALL. */ + setlocale (LC_ALL, ""); +@@ -220,19 +190,20 @@ + + outfile = outfiles[i]; + if (!outfile) +- outfile = concat (infiles[i], "s"); ++ outfile = concat3 (infiles[i], "s", ""); + + need_initials = 0; + first_initial = '\0'; + +- if (ptr < MAX_IN_CORE_SORT) +- /* Sort a small amount of data. */ +- sort_in_core (infiles[i], (int)ptr, outfile); +- else +- sort_offline (infiles[i], ptr, outfile); ++ if (ptr != (int)ptr) ++ { ++ fprintf (stderr, "%s: %s: file too large\n", program_name, ++ infiles[i]); ++ xexit (1); ++ } ++ sort_in_core (infiles[i], (int)ptr, outfile); + } + +- flush_tempfiles (tempcount); + xexit (0); + return 0; /* Avoid bogus warnings. */ + } +@@ -250,10 +221,6 @@ + TEXINDEX_OPTION texindex_options[] = { + { "--help", "-h", (int *)NULL, 0, (char *)NULL, + N_("display this help and exit") }, +- { "--keep", "-k", &keep_tempfiles, 1, (char *)NULL, +- N_("keep temporary files around after processing") }, +- { "--no-keep", 0, &keep_tempfiles, 0, (char *)NULL, +- N_("do not keep temporary files around after processing (default)") }, + { "--output", "-o", (int *)NULL, 0, "FILE", + N_("send output to FILE") }, + { "--version", (char *)NULL, (int *)NULL, 0, (char *)NULL, +@@ -308,20 +275,6 @@ + char **ip; + char **op; + +- /* Store default values into parameter variables. */ +- +- tempdir = getenv ("TMPDIR"); +- if (tempdir == NULL) +- tempdir = getenv ("TEMP"); +- if (tempdir == NULL) +- tempdir = getenv ("TMP"); +- if (tempdir == NULL) +- tempdir = DEFAULT_TMPDIR; +- else +- tempdir = concat (tempdir, "/"); +- +- keep_tempfiles = 0; +- + /* Allocate ARGC input files, which must be enough. */ + + infiles = (char **) xmalloc (argc * sizeof (char *)); +@@ -349,7 +302,7 @@ + else if ((strcmp (arg, "--keep") == 0) || + (strcmp (arg, "-k") == 0)) + { +- keep_tempfiles = 1; ++ /* Ignore, for backward compatibility */ + } + else if ((strcmp (arg, "--help") == 0) || + (strcmp (arg, "-h") == 0)) +@@ -385,41 +338,6 @@ + usage (1); + } + +-/* Return a name for temporary file COUNT. */ +- +-static char * +-maketempname (int count) +-{ +- static char *tempbase = NULL; +- char tempsuffix[10]; +- +- if (!tempbase) +- { +- int fd; +- tempbase = concat (tempdir, "txidxXXXXXX"); +- +- fd = mkstemp (tempbase); +- if (fd == -1) +- pfatal_with_name (tempbase); +- } +- +- sprintf (tempsuffix, ".%d", count); +- return concat (tempbase, tempsuffix); +-} +- +- +-/* Delete all temporary files up to TO_COUNT. */ +- +-void +-flush_tempfiles (int to_count) +-{ +- if (keep_tempfiles) +- return; +- while (last_deleted_tempcount < to_count) +- unlink (maketempname (++last_deleted_tempcount)); +-} +- +- + /* Compare LINE1 and LINE2 according to the specified set of keyfields. */ + + int +@@ -802,150 +720,6 @@ + } + } + +-/* A `struct linebuffer' is a structure which holds a line of text. +- `readline' reads a line from a stream into a linebuffer +- and works regardless of the length of the line. */ +- +-struct linebuffer +-{ +- long size; +- char *buffer; +-}; +- +-/* Initialize LINEBUFFER for use. */ +- +-void +-initbuffer (struct linebuffer *linebuffer) +-{ +- linebuffer->size = 200; +- linebuffer->buffer = (char *) xmalloc (200); +-} +- +-/* Read a line of text from STREAM into LINEBUFFER. +- Return the length of the line. */ +- +-long +-readline (struct linebuffer *linebuffer, FILE *stream) +-{ +- char *buffer = linebuffer->buffer; +- char *p = linebuffer->buffer; +- char *end = p + linebuffer->size; +- +- while (1) +- { +- int c = getc (stream); +- if (p == end) +- { +- buffer = (char *) xrealloc (buffer, linebuffer->size *= 2); +- p += buffer - linebuffer->buffer; +- end += buffer - linebuffer->buffer; +- linebuffer->buffer = buffer; +- } +- if (c < 0 || c == '\n') +- { +- *p = 0; +- break; +- } +- *p++ = c; +- } +- +- return p - buffer; +-} +- +-/* Sort an input file too big to sort in core. */ +- +-void +-sort_offline (char *infile, off_t total, char *outfile) +-{ +- /* More than enough. */ +- int ntemps = 2 * (total + MAX_IN_CORE_SORT - 1) / MAX_IN_CORE_SORT; +- char **tempfiles = (char **) xmalloc (ntemps * sizeof (char *)); +- FILE *istream = fopen (infile, "r"); +- int i; +- struct linebuffer lb; +- long linelength; +- int failure = 0; +- +- initbuffer (&lb); +- +- /* Read in one line of input data. */ +- +- linelength = readline (&lb, istream); +- +- if (lb.buffer[0] != '\\' && lb.buffer[0] != '@') +- { +- error (_("%s: not a texinfo index file"), infile); +- return; +- } +- +- /* Split up the input into `ntemps' temporary files, or maybe fewer, +- and put the new files' names into `tempfiles' */ +- +- for (i = 0; i < ntemps; i++) +- { +- char *outname = maketempname (++tempcount); +- FILE *ostream = fopen (outname, "w"); +- long tempsize = 0; +- +- if (!ostream) +- pfatal_with_name (outname); +- tempfiles[i] = outname; +- +- /* Copy lines into this temp file as long as it does not make file +- "too big" or until there are no more lines. */ +- +- while (tempsize + linelength + 1 <= MAX_IN_CORE_SORT) +- { +- tempsize += linelength + 1; +- fputs (lb.buffer, ostream); +- putc ('\n', ostream); +- +- /* Read another line of input data. */ +- +- linelength = readline (&lb, istream); +- if (!linelength && feof (istream)) +- break; +- +- if (lb.buffer[0] != '\\' && lb.buffer[0] != '@') +- { +- error (_("%s: not a texinfo index file"), infile); +- failure = 1; +- goto fail; +- } +- } +- fclose (ostream); +- if (feof (istream)) +- break; +- } +- +- free (lb.buffer); +- +-fail: +- /* Record number of temp files we actually needed. */ +- +- ntemps = i; +- +- /* Sort each tempfile into another tempfile. +- Delete the first set of tempfiles and put the names of the second +- into `tempfiles'. */ +- +- for (i = 0; i < ntemps; i++) +- { +- char *newtemp = maketempname (++tempcount); +- sort_in_core (tempfiles[i], MAX_IN_CORE_SORT, newtemp); +- if (!keep_tempfiles) +- unlink (tempfiles[i]); +- tempfiles[i] = newtemp; +- } +- +- if (failure) +- return; +- +- /* Merge the tempfiles together and indexify. */ +- +- merge_files (tempfiles, ntemps, outfile); +-} +- + /* Sort INFILE, whose size is TOTAL, + assuming that is small enough to be done in-core, + then indexify it and send the output to OUTFILE (or to stdout). */ +@@ -1349,8 +1123,7 @@ + + for (next_line = linearray; next_line != stop_line; next_line++) + { +- /* If -u was specified, output the line only if distinct from +- previous one. */ ++ /* Output the line only if distinct from previous one. */ + if (next_line == linearray + /* Compare previous line with this one, using only the + explicitly specd keyfields. */ +@@ -1370,215 +1143,6 @@ + finish_index (ostream); + } + +-/* Assume (and optionally verify) that each input file is sorted; +- merge them and output the result. +- Returns nonzero if any input file fails to be sorted. +- +- This is the high-level interface that can handle an unlimited +- number of files. */ +- +-#define MAX_DIRECT_MERGE 10 +- +-int +-merge_files (char **infiles, int nfiles, char *outfile) +-{ +- char **tempfiles; +- int ntemps; +- int i; +- int value = 0; +- int start_tempcount = tempcount; +- +- if (nfiles <= MAX_DIRECT_MERGE) +- return merge_direct (infiles, nfiles, outfile); +- +- /* Merge groups of MAX_DIRECT_MERGE input files at a time, +- making a temporary file to hold each group's result. */ +- +- ntemps = (nfiles + MAX_DIRECT_MERGE - 1) / MAX_DIRECT_MERGE; +- tempfiles = (char **) xmalloc (ntemps * sizeof (char *)); +- for (i = 0; i < ntemps; i++) +- { +- int nf = MAX_DIRECT_MERGE; +- if (i + 1 == ntemps) +- nf = nfiles - i * MAX_DIRECT_MERGE; +- tempfiles[i] = maketempname (++tempcount); +- value |= merge_direct (&infiles[i * MAX_DIRECT_MERGE], nf, tempfiles[i]); +- } +- +- /* All temporary files that existed before are no longer needed +- since their contents have been merged into our new tempfiles. +- So delete them. */ +- flush_tempfiles (start_tempcount); +- +- /* Now merge the temporary files we created. */ +- +- merge_files (tempfiles, ntemps, outfile); +- +- free (tempfiles); +- +- return value; +-} +- +-/* Assume (and optionally verify) that each input file is sorted; +- merge them and output the result. +- Returns nonzero if any input file fails to be sorted. +- +- This version of merging will not work if the number of +- input files gets too high. Higher level functions +- use it only with a bounded number of input files. */ +- +-int +-merge_direct (char **infiles, int nfiles, char *outfile) +-{ +- struct linebuffer *lb1, *lb2; +- struct linebuffer **thisline, **prevline; +- FILE **streams; +- int i; +- int nleft; +- int lossage = 0; +- int *file_lossage; +- struct linebuffer *prev_out = 0; +- FILE *ostream = stdout; +- +- if (outfile) +- { +- ostream = fopen (outfile, "w"); +- } +- if (!ostream) +- pfatal_with_name (outfile); +- +- init_index (); +- +- if (nfiles == 0) +- { +- if (outfile) +- fclose (ostream); +- return 0; +- } +- +- /* For each file, make two line buffers. Also, for each file, there +- is an element of `thisline' which points at any time to one of the +- file's two buffers, and an element of `prevline' which points to +- the other buffer. `thisline' is supposed to point to the next +- available line from the file, while `prevline' holds the last file +- line used, which is remembered so that we can verify that the file +- is properly sorted. */ +- +- /* lb1 and lb2 contain one buffer each per file. */ +- lb1 = (struct linebuffer *) xmalloc (nfiles * sizeof (struct linebuffer)); +- lb2 = (struct linebuffer *) xmalloc (nfiles * sizeof (struct linebuffer)); +- +- /* thisline[i] points to the linebuffer holding the next available +- line in file i, or is zero if there are no lines left in that file. */ +- thisline = (struct linebuffer **) +- xmalloc (nfiles * sizeof (struct linebuffer *)); +- /* prevline[i] points to the linebuffer holding the last used line +- from file i. This is just for verifying that file i is properly +- sorted. */ +- prevline = (struct linebuffer **) +- xmalloc (nfiles * sizeof (struct linebuffer *)); +- /* streams[i] holds the input stream for file i. */ +- streams = (FILE **) xmalloc (nfiles * sizeof (FILE *)); +- /* file_lossage[i] is nonzero if we already know file i is not +- properly sorted. */ +- file_lossage = (int *) xmalloc (nfiles * sizeof (int)); +- +- /* Allocate and initialize all that storage. */ +- +- for (i = 0; i < nfiles; i++) +- { +- initbuffer (&lb1[i]); +- initbuffer (&lb2[i]); +- thisline[i] = &lb1[i]; +- prevline[i] = &lb2[i]; +- file_lossage[i] = 0; +- streams[i] = fopen (infiles[i], "r"); +- if (!streams[i]) +- pfatal_with_name (infiles[i]); +- +- readline (thisline[i], streams[i]); +- } +- +- /* Keep count of number of files not at eof. */ +- nleft = nfiles; +- +- while (nleft) +- { +- struct linebuffer *best = 0; +- struct linebuffer *exch; +- int bestfile = -1; +- int i; +- +- /* Look at the next avail line of each file; choose the least one. */ +- +- for (i = 0; i < nfiles; i++) +- { +- if (thisline[i] && +- (!best || +- 0 < compare_general (best->buffer, thisline[i]->buffer, +- (long) bestfile, (long) i, num_keyfields))) +- { +- best = thisline[i]; +- bestfile = i; +- } +- } +- +- /* Output that line, unless it matches the previous one and we +- don't want duplicates. */ +- +- if (!(prev_out && +- !compare_general (prev_out->buffer, +- best->buffer, 0L, 1L, num_keyfields - 1))) +- indexify (best->buffer, ostream); +- prev_out = best; +- +- /* Now make the line the previous of its file, and fetch a new +- line from that file. */ +- +- exch = prevline[bestfile]; +- prevline[bestfile] = thisline[bestfile]; +- thisline[bestfile] = exch; +- +- while (1) +- { +- /* If the file has no more, mark it empty. */ +- +- if (feof (streams[bestfile])) +- { +- thisline[bestfile] = 0; +- /* Update the number of files still not empty. */ +- nleft--; +- break; +- } +- readline (thisline[bestfile], streams[bestfile]); +- if (thisline[bestfile]->buffer[0] || !feof (streams[bestfile])) +- break; +- } +- } +- +- finish_index (ostream); +- +- /* Free all storage and close all input streams. */ +- +- for (i = 0; i < nfiles; i++) +- { +- fclose (streams[i]); +- free (lb1[i].buffer); +- free (lb2[i].buffer); +- } +- free (file_lossage); +- free (lb1); +- free (lb2); +- free (thisline); +- free (prevline); +- free (streams); +- +- if (outfile) +- fclose (ostream); +- +- return lossage; +-} +- + /* Print error message and exit. */ + + void +@@ -1613,17 +1177,18 @@ + } + + +-/* Return a newly-allocated string concatenating S1 and S2. */ ++/* Return a newly-allocated string concatenating S1, S2, and S3. */ + +-char * +-concat (char *s1, char *s2) ++static char * ++concat3 (const char *s1, const char *s2, const char *s3) + { +- int len1 = strlen (s1), len2 = strlen (s2); +- char *result = (char *) xmalloc (len1 + len2 + 1); ++ int len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3); ++ char *result = (char *) xmalloc (len1 + len2 + len3 + 1); + + strcpy (result, s1); + strcpy (result + len1, s2); +- *(result + len1 + len2) = 0; ++ strcpy (result + len1 + len2, s3); ++ *(result + len1 + len2 + len3) = 0; + + return result; + } -- http://linuxfromscratch.org/mailman/listinfo/patches FAQ: http://www.linuxfromscratch.org/faq/ Unsubscribe: See the above information page
