~ubuntu-branches/ubuntu/feisty/tetex-bin/feisty-updates

« back to all changes in this revision

Viewing changes to debian/patches/SECURITY_CVE-2007-5936+5937.patch

  • Committer: Bazaar Package Importer
  • Author(s): Jamie Strandboge
  • Date: 2007-12-04 10:53:07 UTC
  • Revision ID: james.westby@ubuntu.com-20071204105307-ryd6h5vsj6ii3gun
Tags: 3.0-27ubuntu1.2
* SECURITY UPDATE: improper bounds on static buffer results in stack-based
  buffer overflow
* debian/patches/SECURITY_CVE-2007-5935.patch: make sure tmpbuf is allocated
  enough memory in texk/dvipsk/hps.c
* SECURITY UPDATE: temporary file race condition in dviljk due to use of
  tmpnam()
* SECURITY UPDATE: various buffer overflows in dviljk due to not checking
  memory boundaries
* debian/patches/SECURITY_CVE-2007-5936+5937.patch: use mkdtemp() if
  available in dvi2xx.c.  Replace calls to strcpy() and do proper bounds
  checking in dvi2xx.*.
* Modify Maintainer value to match the DebianMaintainerField
  specification.
* debian/control: Build-Depends on libcairo2-dev
* References
  CVE-2007-5935
  CVE-2007-5936
  CVE-2007-5937

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
diff -Nur tetex-bin-3.0/texk/dviljk/dvi2xx.c tetex-bin-3.0.new/texk/dviljk/dvi2xx.c
 
2
--- tetex-bin-3.0/texk/dviljk/dvi2xx.c  1999-02-06 16:46:34.000000000 -0500
 
3
+++ tetex-bin-3.0.new/texk/dviljk/dvi2xx.c      2007-12-05 13:24:42.000000000 -0500
 
4
@@ -173,7 +173,7 @@
 
5
   y_origin = YDEFAULTOFF; /* y-origin in dots                    */
 
6
 
 
7
   setbuf(ERR_STREAM, NULL);
 
8
-  (void) strcpy(G_progname, argv[0]);
 
9
+  G_progname = argv[0];
 
10
 #ifdef KPATHSEA
 
11
   kpse_set_progname(argv[0]);
 
12
   kpse_set_program_enabled (kpse_pk_format, MAKE_TEX_PK_BY_DEFAULT, kpse_src_compile);
 
13
@@ -2968,8 +2968,8 @@
 
14
 #endif
 
