Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 250261 Details for
Bug 368611
CVE-2007-5936 dviljk uses insecure temporary file
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
A patch without the whitespace-wipe hunks, from Gentoo
dviljk-overflows-tmprace-2.patch (text/plain), 33.29 KB, created by
Lubomir Kundrak
on 2007-11-07 15:38:01 UTC
(
hide
)
Description:
A patch without the whitespace-wipe hunks, from Gentoo
Filename:
MIME Type:
Creator:
Lubomir Kundrak
Created:
2007-11-07 15:38:01 UTC
Size:
33.29 KB
patch
obsolete
>Index: work/texk/dviljk/ChangeLog >=================================================================== >--- work.orig/texk/dviljk/ChangeLog >+++ work/texk/dviljk/ChangeLog >@@ -1,3 +1,42 @@ >+2007-07-02 Joachim Schrod <jschrod@acm.org> >+ >+ * dvi2xx.c (DoSpecial): Security issue: usage of tmpnam() caused >+ tempfile race condition. I use mkdtemp() if it's available and >+ fall back to tmpnam. >+ >+ Special parsing of include files was inconsistent, unify it. The >+ current parsing code still allows lots of non-sensical special >+ commands, but at least it doesn't access unrelated variables any >+ more. >+ >+2007-06-28 Joachim Schrod <jschrod@acm.org> >+ >+ * dvi2xx.c: Fixed a whole bunch of buffer overflows: The program >+ did not check memory bounds for any string operation. All places >+ where strings are copied with strcpy are replaced by dynamically >+ allocated strings (with xstrdup from kpathsea) or bounded string >+ operations. Fixed also manual string copy operations on special >+ strings. Fixed array buffer overflow in defpoint and fill special >+ operations. >+ (DoSpecial): Call of ghostscript for psfile special had also a >+ potential buffer overflow caused by unchecked usage of sprintf. >+ Fix core dump: Check if all required parameters of psfile special >+ are passed. >+ >+ Bumped version number up to 2.6p3. >+ >+ * dvi2xx.h: Some fixed sized string arrays are pointers now, they >+ get dynamically allocated. >+ (GetBytes): Another buffer overflow: Check that the buffer size is >+ sufficient to store the read bytes. That relies on the invariant >+ that the GetBytes macro is always called with an array as argument >+ and not with a pointer. >+ >+ * config.h: Throw an error if kpathsea is not used. dvi2xx.c >+ had previously already kpathsea dependencies without protecting >+ them with #if KPATHSEA. We go that road further since upstream >+ does not exist any more. >+ > 2006-05-29 Karl Berry <karl@tug.org> > > * Makefile.in (install-exec): cd $(bindir) in case we are doing >Index: work/texk/dviljk/c-auto.in >=================================================================== >--- work.orig/texk/dviljk/c-auto.in >+++ work/texk/dviljk/c-auto.in >@@ -1,9 +1,23 @@ >-/* c-auto.in. Generated automatically from configure.in by autoheader. */ >+/* c-auto.in. Generated from configure.in by autoheader. */ >+/* acconfig.h -- used by autoheader when generating c-auto.in. > >-/* Define if type char is unsigned and you are not using gcc. */ >-#ifndef __CHAR_UNSIGNED__ >-#undef __CHAR_UNSIGNED__ >-#endif >+ If you're thinking of editing acconfig.h to fix a configuration >+ problem, don't. Edit the c-auto.h file created by configure, >+ instead. Even better, fix configure to give the right answer. */ >+ >+/* Define to 1 if you have the `mkdtemp' function. */ >+#undef HAVE_MKDTEMP >+ >+/* Define to 1 if you have the `rmdir' function. */ >+#undef HAVE_RMDIR > >-/* The number of bytes in a long. */ >+/* Define to 1 if you have the `unlink' function. */ >+#undef HAVE_UNLINK >+ >+/* The size of a `long', as computed by sizeof. */ > #undef SIZEOF_LONG >+ >+/* Define to 1 if type `char' is unsigned and you are not using gcc. */ >+#ifndef __CHAR_UNSIGNED__ >+# undef __CHAR_UNSIGNED__ >+#endif >Index: work/texk/dviljk/config.h >=================================================================== >--- work.orig/texk/dviljk/config.h >+++ work/texk/dviljk/config.h >@@ -216,12 +216,7 @@ typedef SCHAR_TYPE signed_char; > #endif > > #ifndef KPATHSEA >-extern bool findfile( >-#if NeedFunctionPrototypes >-char path[], char n[], long4 fontmag, char name[], >- bool tfm, int level >-#endif >- ); >+#error "Would need changed findfile, dviljk has changed allocation semantic of name member in tfontptr" > #endif > > >@@ -444,3 +439,24 @@ typedef FILE *FILEPTR; > /* If we have neither, should fall back to fprintf with fixed args. */ > #endif > #endif >+ >+/* If unlink and rmdir are not there, we don't delete the temporary files. */ >+#ifndef HAVE_RMDIR >+#define rmdir(dir) >+#endif >+#ifndef HAVE_UNLINK >+#define unlink(file) >+#endif >+ >+/* If mkdtemp() does not exist, we have to use tmpnam(). */ >+#ifndef HAVE_MKDTEMP >+#define mkdtemp(dir) (tmpnam(dir) ? \ >+ ( mkdir(dir, 0700) == -1 ? NULL : dir ) : \ >+ ( errno = EINVAL, NULL ) ) >+#endif >+ >+#ifndef KPATHSEA >+/* FIXME: Should provide a strdup function. But currently this tree is >+ only used in connection with kpathsea anyhow. */ >+#error "Need xstrdup and xmalloc function, e.g. from kpathsea" >+#endif >Index: work/texk/dviljk/configure >=================================================================== >--- work.orig/texk/dviljk/configure >+++ work/texk/dviljk/configure >@@ -1283,6 +1283,62 @@ EOF > > > >+for ac_func in rmdir unlink mkdtemp >+do >+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 >+echo "configure:1290: checking for $ac_func" >&5 >+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then >+ echo $ac_n "(cached) $ac_c" 1>&6 >+else >+ cat > conftest.$ac_ext <<EOF >+#line 1295 "configure" >+#include "confdefs.h" >+/* System header to define __stub macros and hopefully few prototypes, >+ which can conflict with char $ac_func(); below. */ >+#include <assert.h> >+/* Override any gcc2 internal prototype to avoid an error. */ >+/* We use char because int might match the return type of a gcc2 >+ builtin and then its argument prototype would still apply. */ >+char $ac_func(); >+ >+int main() { >+ >+/* The GNU C library defines this for functions which it implements >+ to always fail with ENOSYS. Some functions are actually named >+ something starting with __ and the normal name is an alias. */ >+#if defined (__stub_$ac_func) || defined (__stub___$ac_func) >+choke me >+#else >+$ac_func(); >+#endif >+ >+; return 0; } >+EOF >+if { (eval echo configure:1318: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then >+ rm -rf conftest* >+ eval "ac_cv_func_$ac_func=yes" >+else >+ echo "configure: failed program was:" >&5 >+ cat conftest.$ac_ext >&5 >+ rm -rf conftest* >+ eval "ac_cv_func_$ac_func=no" >+fi >+rm -f conftest* >+fi >+ >+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then >+ echo "$ac_t""yes" 1>&6 >+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` >+ cat >> confdefs.h <<EOF >+#define $ac_tr_func 1 >+EOF >+ >+else >+ echo "$ac_t""no" 1>&6 >+fi >+done >+ >+ > ac_config_files="$ac_config_files Makefile" > > trap '' 1 2 15 >Index: work/texk/dviljk/configure.in >=================================================================== >--- work.orig/texk/dviljk/configure.in >+++ work/texk/dviljk/configure.in >@@ -14,5 +14,7 @@ dnl These tests prevent reliable cross-c > AC_C_CHAR_UNSIGNED > AC_CHECK_SIZEOF(long) > >+AC_CHECK_FUNCS(rmdir unlink mkdtemp) >+ > KPSE_CONFIG_FILES([Makefile]) > AC_OUTPUT >Index: work/texk/dviljk/dvi2xx.c >=================================================================== >--- work.orig/texk/dviljk/dvi2xx.c >+++ work/texk/dviljk/dvi2xx.c >@@ -1,5 +1,5 @@ > /* $Id: dvi2xx.c,v 2.5 1997/12/08 20:52:20 neumann Exp $ */ >-#define VERSION "2.6p2 (dviljk)" >+#define VERSION "dviljk (version 2.6p3)" > /* > #define DEBUGGS 1 > */ >@@ -173,7 +173,7 @@ char *argv[]; > y_origin = YDEFAULTOFF; /* y-origin in dots */ > > setbuf(ERR_STREAM, NULL); >- (void) strcpy(G_progname, argv[0]); >+ G_progname = argv[0]; > #ifdef KPATHSEA > kpse_set_progname(argv[0]); > kpse_set_program_enabled (kpse_pk_format, MAKE_TEX_PK_BY_DEFAULT, kpse_src_compile); >@@ -2968,8 +2968,8 @@ char *argv[]; > #endif > { > int argind; /* argument index for flags */ >- char curarea[STRSIZE]; /* current file area */ >- char curname[STRSIZE]; /* current file name */ >+ char *curarea; /* current file area */ >+ char *curname; /* current file name */ > char *tcp, *tcp1; /* temporary character pointers */ > char *this_arg; > double x_offset = 0.0, y_offset = 0.0; >@@ -2988,9 +2988,9 @@ char *argv[]; > #endif > #endif > >- if (argc == 2 && (strcmp (argv[1], "--version") == 0)) { >+ if (argc == 2 && EQ(argv[1], "--version")) { > extern KPSEDLL char *kpathsea_version_string; >- puts ("dvilj(k) 2.6"); >+ puts (VERSION); > puts (kpathsea_version_string); > puts ("Copyright (C) 1997 Gustaf Neumann.\n\ > There is NO warranty. You may redistribute this software\n\ >@@ -3328,8 +3328,8 @@ Primary author of Dvi2xx: Gustaf Neumann > } > } else { > >- (void) strcpy(filename, tcp); >- if (!strcmp(filename, "-")) { >+ filename = tcp; >+ if (EQ(filename, "-")) { > EmitFileName = "-"; > #ifdef RISC_USE_OSL > dvifp = BINOPEN("Kbd:"); >@@ -3339,57 +3339,68 @@ Primary author of Dvi2xx: Gustaf Neumann > AssureBinary(fileno(dvifp)); > #endif > } else { >+ /* Since this code is used only once during startup, we don't care >+ about free()ing the allocated strings that represent filenames. >+ It will be more work to realize proper deallocation handling than >+ it's worth in terms of saving a few bytes. We consider these >+ bytes actually static memory where we don't know the size in >+ advance and don't add them to the allocated_storage count. >+ [27 Jun 07 -js] */ > #ifdef KPATHSEA > /* split into directory + file name */ > int tcplen, argvlen; > tcp = (char *)xbasename(argv[argind]);/* this knows about any kind of slashes */ > tcplen = strlen(tcp); >+ if ( tcplen == 0 ) { >+ /* This happens when the DVI file name has a trailing slash; this >+ is not a valid name. Then we terminate the argument parsing >+ loop, a usage message will be output below. */ >+ break; >+ } > argvlen = strlen(argv[argind]); > if (tcplen == argvlen) >- curarea[0] = '\0'; >+ curarea = ""; > else { >- (void) strcpy(curarea, argv[argind]); >+ curarea = xstrdup(argv[argind]); > curarea[argvlen-tcplen] = '\0'; > } > #else > tcp = strrchr(argv[argind], '/'); > /* split into directory + file name */ > if (tcp == NULL) { >- curarea[0] = '\0'; >+ curarea[0] = ""; > tcp = argv[argind]; > } else { >- (void) strcpy(curarea, argv[argind]); >+ curarea = xstrdup(argv[argind]); > curarea[tcp-argv[argind]+1] = '\0'; > tcp += 1; > } > #endif > >+ curname = (char *) xmalloc(strlen(tcp)+5); /* + space for ".dvi" */ > (void) strcpy(curname, tcp); > /* split into file name + extension */ >- tcp1 = strrchr(tcp, '.'); >+ tcp1 = strrchr(curname, '.'); > if (tcp1 == NULL) { >- (void) strcpy(rootname, curname); >+ rootname = xstrdup(curname); > strcat(curname, ".dvi"); > } else { > *tcp1 = '\0'; >- (void) strcpy(rootname, curname); >+ rootname = xstrdup(curname); > *tcp1 = '.'; > } > >+ filename = (char *) xmalloc(strlen(curarea)+strlen(curname)+1); > (void) strcpy(filename, curarea); > (void) strcat(filename, curname); > > if ((dvifp = BINOPEN(filename)) == FPNULL) { > /* do not insist on .dvi */ > if (tcp1 == NULL) { >- int l = strlen(curname); >- if (l > 4) >- curname[l - 4] = '\0'; >- l = strlen(filename); >- if (l > 4) >- filename[l - 4] = '\0'; >+ filename[strlen(filename) - 4] = '\0'; >+ dvifp = BINOPEN(filename); > } >- if (tcp1 != NULL || (dvifp = BINOPEN(filename)) == FPNULL) { >+ if (dvifp == FPNULL) { > #ifdef MSC5 > Fatal("%s: can't find DVI file \"%s\"\n\n", > G_progname, filename); >@@ -3411,7 +3422,7 @@ Primary author of Dvi2xx: Gustaf Neumann > y_goffset = (short) MM_TO_PXL(y_offset) + y_origin; > > if (dvifp == FPNULL) { >- fprintf(ERR_STREAM,"\nThis is the DVI to %s converter version %s", >+ fprintf(ERR_STREAM,"\nThis is the DVI to %s converter %s", > PRINTER, VERSION); > #ifdef SEVENBIT > fprintf(ERR_STREAM,", 7bit"); >@@ -3507,13 +3518,8 @@ Primary author of Dvi2xx: Gustaf Neumann > exit(1); > } > if (EQ(EmitFileName, "")) { >- if ((EmitFileName = (char *)malloc( STRSIZE )) != NULL) >- allocated_storage += STRSIZE; >- else >- Fatal("Can't allocate storage of %d bytes\n",STRSIZE); >- (void) strcpy(EmitFileName, curname); >- if ((tcp1 = strrchr(EmitFileName, '.'))) >- *tcp1 = '\0'; >+ EmitFileName = (char *) xmalloc(strlen(rootname)+sizeof(EMITFILE_EXTENSION)); >+ (void) strcpy(EmitFileName, rootname); > strcat(EmitFileName, EMITFILE_EXTENSION); > } > if (G_quiet) >@@ -3698,6 +3704,8 @@ bool PFlag; > #endif > } > CloseFiles(); >+ if ( tmp_dir[0] != '\0' ) >+ rmdir (tmp_dir); /* ignore errors */ > exit(G_errenc); > } > >@@ -3895,22 +3903,21 @@ char *str; > int n; > #endif > { >- char spbuf[STRSIZE], xs[STRSIZE], ys[STRSIZE]; >- char *sf = NULL, *psfile = NULL; >+ char xs[STRSIZE], ys[STRSIZE]; >+ char *include_file = NULL; >+ enum { VerbFile, HPFile, PSFile } file_type; > float x,y; > long4 x_pos, y_pos; > KeyWord k; > int i, j, j1; > static int GrayScale = 10, Pattern = 1; > static bool GrayFill = _TRUE; >- static long4 p_x[80], p_y[80]; >- int llx=0, lly=0, urx=0, ury=0, rwi=0, rhi=0; >-#ifdef WIN32 >- char *gs_path; >-#endif >+ static long4 p_x[MAX_SPECIAL_DEFPOINTS], p_y[MAX_SPECIAL_DEFPOINTS]; >+ int llx=0, lly=0, urx=0, ury=0, rwi=0; > > str[n] = '\0'; >- spbuf[0] = '\0'; >+ for ( i=0 ; i<MAX_SPECIAL_DEFPOINTS ; i++ ) >+ p_x[i] = p_y[i] = -1; > > SetPosn(h, v); > #ifdef __riscos >@@ -3924,41 +3931,30 @@ int n; > /* get all keyword-value pairs */ > /* for compatibility, single words are taken as file names */ > if ( k.vt == None && access(k.Key, 0) == 0) { >- if ( sf >-#ifdef KPATHSEA >- && !kpse_tex_hush ("special") >-#endif >- ) >- Warning("More than one \\special file name given. %s ignored", sf); >- (void) strcpy(spbuf, k.Key); >- sf = spbuf; >- /* >- for (j = 1; ((sf[j]=='/' ? sf[j]='\\':sf[j]) != '\0'); j++); >- */ >- } else if ( GetKeyVal( &k, KeyTab, NKEYS, &i ) && i != -1 ) >+ if ( include_file && !kpse_tex_hush ("special") ) { >+ Warning("More than one \\special file name given. %s ignored", include_file); >+ free (include_file); >+ } >+ include_file = xstrdup(k.Key); >+ file_type = VerbFile; >+ } else if ( GetKeyVal( &k, KeyTab, NKEYS, &i ) && i != -1 ) { > switch (i) { > case PSFILE: >- if (sf >-#ifdef KPATHSEA >- && !kpse_tex_hush ("special") >-#endif >- ) >- Warning("More than one \\special file name given. %s ignored", sf); >- (void) strcpy(spbuf, k.Val); >- psfile = spbuf; >- /* >- for (j=1; ((sf[j]=='/' ? sf[j]='\\':sf[j]) != '\0'); j++); >- */ >+ if ( include_file ) { >+ Warning("More than one \\special file name given. %s ignored", include_file); >+ free(include_file); >+ } >+ include_file = xstrdup(k.Val); >+ file_type = PSFile; > break; > > case HPFILE: >- if (sf) >- Warning("More than one \\special file name given. %s ignored", sf); >- (void) strcpy(spbuf, k.Val); >- sf = spbuf; >- /* >- for (j=1; ((sf[j]=='/' ? sf[j]='\\':sf[j]) != '\0'); j++); >- */ >+ if ( include_file && !kpse_tex_hush ("special") ) { >+ Warning("More than one \\special file name given. %s ignored", include_file); >+ free(include_file); >+ } >+ include_file = xstrdup(k.Val); >+ file_type = HPFile; > break; > > case ORIENTATION: >@@ -3978,23 +3974,24 @@ int n; > } > #endif > else >-#ifdef KPATHSEA >- if (!kpse_tex_hush ("special")) >-#endif > Warning( "Invalid orientation (%d)given; ignored.", k.v.i); > break; > > case RESETPOINTS: >- (void) strcpy(spbuf, k.Val); >- >- sf = NULL; >+ for ( i=0 ; i<MAX_SPECIAL_DEFPOINTS ; i++ ) >+ p_x[i] = p_y[i] = -1; > break; > > case DEFPOINT: >- (void) strcpy(spbuf, k.Val); >- i = sscanf(spbuf,"%d(%[^,],%s)",&j,xs,ys); >+ /* 254 is STRSIZE-1. cpp should be used to construct that number. */ >+ i = sscanf(k.Val,"%d(%254[^,],%254s)",&j,xs,ys); > if (i>0) { >- x_pos = h; >+ if ( j < 0 || j >= MAX_SPECIAL_DEFPOINTS ) { >+ Warning ("defpoint %d ignored, must be between 0 and %d", >+ j, MAX_SPECIAL_DEFPOINTS); >+ break; >+ } >+ x_pos = h; > y_pos = v; > if (i>1) { > if (sscanf(xs,"%fpt",&x)>0) { >@@ -4011,19 +4008,32 @@ int n; > p_x[j]=x_pos; > p_y[j]=y_pos; > } else >-#ifdef KPATHSEA >- if (!kpse_tex_hush ("special")) >-#endif > Warning("invalid point definition\n"); >- >- sf = NULL; > break; > > case FILL: >- (void) strcpy(spbuf, k.Val); >- i = sscanf(spbuf,"%d/%d %s",&j,&j1,xs); >+ /* 254 is STRSIZE-1. cpp should be used to construct that number. */ >+ i = sscanf(k.Val,"%d/%d %254s",&j,&j1,xs); > if (i>1) { > #ifdef LJ >+ if ( j < 0 || j >= MAX_SPECIAL_DEFPOINTS ) { >+ Warning ("fill ignored, point %d must be between 0 and %d", >+ j, MAX_SPECIAL_DEFPOINTS); >+ break; >+ } >+ if ( p_x[j] == -1 ) { >+ Warning ("fill ignored, point %d is undefined\n", j); >+ break; >+ } >+ if ( j1 < 0 || j1 >= MAX_SPECIAL_DEFPOINTS ) { >+ Warning ("fill ignored, point %d must be between 0 and %d", >+ j1, MAX_SPECIAL_DEFPOINTS); >+ break; >+ } >+ if ( p_x[j1] == -1 ) { >+ Warning ("fill ignored, point %d is undefined\n", j1); >+ break; >+ } > SetPosn(p_x[j], p_y[j]); > x_pos = (long4)PIXROUND(p_x[j1]-p_x[j], hconv); > y_pos = (long4)PIXROUND(p_y[j1]-p_y[j], vconv); >@@ -4044,9 +4054,6 @@ int n; > GrayScale = k.v.i; > GrayFill = _TRUE; > } else >-#ifdef KPATHSEA >- if (!kpse_tex_hush ("special")) >-#endif > Warning( "Invalid gray scale (%d) given; ignored.", k.v.i); > break; > >@@ -4055,9 +4062,6 @@ int n; > Pattern = k.v.i; > GrayFill = _FALSE; > } else >-#ifdef KPATHSEA >- if (!kpse_tex_hush ("special")) >-#endif > Warning( "Invalid pattern (%d) given; ignored.", k.v.i); > break; > >@@ -4066,75 +4070,123 @@ int n; > case URX: urx = k.v.i; break; > case URY: ury = k.v.i; break; > case RWI: rwi = k.v.i; break; >- case RHI: rhi = k.v.i; break; >+ case RHI: >+ if (!kpse_tex_hush ("special")) >+ Warning("Whatever rhi was good for once, it is ignored now."); >+ break; > > default: >-#ifdef KPATHSEA >- if (!kpse_tex_hush ("special")) >-#endif >+ if ( !kpse_tex_hush ("special") ) > Warning("Can't handle %s=%s command; ignored.", k.Key, k.Val); > break; > } >- >- else >-#ifdef KPATHSEA >- if (!kpse_tex_hush ("special")) >-#endif >+ >+ } else if (!kpse_tex_hush ("special")) { > Warning("Invalid keyword or value in \\special - <%s> ignored", k.Key); >+ } >+ >+ free (k.Key); >+ if ( k.Val != NULL ) free(k.Val); > } > >- if ( sf || psfile ) { >+ if ( include_file ) { > last_rx = last_ry = UNKNOWN; > #ifdef IBM3812 > PMPflush; > #endif >- if (sf) { >- if (i == HPFILE) >- CopyHPFile( sf ); >- else >- CopyFile( sf ); >- } >- else >+ > #ifdef LJ >- if (psfile) { >+ if ( file_type == PSFile) { > /* int height = rwi * (urx - llx) / (ury - lly);*/ > int width = urx - llx; > int height = ury - lly; > char cmd[255]; >- int scale_factor = 3000 * width / rwi; >- int adjusted_height = height * 300/scale_factor; >- int adjusted_llx = llx * 300/scale_factor; >+ char *cmd_format = "%s -q -dSIMPLE -dSAFER -dNOPAUSE -sDEVICE=%s -sOutputFile=%s %s %s showpage.ps -c quit"; >+ char *gs_cmd; >+ int scale_factor, adjusted_height, adjusted_llx; > char *printer = "ljetplus"; /* use the most stupid one */ > >- >- char scale_file_name[255]; >- char *scale_file = tmpnam(scale_file_name); >- char *pcl_file = tmpnam(NULL); >+ char pcl_file[STRSIZE]; >+ char scale_file[STRSIZE]; > FILEPTR scalef; > >- if ( (scalef = BOUTOPEN(scale_file)) == FPNULL ) { >- Warning("Unable to open file %s for writing", scale_file ); >- return; >- } >- fprintf(scalef, "%.2f %.2f scale\n%d %d translate\n", >- 300.0/scale_factor, 300.0/scale_factor, >- 0, adjusted_height == height ? 0 : ury); >- BCLOSE( scalef ); >+ if ( urx == 0 || ury == 0 || rwi == 0 ) { >+ /* Since dvips' psfile special has a different syntax, this might >+ well be one of those specials, i.e., a non-dviljk special. Then >+ the Warning should be suppressable. */ >+ if ( !kpse_tex_hush ("special") ) >+ Warning ("Ignoring psfile special without urx, ury and rwi attributes"); >+ free (include_file); >+ return; >+ } >+ scale_factor = 3000 * width / rwi; >+ adjusted_height = height * 300/scale_factor; >+ adjusted_llx = llx * 300/scale_factor; >+ >+ /* We cannot use mkstemp, as we cannot pass two open file descriptors >+ portably to Ghostscript. We don't want to use tmpnam() or tempnam() >+ either, as they have tempfile creation race conditions. Instead we >+ create a temporary directory with mkdtemp() -- if that's available. >+ If not, we are thrown back to tempnam(), to get our functionality >+ at all. We need to create the temporary directory only once per >+ run; it will be deleted in AllDone(). */ >+ if ( tmp_dir[0] == '\0' ) { >+ char * base_dir; >+ if ( (base_dir = getenv("TMPDIR")) == NULL ) { >+ base_dir = "/tmp"; >+ } else if ( strlen(base_dir) > STRSIZE - sizeof("/dviljkXXXXXX/include.pcl") ) { >+ Warning ("TMPDIR %s is too long, using /tmp instead", base_dir); >+ base_dir = "/tmp"; >+ } >+ if ( base_dir[0] == '/' && base_dir[1] == '\0' ) { >+ Warning ("Feeling naughty, do we? / is no temporary directory, dude"); >+ base_dir = "/tmp"; >+ } >+ strcpy (tmp_dir, base_dir); >+ strcat (tmp_dir, "/dviljkXXXXXX"); >+ if ( mkdtemp(tmp_dir) == NULL ) { >+ Warning ("Could not create temporary directory %s, errno = %d; ignoring include file special", >+ tmp_dir, errno); >+ return; >+ } >+ } >+ strcpy(pcl_file, tmp_dir); >+ strcat(pcl_file, "/include.pcl"); >+ strcpy(scale_file, tmp_dir); >+ strcat(scale_file, "/scale.ps"); >+ >+ if ( (scalef = BOUTOPEN(scale_file)) == FPNULL ) { >+ Warning("Unable to open file %s for writing", scale_file ); >+ free (include_file); >+ unlink(scale_file); /* ignore error */ >+ return; >+ } >+ fprintf(scalef, "%.2f %.2f scale\n%d %d translate\n", >+ 300.0/scale_factor, 300.0/scale_factor, >+ 0, adjusted_height == height ? 0 : ury); >+ BCLOSE( scalef ); > > #ifdef WIN32 >- gs_path = getenv("GS_PATH"); >- if (!gs_path) >- gs_path = "gswin32c.exe"; >- sprintf(cmd,"%s -q -dSIMPLE -dSAFER -dNOPAUSE -sDEVICE=%s -sOutputFile=%s %s %s showpage.ps -c quit", >- gs_path, printer, pcl_file, scale_file, psfile); >+ if ( (gs_cmd = getenv("GS_PATH")) == NULL ) >+ gs_cmd = "gswin32c.exe"; > #else >- sprintf(cmd,"gs -q -dSIMPLE -dSAFER -dNOPAUSE -sDEVICE=%s -sOutputFile=%s %s %s showpage.ps -c quit", >- printer, pcl_file, scale_file, psfile); >+ gs_cmd = "gs"; > #endif >+ if ( strlen(cmd_format)-10 + strlen(gs_cmd) + strlen(printer) + >+ strlen(pcl_file) + strlen(scale_file) + strlen(include_file) +1 > >+ sizeof(cmd) ) { >+ Warning ("Ghostscript command for %s would be too long, skipping special", include_file); >+ free (include_file); >+ unlink(scale_file); /* ignore errors */ >+ unlink(pcl_file); >+ return; >+ } >+ sprintf(cmd, cmd_format, >+ gs_cmd, printer, pcl_file, scale_file, include_file); > #ifdef DEBUGGS > fprintf(stderr, > "PS-file '%s' w=%d, h=%d, urx=%d, ury=%d, llx=%d, lly=%d, rwi=%d\n", >- psfile, urx - llx, height, urx,ury,llx,lly, rwi); >+ include_file, urx - llx, height, urx,ury,llx,lly, rwi); > fprintf(stderr,"%s\n",cmd); > #endif > if (system(cmd)) { >@@ -4158,11 +4210,21 @@ int n; > #endif > > CopyHPFile( pcl_file ); >- /* unlink(pcl_file); */ >- /* unlink(scale_file); */ >- } > } >+ unlink(scale_file); /* ignore errors */ >+ unlink(pcl_file); >+ } >+ else > #endif /* LJ */ >+ >+ if ( file_type == HPFile ) >+ CopyHPFile( include_file ); >+ else if ( file_type == VerbFile ) >+ CopyFile( include_file ); >+ else >+ Warning ("This can't happen: unknown file_type value %d", file_type); >+ >+ if ( include_file != NULL ) free(include_file); > } > } > >@@ -4173,12 +4235,11 @@ int n; > /**********************************************************************/ > /***************************** GetKeyStr ****************************/ > /**********************************************************************/ >-/* extract first keyword-value pair from string (value part may be null) >- * return pointer to remainder of string >- * return NULL if none found >+/* Extract first keyword-value pair from string (value part may be null), >+ * keyword and value are allocated and must be free by caller. >+ * Return pointer to remainder of string, >+ * return NULL if none found. > */ >-char KeyStr[STRSIZE]; >-char ValStr[STRSIZE]; > #if NeedFunctionPrototypes > char *GetKeyStr(char *str, KeyWord *kw ) > #else >@@ -4187,39 +4248,46 @@ char *str; > KeyWord *kw; > #endif > { >- char *s, *k, *v, t; >+ char *s, *start; >+ char save_char, quote_char; > if ( !str ) > return( NULL ); > for (s = str; *s == ' '; s++) > ; /* skip over blanks */ > if (*s == '\0') > return( NULL ); >- for (k = KeyStr; /* extract keyword portion */ >- *s != ' ' && *s != '\0' && *s != '='; >- *k++ = *s++) >- ; >- *k = '\0'; >- kw->Key = KeyStr; >- kw->Val = v = NULL; >+ start = s++; /* start of keyword */ >+ while ( *s != ' ' && *s != '\0' && *s != '=' ) /* locate end */ >+ s++; >+ save_char = *s; >+ *s = '\0'; >+ kw->Key = xstrdup(start); >+ kw->Val = NULL; > kw->vt = None; >- for ( ; *s == ' '; s++) >- ; /* skip over blanks */ >- if ( *s != '=' ) /* look for "=" */ >+ if ( save_char == '\0' ) /* shortcut when we're at the end */ >+ return (s); >+ *s = save_char; /* restore keyword end char */ >+ while ( *s == ' ' ) s++ ; /* skip over blanks */ >+ if ( *s != '=' ) /* no "=" means no value */ > return( s ); >- for (s++; *s == ' '; s++); /* skip over blanks */ >- if ( *s == '\'' || *s == '\"' ) /* get string delimiter */ >- t = *s++; >+ for (s++; *s == ' '; s++) >+ ; /* skip over blanks */ >+ if ( *s == '\'' || *s == '\"' ) /* get string delimiter */ >+ quote_char = *s++; > else >- t = ' '; >- for (v = ValStr; /* copy value portion up to delim */ >- *s != t && *s != '\0'; >- *v++ = *s++) >- ; >- if ( t != ' ' && *s == t ) >- s++; >- *v = '\0'; >- kw->Val = ValStr; >+ quote_char = ' '; >+ start = s; /* no increment, might be "" as value */ >+ while ( *s != quote_char && *s != '\0' ) >+ s++; /* locate end of value portion */ >+ save_char = *s; >+ *s = '\0'; >+ kw->Val = xstrdup(start); > kw->vt = String; >+ if ( save_char != '\0' ) { /* save_char is now quote_char */ >+ *s = save_char; >+ if ( quote_char != ' ' ) /* we had real quote chars */ >+ s++; >+ } > return( s ); > } > >@@ -4819,13 +4887,14 @@ struct font_entry *fontptr; > the resident fonts. */ > if (tfm_read_info(fontptr->n, &tfm_info) > && tfm_info.family[0] >- && strcmp((char *)tfm_info.family, "HPAUTOTFM") == 0) { >+ && EQ((char *)tfm_info.family, "HPAUTOTFM")) { > unsigned i; > double factor = fontptr->s / (double)0x100000; > > resident_count++; > fontptr->resident_p = _TRUE; >- strcpy(fontptr->symbol_set, (char *)tfm_info.coding_scheme); >+ strncpy(fontptr->symbol_set, (char *)tfm_info.coding_scheme, 39); >+ fontptr->symbol_set[39] = '\0'; > fontptr->resid = tfm_info.typeface_id; > fontptr->spacing = tfm_info.spacing; > fontptr->style = tfm_info.style; >@@ -4878,7 +4947,7 @@ struct font_entry *fontptr; > fontptr->resident_p = _FALSE; > > if (tfm_info.family[0] >- && strcmp((char *)tfm_info.family, "UNSPECIFIED") == 0) { >+ && EQ((char *)tfm_info.family, "UNSPECIFIED")) { > Warning("font family for %s is UNSPECIFIED; need to run dvicopy?", > fontptr->n); > fontptr->font_file_id = NO_FILE; >@@ -5031,10 +5100,9 @@ printf("[%ld]=%lf * %lf * %lf + 0.5 = %l > if (tfontptr->resident_p) > return; > >- if (!(resident_font_located)) { >+ if (!(resident_font_located)) > #endif > >-#ifdef KPATHSEA > { > kpse_glyph_file_type font_ret; > char *name; >@@ -5047,9 +5115,9 @@ printf("[%ld]=%lf * %lf * %lf + 0.5 = %l > if (name) > { > font_found = _TRUE; >- strcpy (tfontptr->name, name); >- free (name); >- >+ tfontptr->name = name; >+ allocated_storage += strlen(name)+1; >+ > if (!FILESTRCASEEQ (tfontptr->n, font_ret.name)) { > fprintf (stderr, > "dvilj: Font %s not found, using %s at %d instead.\n", >@@ -5071,29 +5139,6 @@ printf("[%ld]=%lf * %lf * %lf + 0.5 = %l > tfontptr->n, dpi); > } > } >-#else /* not KPATHSEA */ >- if (!(findfile(PXLpath, >- tfontptr->n, >- tfontptr->font_mag, >- tfontptr->name, >- _FALSE, >- 0))) { >- Warning(tfontptr->name); /* contains error messsage */ >- tfontptr->font_file_id = NO_FILE; >-#ifdef __riscos >- MakeMetafontFile(PXLpath, tfontptr->n, tfontptr->font_mag); >-#endif >- } >- else { >- font_found = _TRUE; >- if (G_verbose) >- fprintf(ERR_STREAM,"%d: using font <%s>\n", plusid, tfontptr->name); >- } >-#endif /* not KPATHSEA */ >- >-#ifdef LJ_RESIDENT_FONTS >- } >-#endif > > tfontptr->plusid = plusid; > plusid++; >Index: work/texk/dviljk/dvi2xx.h >=================================================================== >--- work.orig/texk/dviljk/dvi2xx.h >+++ work/texk/dviljk/dvi2xx.h >@@ -10,8 +10,8 @@ > > #ifdef KPATHSEA > #include <kpathsea/config.h> >+#include <kpathsea/c-std.h> > #include <kpathsea/c-limits.h> >-#include <kpathsea/c-memstr.h> > #include <kpathsea/magstep.h> > #include <kpathsea/proginit.h> > #include <kpathsea/progname.h> >@@ -24,6 +24,7 @@ > #include <string.h> > #include <stdio.h> > #include <stdlib.h> >+#include <unistd.h> > #ifdef unix > #include <limits.h> > #endif >@@ -41,9 +42,6 @@ > #ifdef MSC5 > #include <dos.h> /* only for binaryopen on device */ > #endif >-#if defined (unix) && !defined (KPATHSEA) >-#include <limits.h> >-#endif > > > #include "config.h" >@@ -116,6 +114,7 @@ > #define HUGE_SIZE (unsigned char) 2 > #define HUGE_CHAR_PATTERN 32767l > #define BYTES_PER_PIXEL_LINE 500 /* max number of bytes per pixel line */ >+#define MAX_SPECIAL_DEFPOINTS 80 /* max number of defpoint specials */ > > > #define PK_POST 245 >@@ -281,7 +280,14 @@ char *MFMODE = MFMODE600; > #define VisChar(c) (unsigned char)(c) > #endif > >-#define GetBytes(fp,buf,n) read_multi(buf,1,n,fp) /* used to be a function */ >+/* Used to be a function. buf is always an array, never a pointer. >+ Without that invariant, we would have to introduce full dynamic >+ memory management in this driver -- probably it would be easier to >+ write a new one. [27 Jun 07 -js] */ >+#define GetBytes(fp,buf,n) \ >+ ( sizeof(buf) != sizeof(void *) && sizeof(buf) > n ? \ >+ read_multi(buf, 1, n, fp) \ >+ : Fatal("Try to read %d bytes in an array of size %d", n, sizeof(buf)) ) > > > /**********************************************************************/ >@@ -307,6 +313,7 @@ int printf(); > int sscanf(); > int strcmp(); > char *strcpy(); >+char *strncpy(); > # ifdef MSC5 > unsigned int strlen(); > # endif >@@ -393,7 +400,7 @@ struct font_entry { /* font entry */ > char n[STRSIZE]; /* FNT_DEF command parameters */ > long4 font_mag; /* computed from FNT_DEF s and d parameters */ > /*char psname[STRSIZE];*/ /* PostScript name of the font */ >- char name[STRSIZE]; /* full name of PXL file */ >+ char *name; /* full name of PXL file */ > FILEPTR font_file_id; /* file identifier (NO_FILE if none) */ > #ifdef USEPXL > long4 magnification; /* magnification read from PXL file */ >@@ -487,8 +494,8 @@ void LoadAChar DVIPROTO((long4, regis > long4 NoSignExtend DVIPROTO((FILEPTR, int)); > void OpenFontFile DVIPROTO((void)); > long4 PixRound DVIPROTO((long4, long4)); >-void PkRaster DVIPROTO((struct char_entry *, int)); >-void RasterLine DVIPROTO((struct char_entry *, unsigned int, >+void PkRaster DVIPROTO((struct char_entry *, int)); >+void RasterLine DVIPROTO((struct char_entry *, unsigned int, > unsigned int, unsigned char *)); > void RasterChar DVIPROTO((struct char_entry *)); > void ReadFontDef DVIPROTO((long4)); >@@ -534,11 +541,12 @@ bool LastPageSpecified = _FALSE; > #ifndef KPATHSEA > char *PXLpath = FONTAREA; > #endif >-char G_progname[STRSIZE]; /* program name */ >-char filename[STRSIZE]; /* DVI file name */ >-char rootname[STRSIZE]; /* DVI filename without extension */ >+char *G_progname; /* program name */ >+char *filename; /* DVI file name */ >+char *rootname; /* DVI filename without extension */ > char *HeaderFileName = ""; /* file name & path of Headerfile */ > char *EmitFileName = ""; /* file name & path for output */ >+char tmp_dir[STRSIZE] = ""; /* temporary directory for auxilliary files */ > #ifdef IBM3812 > bool FirstAlternate = _FALSE; /* first page from alternate casette ? */ > #endif
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 368611
:
249481
| 250261