15
 {
 
16
   int     argind;            /* argument index for flags      */
 
17
-  char    curarea[STRSIZE];  /* current file area             */
 
18
-  char    curname[STRSIZE];  /* current file name             */
 
19
+  char    *curarea;         /* current file area             */
 
20
+  char    *curname;         /* current file name             */
 
21
   char    *tcp, *tcp1;       /* temporary character pointers  */
 
22
   char    *this_arg;
 
23
   double  x_offset = 0.0, y_offset = 0.0;
 
24
@@ -2988,9 +2988,9 @@
 
25
 #endif
 
26
 #endif
 
27
 
 
28
-  if (argc == 2 && (strcmp (argv[1], "--version") == 0)) {
 
29
+  if (argc == 2 && EQ(argv[1], "--version")) {
 
30
     extern KPSEDLL char *kpathsea_version_string;
 
31
-    puts ("dvilj(k) 2.6");
 
32
+    puts (VERSION);
 
33
     puts (kpathsea_version_string);
 
34
     puts ("Copyright (C) 1997 Gustaf Neumann.\n\
 
35
 There is NO warranty.  You may redistribute this software\n\
 
36
@@ -3328,8 +3328,8 @@
 
37
       }
 
38
     } else {
 
39
 
 
40
-      (void) strcpy(filename, tcp);
 
41
-      if (!strcmp(filename, "-")) {
 
42
+      filename = tcp;
 
43
+      if (EQ(filename, "-")) {
 
44
         EmitFileName = "-";
 
45
 #ifdef RISC_USE_OSL
 
46
         dvifp = BINOPEN("Kbd:");
 
47
@@ -3339,57 +3339,68 @@
 
48
          AssureBinary(fileno(dvifp));
 
49
 #endif
 
50
       } else {
 
51
+       /* Since this code is used only once during startup, we don't care
 
52
+          about free()ing the allocated strings that represent filenames.
 
53
+          It will be more work to realize proper deallocation handling than
 
54
+          it's worth in terms of saving a few bytes. We consider these
 
55
+          bytes actually static memory where we don't know the size in
 
56
+          advance and don't add them to the allocated_storage count.
 
57
+          [27 Jun 07 -js] */
 
58
 #ifdef KPATHSEA
 
59
         /* split into directory + file name */
 
60
        int tcplen, argvlen;
 
61
        tcp = (char *)xbasename(argv[argind]);/* this knows about any kind of slashes */
 
62
        tcplen = strlen(tcp);
 
63
+       if ( tcplen == 0 ) {
 
64
+         /* This happens when the DVI file name has a trailing slash; this
 
65
+            is not a valid name. Then we terminate the argument parsing
 
66
+            loop, a usage message will be output below. */
 
67
+         break;
 
68
+       }
 
69
        argvlen = strlen(argv[argind]);
 
70
        if (tcplen == argvlen)
 
71
-         curarea[0] = '\0';
 
72
+         curarea = "";
 
73
        else {
 
74
-         (void) strcpy(curarea, argv[argind]);
 
75
+         curarea = xstrdup(argv[argind]);
 
76
          curarea[argvlen-tcplen] = '\0';
 
77
        }
 
78
 #else
 
79
         tcp = strrchr(argv[argind], '/');
 
80
         /* split into directory + file name */
 
81
         if (tcp == NULL) {
 
82
-          curarea[0] = '\0';
 
83
+          curarea[0] = "";
 
84
           tcp = argv[argind];
 
85
         } else {
 
86
-          (void) strcpy(curarea, argv[argind]);
 
87
+         curarea = xstrdup(argv[argind]);
 
88
           curarea[tcp-argv[argind]+1] = '\0';
 
89
           tcp += 1;
 
90
         }
 
91
 #endif
 
92
 
 
93
+        curname = (char *) xmalloc(strlen(tcp)+5);  /* + space for ".dvi" */
 
94
         (void) strcpy(curname, tcp);
 
95
         /* split into file name + extension */
 
96
-        tcp1 = strrchr(tcp, '.');
 
97
+        tcp1 = strrchr(curname, '.');
 
98
         if (tcp1 == NULL) {
 
99
-          (void) strcpy(rootname, curname);
 
100
+          rootname = xstrdup(curname);
 
101
           strcat(curname, ".dvi");
 
102
         } else {
 
103
           *tcp1 = '\0';
 
104
-          (void) strcpy(rootname, curname);
 
105
+          rootname = xstrdup(curname);
 
106
           *tcp1 = '.';
 
107
         }
 
108
 
 
109
+       filename = (char *) xmalloc(strlen(curarea)+strlen(curname)+1);
 
110
         (void) strcpy(filename, curarea);
 
111
         (void) strcat(filename, curname);
 
112
 
 
113
         if ((dvifp = BINOPEN(filename)) == FPNULL) {
 
114
           /* do not insist on .dvi */
 
115
           if (tcp1 == NULL) {
 
116
-            int l = strlen(curname);
 
117
-            if (l > 4)
 
118
-              curname[l - 4] = '\0';
 
119
-            l = strlen(filename);
 
120
-            if (l > 4)
 
121
-              filename[l - 4] = '\0';
 
122
+           filename[strlen(filename) - 4] = '\0';
 
123
+           dvifp = BINOPEN(filename);
 
124
           }
 
125
-          if (tcp1 != NULL || (dvifp = BINOPEN(filename)) == FPNULL) {
 
126
+          if (dvifp == FPNULL) {
 
127
 #ifdef MSC5
 
128
             Fatal("%s: can't find DVI file \"%s\"\n\n",
 
129
                   G_progname, filename);
 
130
@@ -3507,13 +3518,8 @@
 
131
     exit(1);
 
132
   }
 
133
   if (EQ(EmitFileName, "")) {
 
134
-    if ((EmitFileName = (char *)malloc( STRSIZE )) != NULL)
 
135
-      allocated_storage += STRSIZE;
 
136
-    else
 
137
-      Fatal("Can't allocate storage of %d bytes\n",STRSIZE);
 
138
-    (void) strcpy(EmitFileName, curname);
 
139
-    if ((tcp1 = strrchr(EmitFileName, '.')))
 
140
-      *tcp1 = '\0';
 
141
+    EmitFileName = (char *) xmalloc(strlen(rootname)+sizeof(EMITFILE_EXTENSION));
 
142
+    (void) strcpy(EmitFileName, rootname);
 
143
     strcat(EmitFileName, EMITFILE_EXTENSION);
 
144
   }
 
145
   if (G_quiet)
 
146
@@ -3698,6 +3704,8 @@
 
147
 #endif
 
148
   }
 
149
   CloseFiles();
 
150
+  if ( tmp_dir[0] != '\0' )
 
151
+    rmdir (tmp_dir);                   /* ignore errors */
 
152
   exit(G_errenc);
 
153
 }
 
154
 
 
155
@@ -3895,22 +3903,21 @@
 
156
 int  n;
 
157
 #endif
 
158
 {
 
159
-  char    spbuf[STRSIZE], xs[STRSIZE], ys[STRSIZE];
 
160
-  char    *sf = NULL, *psfile = NULL;
 
161
+  char    xs[STRSIZE], ys[STRSIZE];
 
162
+  char    *include_file = NULL;
 
163
+  enum    { VerbFile, HPFile, PSFile } file_type;
 
164
   float   x,y;
 
165
   long4   x_pos, y_pos;
 
166
   KeyWord k;
 
167
   int     i, j, j1;
 
168
   static  int   GrayScale = 10, Pattern = 1;
 
169
   static  bool  GrayFill = _TRUE;
 
170
-  static  long4 p_x[80], p_y[80];
 
171
-  int llx=0, lly=0, urx=0, ury=0, rwi=0, rhi=0;
 
172
-#ifdef WIN32
 
173
-  char    *gs_path;
 
174
-#endif
 
175
+  static  long4 p_x[MAX_SPECIAL_DEFPOINTS], p_y[MAX_SPECIAL_DEFPOINTS];
 
176
+  int llx=0, lly=0, urx=0, ury=0, rwi=0;
 
177
 
 
178
   str[n] = '\0';
 
179
-  spbuf[0] = '\0';
 
180
+  for ( i=0 ; i<MAX_SPECIAL_DEFPOINTS ; i++ )
 
181
+    p_x[i] = p_y[i] = -1;
 
182
 
 
183
   SetPosn(h, v);
 
184
 #ifdef __riscos
 
185
@@ -3924,41 +3931,30 @@
 
186
     /* get all keyword-value pairs */
 
187
     /* for compatibility, single words are taken as file names */
 
188
     if ( k.vt == None && access(k.Key, 0) == 0) {
 
189
-      if ( sf
 
190
-#ifdef KPATHSEA
 
191
-           && !kpse_tex_hush ("special")
 
192
-#endif
 
193
-         )
 
194
-        Warning("More than one \\special file name given. %s ignored", sf);
 
195
-      (void) strcpy(spbuf, k.Key);
 
196
-      sf = spbuf;
 
197
-      /*
 
198
-        for (j = 1; ((sf[j]=='/' ? sf[j]='\\':sf[j]) != '\0'); j++);
 
199
-        */
 
200
-    } else if ( GetKeyVal( &k, KeyTab, NKEYS, &i ) && i != -1 )
 
201
+      if ( include_file && !kpse_tex_hush ("special") ) {
 
202
+        Warning("More than one \\special file name given. %s ignored", include_file);
 
203
+       free (include_file);
 
204
+      }
 
205
+      include_file = xstrdup(k.Key);
 
206
+      file_type = VerbFile;
 
207
+    } else if ( GetKeyVal( &k, KeyTab, NKEYS, &i ) && i != -1 ) {
 
208
       switch (i) {
 
209
       case PSFILE:
 
210
-        if (sf
 
211
-#ifdef KPATHSEA
 
212
-            && !kpse_tex_hush ("special")
 
213
-#endif
 
214
-            )
 
215
-            Warning("More than one \\special file name given. %s ignored", sf);
 
216
-        (void) strcpy(spbuf, k.Val);
 
217
-        psfile = spbuf;
 
218
-        /*
 
219
-          for (j=1; ((sf[j]=='/' ? sf[j]='\\':sf[j]) != '\0'); j++);
 
220
-          */
 
221
+        if ( include_file ) {
 
222
+         Warning("More than one \\special file name given. %s ignored", include_file);
 
223
+         free(include_file);
 
224
+       }
 
225
+        include_file = xstrdup(k.Val);
 
226
+       file_type = PSFile;
 
227
         break;
 
228
         
 
229
       case HPFILE:
 
230
-        if (sf)
 
231
-            Warning("More than one \\special file name given. %s ignored", sf);
 
232
-        (void) strcpy(spbuf, k.Val);
 
233
-        sf = spbuf;
 
234
-        /*
 
235
-          for (j=1; ((sf[j]=='/' ? sf[j]='\\':sf[j]) != '\0'); j++);
 
236
-          */
 
237
+        if ( include_file && !kpse_tex_hush ("special") ) {
 
238
+         Warning("More than one \\special file name given. %s ignored", include_file);
 
239
+         free(include_file);
 
240
+       }
 
241
+        include_file = xstrdup(k.Val);
 
242
+       file_type = HPFile;
 
243
         break;
 
244
 
 
245
       case ORIENTATION:
 
246
@@ -3978,23 +3974,24 @@
 
247
         }
 
248
 #endif
 
249
         else
 
250
-#ifdef KPATHSEA
 
251
-           if (!kpse_tex_hush ("special"))
 
252
-#endif
 
253
           Warning( "Invalid orientation (%d)given; ignored.", k.v.i);
 
254
         break;
 
255
 
 
256
       case RESETPOINTS:
 
257
-        (void) strcpy(spbuf, k.Val);
 
258
-
 
259
-        sf = NULL;
 
260
+       for ( i=0 ; i<MAX_SPECIAL_DEFPOINTS ; i++ )
 
261
+         p_x[i] = p_y[i] = -1;
 
262
         break;
 
263
 
 
264
       case DEFPOINT:
 
265
-        (void) strcpy(spbuf, k.Val);
 
266
-        i = sscanf(spbuf,"%d(%[^,],%s)",&j,xs,ys);
 
267
+       /* 254 is STRSIZE-1. cpp should be used to construct that number. */
 
268
+        i = sscanf(k.Val,"%d(%254[^,],%254s)",&j,xs,ys);
 
269
         if (i>0) {
 
270
-          x_pos = h; 
 
271
+         if ( j < 0  ||  j >= MAX_SPECIAL_DEFPOINTS ) {
 
272
+           Warning ("defpoint %d ignored, must be between 0 and %d",
 
273
+                    j, MAX_SPECIAL_DEFPOINTS);
 
274
+           break;
 
275
+         }
 
276
+          x_pos = h;
 
277
           y_pos = v;
 
278
           if (i>1) {
 
279
             if (sscanf(xs,"%fpt",&x)>0) {
 
280
@@ -4011,19 +4008,32 @@
 
281
           p_x[j]=x_pos;
 
282
           p_y[j]=y_pos;
 
283
         } else
 
284
-#ifdef KPATHSEA
 
285
-              if (!kpse_tex_hush ("special"))
 
286
-#endif
 
287
           Warning("invalid point definition\n");
 
288
-
 
289
-        sf = NULL;
 
290
         break;
 
291
 
 
292
       case FILL:
 
293
-        (void) strcpy(spbuf, k.Val);
 
294
-        i = sscanf(spbuf,"%d/%d %s",&j,&j1,xs);
 
295
+       /* 254 is STRSIZE-1. cpp should be used to construct that number. */
 
296
+        i = sscanf(k.Val,"%d/%d %254s",&j,&j1,xs);
 
297
         if (i>1) {
 
298
 #ifdef LJ
 
299
+         if ( j < 0 || j >= MAX_SPECIAL_DEFPOINTS ) {
 
300
+           Warning ("fill ignored, point %d must be between 0 and %d",
 
301
+                    j, MAX_SPECIAL_DEFPOINTS);
 
302
+           break;
 
303
+         }
 
304
+         if ( p_x[j] == -1 ) {
 
305
+           Warning ("fill ignored, point %d is undefined\n", j);
 
306
+           break;
 
307
+         }
 
308
+         if ( j1 < 0 || j1 >= MAX_SPECIAL_DEFPOINTS ) {
 
309
+           Warning ("fill ignored, point %d must be between 0 and %d",
 
310
+                    j1, MAX_SPECIAL_DEFPOINTS);
 
311
+           break;
 
312
+         }
 
313
+         if ( p_x[j1] == -1 ) {
 
314
+           Warning ("fill ignored, point %d is undefined\n", j1);
 
315
+           break;
 
316
+         }
 
317
           SetPosn(p_x[j], p_y[j]);
 
318
           x_pos = (long4)PIXROUND(p_x[j1]-p_x[j], hconv);
 
319
           y_pos = (long4)PIXROUND(p_y[j1]-p_y[j], vconv);
 
320
@@ -4044,9 +4054,6 @@
 
321
           GrayScale = k.v.i;
 
322
           GrayFill = _TRUE;
 
323
         } else
 
324
-#ifdef KPATHSEA
 
325
-           if (!kpse_tex_hush ("special"))
 
326
-#endif
 
327
           Warning( "Invalid gray scale (%d) given; ignored.", k.v.i);
 
328
         break;
 
329
 
 
330
@@ -4055,9 +4062,6 @@
 
331
           Pattern = k.v.i;
 
332
           GrayFill = _FALSE;
 
333
         } else
 
334
-#ifdef KPATHSEA
 
335
-           if (!kpse_tex_hush ("special"))
 
336
-#endif
 
337
           Warning( "Invalid pattern (%d) given; ignored.", k.v.i);
 
338
         break;
 
339
 
 
340
@@ -4066,75 +4070,122 @@
 
341
       case URX: urx = k.v.i; break;
 
342
       case URY: ury = k.v.i; break;
 
343
       case RWI: rwi = k.v.i; break;
 
344
-      case RHI: rhi = k.v.i; break;
 
345
+      case RHI:
 
346
+       if (!kpse_tex_hush ("special"))
 
347
+            Warning("Whatever rhi was good for once, it is ignored now.");
 
348
+       break;
 
349
 
 
350
       default:
 
351
-#ifdef KPATHSEA
 
352
-           if (!kpse_tex_hush ("special"))
 
353
-#endif
 
354
+       if ( !kpse_tex_hush ("special") )
 
355
         Warning("Can't handle %s=%s command; ignored.", k.Key, k.Val);
 
356
         break;
 
357
       }
 
358
-      
 
359
-    else
 
360
-#ifdef KPATHSEA
 
361
-           if (!kpse_tex_hush ("special"))
 
362
-#endif
 
363
+
 
364
+    } else if (!kpse_tex_hush ("special")) {
 
365
       Warning("Invalid keyword or value in \\special - <%s> ignored", k.Key);
 
366
+    }
 
367
+
 
368
+    free (k.Key);
 
369
+    if ( k.Val != NULL )  free(k.Val);
 
370
   }
 
371
 
 
372
-  if ( sf || psfile ) {
 
373
+  if ( include_file ) {
 
374
     last_rx = last_ry = UNKNOWN;
 
375
 #ifdef IBM3812
 
376
     PMPflush;
 
377
 #endif
 
378
-    if (sf) {
 
379
-      if (i == HPFILE) 
 
380
-        CopyHPFile( sf );
 
381
-      else 
 
382
-        CopyFile( sf );
 
383
-    }
 
384
-    else
 
385
+
 
386
 #ifdef LJ
 
387
-      if (psfile) {
 
388
+      if ( file_type == PSFile) {
 
389
         /* int height = rwi * (urx - llx) / (ury - lly);*/
 
390
         int width  = urx - llx;
 
391
         int height = ury - lly;
 
392
         char cmd[255];
 
393
-        int scale_factor    = 3000 * width / rwi;
 
394
-        int adjusted_height = height * 300/scale_factor;
 
395
-        int adjusted_llx    = llx    * 300/scale_factor;
 
396
+        char *cmd_format = "%s -q -dSIMPLE -dSAFER -dNOPAUSE -sDEVICE=%s -sOutputFile=%s %s %s showpage.ps -c quit";
 
397
+        char *gs_cmd;
 
398
+        int scale_factor, adjusted_height, adjusted_llx;
 
399
         char *printer = "ljetplus"; /* use the most stupid one */
 
400
 
 
401
-
 
402
-        char scale_file_name[255];
 
403
-        char *scale_file = tmpnam(scale_file_name);
 
404
-        char *pcl_file = tmpnam(NULL);  
 
405
+        char pcl_file[STRSIZE];
 
406
+        char scale_file[STRSIZE];
 
407
         FILEPTR scalef;
 
408
 
 
409
-        if ( (scalef = BOUTOPEN(scale_file)) == FPNULL ) {
 
410
-          Warning("Unable to open file %s for writing", scale_file );
 
411
-          return;
 
412
-        }
 
413
-        fprintf(scalef, "%.2f %.2f scale\n%d %d translate\n",  
 
414
-                300.0/scale_factor, 300.0/scale_factor,
 
415
-                0, adjusted_height == height ? 0 : ury);
 
416
-        BCLOSE( scalef );
 
417
+        if ( urx == 0 || ury == 0 || rwi == 0 ) {
 
418
+       /* Since dvips' psfile special has a different syntax, this might
 
419
+          well be one of those specials, i.e., a non-dviljk special. Then
 
420
+          the Warning should be suppressable. */
 
421
+       if ( !kpse_tex_hush ("special") )
 
422
+         Warning ("Ignoring psfile special without urx, ury and rwi attributes");
 
423
+       free (include_file);
 
424
+       return;
 
425
+      }
 
426
+      scale_factor    = 3000 * width / rwi;
 
427
+      adjusted_height = height * 300/scale_factor;
 
428
+      adjusted_llx    = llx    * 300/scale_factor;
 
429
+
 
430
+      /* We cannot use mkstemp, as we cannot pass two open file descriptors
 
431
+        portably to Ghostscript. We don't want to use tmpnam() or tempnam()
 
432
+        either, as they have tempfile creation race conditions. Instead we
 
433
+        create a temporary directory with mkdtemp(). We need to create the
 
434
+        temporary directory only once per run; it will be deleted in
 
435
+         AllDone(). */
 
436
+      if ( tmp_dir[0] == '\0' ) {
 
437
+       char * base_dir;
 
438
+       if ( (base_dir = getenv("TMPDIR")) == NULL ) {
 
439
+         base_dir = "/tmp";
 
440
+       } else if ( strlen(base_dir) > STRSIZE - sizeof("/dviljkXXXXXX/include.pcl") ) {
 
441
+         Warning ("TMPDIR %s is too long, using /tmp instead", base_dir);
 
442
+         base_dir = "/tmp";
 
443
+       }
 
444
+       if ( base_dir[0] == '/'  && base_dir[1] == '\0' ) {
 
445
+         Warning ("Feeling naughty, do we? / is no temporary directory, dude");
 
446
+         base_dir = "/tmp";
 
447
+       }
 
448
+       strcpy (tmp_dir, base_dir);
 
449
+       strcat (tmp_dir, "/dviljkXXXXXX");
 
450
+       if ( mkdtemp(tmp_dir) == NULL ) {
 
451
+         Warning ("Could not create temporary directory %s, errno = %d; ignoring include file special",
 
452
+                  tmp_dir, errno);
 
453
+         return;
 
454
+       }
 
455
+      }
 
456
+      strcpy(pcl_file, tmp_dir);
 
457
+      strcat(pcl_file, "/include.pcl");
 
458
+      strcpy(scale_file, tmp_dir);
 
459
+      strcat(scale_file, "/scale.ps");
 
460
+
 
461
+      if ( (scalef = BOUTOPEN(scale_file)) == FPNULL ) {
 
462
+       Warning("Unable to open file %s for writing", scale_file );
 
463
+       free (include_file);
 
464
+       unlink(scale_file);             /* ignore error */
 
465
+       return;
 
466
+      }
 
467
+      fprintf(scalef, "%.2f %.2f scale\n%d %d translate\n",
 
468
+             300.0/scale_factor, 300.0/scale_factor,
 
469
+             0, adjusted_height == height ? 0 : ury);
 
470
+      BCLOSE( scalef );
 
471
 
 
472
 #ifdef WIN32
 
473
-       gs_path = getenv("GS_PATH");
 
474
-       if (!gs_path)
 
475
-         gs_path = "gswin32c.exe";
 
476
-        sprintf(cmd,"%s -q -dSIMPLE -dSAFER -dNOPAUSE -sDEVICE=%s -sOutputFile=%s %s %s showpage.ps -c quit",
 
477
-               gs_path, printer, pcl_file, scale_file, psfile);
 
478
+      if ( (gs_cmd = getenv("GS_PATH")) == NULL )
 
479
+       gs_cmd = "gswin32c.exe";
 
480
 #else
 
481
-        sprintf(cmd,"gs -q -dSIMPLE -dSAFER -dNOPAUSE -sDEVICE=%s -sOutputFile=%s %s %s showpage.ps -c quit",
 
482
-                printer, pcl_file, scale_file, psfile);
 
483
+      gs_cmd = "gs";
 
484
 #endif
 
485
+      if ( strlen(cmd_format)-10 + strlen(gs_cmd) + strlen(printer) +
 
486
+              strlen(pcl_file) + strlen(scale_file) + strlen(include_file) +1 >
 
487
+          sizeof(cmd) ) {
 
488
+       Warning ("Ghostscript command for %s would be too long, skipping special", include_file);
 
489
+       free (include_file);
 
490
+       unlink(scale_file);             /* ignore errors */
 
491
+       unlink(pcl_file);
 
492
+       return;
 
493
+      }
 
494
+      sprintf(cmd, cmd_format,
 
495
+             gs_cmd, printer, pcl_file, scale_file, include_file);
 
496
 #ifdef DEBUGGS   
 
497
         fprintf(stderr,
 
498
           "PS-file '%s' w=%d, h=%d, urx=%d, ury=%d, llx=%d, lly=%d, rwi=%d\n",
 
499
-                psfile, urx - llx, height, urx,ury,llx,lly, rwi);
 
500
+             include_file, urx - llx, height, urx,ury,llx,lly, rwi);
 
501
         fprintf(stderr,"%s\n",cmd);
 
502
 #endif
 
503
         if (system(cmd)) {
 
504
@@ -4158,11 +4209,21 @@
 
505
 #endif
 
506
 
 
507
           CopyHPFile( pcl_file );
 
508
-          /* unlink(pcl_file); */
 
509
-          /* unlink(scale_file); */
 
510
-        }
 
511
       }
 
512
+      unlink(scale_file);              /* ignore errors */
 
513
+      unlink(pcl_file);
 
514
+    }
 
515
+    else
 
516
 #endif /* LJ */
 
517
+
 
518
+    if ( file_type == HPFile )
 
519
+      CopyHPFile( include_file );
 
520
+    else if ( file_type == VerbFile )
 
521
+      CopyFile( include_file );
 
522
+    else
 
523
+      Warning ("This can't happen: unknown file_type value %d", file_type);
 
524
+
 
525
+    if ( include_file != NULL )  free(include_file);
 
526
   }
 
527
 }
 
528
 
 
529
@@ -4173,12 +4234,11 @@
 
530
 /**********************************************************************/
 
531
 /*****************************  GetKeyStr  ****************************/
 
532
 /**********************************************************************/
 
533
-/* extract first keyword-value pair from string (value part may be null)
 
534
- * return pointer to remainder of string
 
535
- * return NULL if none found
 
536
+/* Extract first keyword-value pair from string (value part may be null),
 
537
+ * keyword and value are allocated and must be free by caller.
 
538
+ * Return pointer to remainder of string,
 
539
+ * return NULL if none found.
 
540
  */
 
541
-char    KeyStr[STRSIZE];
 
542
-char    ValStr[STRSIZE];
 
543
 #if NeedFunctionPrototypes
 
544
 char *GetKeyStr(char *str, KeyWord *kw )
 
545
 #else
 
546
@@ -4187,39 +4247,46 @@
 
547
 KeyWord *kw;
 
548
 #endif
 
549
 {
 
550
-  char    *s, *k, *v, t;
 
551
+  char *s, *start;
 
552
+  char save_char, quote_char;
 
553
   if ( !str )
 
554
     return( NULL );
 
555
   for (s = str; *s == ' '; s++)
 
556
     ;          /* skip over blanks */
 
557
   if (*s == '\0')
 
558
     return( NULL );
 
559
-  for (k = KeyStr; /* extract keyword portion */
 
560
-       *s != ' ' && *s != '\0' && *s != '=';
 
561
-       *k++ = *s++)
 
562
-    ;
 
563
-  *k = '\0';
 
564
-  kw->Key = KeyStr;
 
565
-  kw->Val = v = NULL;
 
566
+  start = s++;                         /* start of keyword */
 
567
+  while ( *s != ' ' && *s != '\0' && *s != '=' )  /* locate end */
 
568
+    s++;
 
569
+  save_char = *s;
 
570
+  *s = '\0';
 
571
+  kw->Key = xstrdup(start);
 
572
+  kw->Val = NULL;
 
573
   kw->vt = None;
 
574
-  for ( ; *s == ' '; s++)
 
575
-    ;            /* skip over blanks */
 
576
-  if ( *s != '=' )         /* look for "=" */
 
577
+  if ( save_char == '\0' )             /* shortcut when we're at the end */
 
578
+    return (s);
 
579
+  *s = save_char;                      /* restore keyword end char */
 
580
+  while ( *s == ' ' ) s++ ;            /* skip over blanks */
 
581
+  if ( *s != '=' )                     /* no "=" means no value */
 
582
     return( s );
 
583
-  for (s++; *s == ' '; s++);      /* skip over blanks */
 
584
-  if ( *s == '\'' || *s == '\"' )  /* get string delimiter */
 
585
-    t = *s++;
 
586
+  for (s++; *s == ' '; s++)
 
587
+    ;                                  /* skip over blanks */
 
588
+  if ( *s == '\'' || *s == '\"' )      /* get string delimiter */
 
589
+    quote_char = *s++;
 
590
   else
 
591
-    t = ' ';
 
592
-  for (v = ValStr; /* copy value portion up to delim */
 
593
-       *s != t && *s != '\0';
 
594
-       *v++ = *s++)
 
595
-    ;
 
596
-  if ( t != ' ' && *s == t )
 
597
-    s++;
 
598
-  *v = '\0';
 
599
-  kw->Val = ValStr;
 
600
+    quote_char = ' ';
 
601
+  start = s;                           /* no increment, might be "" as value */
 
602
+  while ( *s != quote_char && *s != '\0' )
 
603
+    s++;                         /* locate end of value portion */
 
604
+  save_char = *s;
 
605
+  *s = '\0';
 
606
+  kw->Val = xstrdup(start);
 
607
   kw->vt = String;
 
608
+  if ( save_char != '\0' ) {           /* save_char is now quote_char */
 
609
+    *s = save_char;
 
610
+    if ( quote_char != ' ' )           /* we had real quote chars */
 
611
+      s++;
 
612
+  }
 
613
   return( s );
 
614
 }
 
615
 
 
616
@@ -4819,13 +4886,14 @@
 
617
      the resident fonts.  */
 
618
   if (tfm_read_info(fontptr->n, &tfm_info)
 
619
       && tfm_info.family[0]
 
620
-      && strcmp((char *)tfm_info.family, "HPAUTOTFM") == 0) {
 
621
+      && EQ((char *)tfm_info.family, "HPAUTOTFM")) {
 
622
     unsigned i;
 
623
     double factor = fontptr->s / (double)0x100000;
 
624
 
 
625
     resident_count++;
 
626
     fontptr->resident_p = _TRUE;
 
627
-    strcpy(fontptr->symbol_set, (char *)tfm_info.coding_scheme);
 
628
+    strncpy(fontptr->symbol_set, (char *)tfm_info.coding_scheme, 39);
 
629
+    fontptr->symbol_set[39] = '\0';
 
630
     fontptr->resid = tfm_info.typeface_id;
 
631
     fontptr->spacing = tfm_info.spacing;
 
632
     fontptr->style = tfm_info.style;
 
633
@@ -4878,7 +4946,7 @@
 
634
     fontptr->resident_p = _FALSE;
 
635
 
 
636
     if (tfm_info.family[0]
 
637
-        && strcmp((char *)tfm_info.family, "UNSPECIFIED") == 0) {
 
638
+        && EQ((char *)tfm_info.family, "UNSPECIFIED")) {
 
639
       Warning("font family for %s is UNSPECIFIED; need to run dvicopy?",
 
640
               fontptr->n);
 
641
       fontptr->font_file_id = NO_FILE;
 
642
@@ -5031,10 +5099,9 @@
 
643
   if (tfontptr->resident_p)
 
644
     return;
 
645
 
 
646
-  if (!(resident_font_located)) {
 
647
+  if (!(resident_font_located))
 
648
 #endif
 
649
 
 
650
-#ifdef KPATHSEA
 
651
     {
 
652
       kpse_glyph_file_type font_ret;
 
653
       char *name;
 
654
@@ -5047,9 +5114,9 @@
 
655
       if (name)
 
656
         {
 
657
           font_found = _TRUE;
 
658
-          strcpy (tfontptr->name, name);
 
659
-          free (name);
 
660
-          
 
661
+          tfontptr->name = name;
 
662
+          allocated_storage += strlen(name)+1;
 
663
+
 
664
           if (!FILESTRCASEEQ (tfontptr->n, font_ret.name)) {
 
665
               fprintf (stderr,
 
666
                        "dvilj: Font %s not found, using %s at %d instead.\n",
 
667
@@ -5071,29 +5138,6 @@
 
668
             tfontptr->n, dpi);
 
669
         }
 
670
     }
 
671
-#else /* not KPATHSEA */
 
672
-    if (!(findfile(PXLpath,
 
673
-                   tfontptr->n,
 
674
-                   tfontptr->font_mag,
 
675
-                   tfontptr->name,
 
676
-                   _FALSE,
 
677
-                   0))) {
 
678
-      Warning(tfontptr->name); /* contains error messsage */
 
679
-      tfontptr->font_file_id = NO_FILE;
 
680
-#ifdef __riscos
 
681
-      MakeMetafontFile(PXLpath, tfontptr->n, tfontptr->font_mag);
 
682
-#endif
 
683
-    }
 
684
-    else {
 
685
-      font_found = _TRUE;
 
686
-      if (G_verbose)
 
687
-        fprintf(ERR_STREAM,"%d: using font <%s>\n", plusid, tfontptr->name);
 
688
-    }
 
689
-#endif /* not KPATHSEA */
 
690
-
 
691
-#ifdef LJ_RESIDENT_FONTS
 
692
-  }
 
693
-#endif
 
694
 
 
695
   tfontptr->plusid = plusid;
 
696
   plusid++;
 
697
diff -Nur tetex-bin-3.0/texk/dviljk/dvi2xx.h tetex-bin-3.0.new/texk/dviljk/dvi2xx.h
 
698
--- tetex-bin-3.0/texk/dviljk/dvi2xx.h  1999-03-16 02:03:33.000000000 -0500
 
699
+++ tetex-bin-3.0.new/texk/dviljk/dvi2xx.h      2007-12-05 13:24:42.000000000 -0500
 
700
@@ -10,8 +10,8 @@
 
701
 
 
702
 #ifdef KPATHSEA
 
703
 #include <kpathsea/config.h>
 
704
+#include <kpathsea/c-std.h>
 
705
 #include <kpathsea/c-limits.h>
 
706
-#include <kpathsea/c-memstr.h>
 
707
 #include <kpathsea/magstep.h>
 
708
 #include <kpathsea/proginit.h>
 
709
 #include <kpathsea/progname.h>
 
710
@@ -24,6 +24,7 @@
 
711
 #include <string.h>
 
712
 #include <stdio.h>
 
713
 #include <stdlib.h>
 
714
+#include <unistd.h>
 
715
 #ifdef  unix
 
716
 #include <limits.h>
 
717
 #endif
 
718
@@ -41,9 +42,6 @@
 
719
 #ifdef MSC5
 
720
 #include <dos.h>     /* only for binaryopen on device  */
 
721
 #endif
 
722
-#if defined (unix) && !defined (KPATHSEA)
 
723
-#include <limits.h>
 
724
-#endif
 
725
 
 
726
 
 
727
 #include "config.h"
 
728
@@ -116,6 +114,7 @@
 
729
 #define  HUGE_SIZE  (unsigned char) 2
 
730
 #define  HUGE_CHAR_PATTERN 32767l
 
731
 #define  BYTES_PER_PIXEL_LINE 500    /* max number of bytes per pixel line */
 
732
+#define  MAX_SPECIAL_DEFPOINTS 80    /* max number of defpoint specials */
 
733
 
 
734
 
 
735
 #define PK_POST 245
 
736
@@ -281,7 +280,14 @@
 
737
 #define VisChar(c) (unsigned char)(c)
 
738
 #endif
 
739
 
 
740
-#define GetBytes(fp,buf,n) read_multi(buf,1,n,fp) /* used to be a function */
 
741
+/* Used to be a function. buf is always an array, never a pointer.
 
742
+   Without that invariant, we would have to introduce full dynamic
 
743
+   memory management in this driver -- probably it would be easier to
 
744
+   write a new one. [27 Jun 07 -js] */
 
745
+#define GetBytes(fp,buf,n) \
 
746
+    ( sizeof(buf) != sizeof(void *) && sizeof(buf) > n ? \
 
747
+        read_multi(buf, 1, n, fp) \
 
748
+      : Fatal("Try to read %d bytes in an array of size %d", n, sizeof(buf)) )
 
749
 
 
750
 
 
751
 /**********************************************************************/
 
752
@@ -307,6 +313,7 @@
 
753
 int     sscanf();
 
754
 int     strcmp();
 
755
 char   *strcpy();
 
756
+char   *strncpy();
 
757
 #   ifdef MSC5
 
758
 unsigned int strlen();
 
759
 #   endif
 
760
@@ -393,7 +400,7 @@
 
761
     char n[STRSIZE];          /* FNT_DEF command parameters                */
 
762
     long4    font_mag;         /* computed from FNT_DEF s and d parameters  */
 
763
     /*char psname[STRSIZE];*/ /* PostScript name of the font               */
 
764
-    char    name[STRSIZE];    /* full name of PXL file                     */
 
765
+    char    *name;            /* full name of PXL file                     */
 
766
     FILEPTR font_file_id;      /* file identifier (NO_FILE if none)         */
 
767
 #ifdef USEPXL
 
768
     long4    magnification;    /* magnification read from PXL file          */
 
769
@@ -487,8 +494,8 @@
 
770
 long4   NoSignExtend DVIPROTO((FILEPTR, int));
 
771
 void    OpenFontFile DVIPROTO((void));
 
772
 long4   PixRound DVIPROTO((long4, long4));
 
773
-void    PkRaster DVIPROTO((struct char_entry *, int)); 
 
774
-void    RasterLine DVIPROTO((struct char_entry *, unsigned int, 
 
775
+void    PkRaster DVIPROTO((struct char_entry *, int));
 
776
+void    RasterLine DVIPROTO((struct char_entry *, unsigned int,
 
777
                             unsigned int, unsigned char *));
 
778
 void    RasterChar DVIPROTO((struct char_entry *));
 
779
 void    ReadFontDef DVIPROTO((long4));
 
780
@@ -534,11 +541,12 @@
 
781
 #ifndef KPATHSEA
 
782
 char   *PXLpath = FONTAREA;
 
783
 #endif
 
784
-char    G_progname[STRSIZE];     /* program name                        */
 
785
-char    filename[STRSIZE];       /* DVI file name                       */
 
786
-char    rootname[STRSIZE];       /* DVI filename without extension      */
 
787
+char   *G_progname;             /* program name                        */
 
788
+char   *filename;               /* DVI file name                       */
 
789
+char   *rootname;               /* DVI filename without extension      */
 
790
 char   *HeaderFileName = "";     /* file name & path of Headerfile      */
 
791
 char   *EmitFileName = "";       /* file name & path for output         */
 
792
+char    tmp_dir[STRSIZE] = "";  /* temporary directory for auxilliary files */
 
793
 #ifdef IBM3812
 
794
 bool    FirstAlternate = _FALSE; /* first page from alternate casette ?   */
 
795
 #endif