]>
Commit | Line | Data |
---|---|---|
768e5264 AM |
1 | diff -up tetex-src-3.0/texk/dviljk/dvi2xx.c.dviljktemp tetex-src-3.0/texk/dviljk/dvi2xx.c |
2 | --- tetex-src-3.0/texk/dviljk/dvi2xx.c.dviljktemp 1999-02-06 22:46:34.000000000 +0100 | |
3 | +++ tetex-src-3.0/texk/dviljk/dvi2xx.c 2007-11-13 14:53:45.000000000 +0100 | |
4 | @@ -1,5 +1,5 @@ | |
5 | /* $Id$ */ | |
6 | -#define VERSION "2.6p2 (dviljk)" | |
7 | +#define VERSION "dviljk (version 2.6p3)" | |
8 | /* | |
9 | #define DEBUGGS 1 | |
10 | */ | |
11 | @@ -173,7 +173,7 @@ char *argv[]; | |
12 | y_origin = YDEFAULTOFF; /* y-origin in dots */ | |
13 | ||
14 | setbuf(ERR_STREAM, NULL); | |
15 | - (void) strcpy(G_progname, argv[0]); | |
16 | + G_progname = argv[0]; | |
17 | #ifdef KPATHSEA | |
18 | kpse_set_progname(argv[0]); | |
19 | kpse_set_program_enabled (kpse_pk_format, MAKE_TEX_PK_BY_DEFAULT, kpse_src_compile); | |
20 | @@ -2968,8 +2968,8 @@ char *argv[]; | |
21 | #endif | |
22 | { | |
23 | int argind; /* argument index for flags */ | |
24 | - char curarea[STRSIZE]; /* current file area */ | |
25 | - char curname[STRSIZE]; /* current file name */ | |
26 | + char *curarea; /* current file area */ | |
27 | + char *curname; /* current file name */ | |
28 | char *tcp, *tcp1; /* temporary character pointers */ | |
29 | char *this_arg; | |
30 | double x_offset = 0.0, y_offset = 0.0; | |
31 | @@ -2988,9 +2988,9 @@ char *argv[]; | |
32 | #endif | |
33 | #endif | |
34 | ||
35 | - if (argc == 2 && (strcmp (argv[1], "--version") == 0)) { | |
36 | + if (argc == 2 && EQ(argv[1], "--version")) { | |
37 | extern KPSEDLL char *kpathsea_version_string; | |
38 | - puts ("dvilj(k) 2.6"); | |
39 | + puts (VERSION); | |
40 | puts (kpathsea_version_string); | |
41 | puts ("Copyright (C) 1997 Gustaf Neumann.\n\ | |
42 | There is NO warranty. You may redistribute this software\n\ | |
43 | @@ -3328,8 +3328,8 @@ Primary author of Dvi2xx: Gustaf Neumann | |
44 | } | |
45 | } else { | |
46 | ||
47 | - (void) strcpy(filename, tcp); | |
48 | - if (!strcmp(filename, "-")) { | |
49 | + filename = tcp; | |
50 | + if (EQ(filename, "-")) { | |
51 | EmitFileName = "-"; | |
52 | #ifdef RISC_USE_OSL | |
53 | dvifp = BINOPEN("Kbd:"); | |
54 | @@ -3339,57 +3339,68 @@ Primary author of Dvi2xx: Gustaf Neumann | |
55 | AssureBinary(fileno(dvifp)); | |
56 | #endif | |
57 | } else { | |
58 | + /* Since this code is used only once during startup, we don't care | |
59 | + about free()ing the allocated strings that represent filenames. | |
60 | + It will be more work to realize proper deallocation handling than | |
61 | + it's worth in terms of saving a few bytes. We consider these | |
62 | + bytes actually static memory where we don't know the size in | |
63 | + advance and don't add them to the allocated_storage count. | |
64 | + [27 Jun 07 -js] */ | |
65 | #ifdef KPATHSEA | |
66 | /* split into directory + file name */ | |
67 | int tcplen, argvlen; | |
68 | tcp = (char *)xbasename(argv[argind]);/* this knows about any kind of slashes */ | |
69 | tcplen = strlen(tcp); | |
70 | + if ( tcplen == 0 ) { | |
71 | + /* This happens when the DVI file name has a trailing slash; this | |
72 | + is not a valid name. Then we terminate the argument parsing | |
73 | + loop, a usage message will be output below. */ | |
74 | + break; | |
75 | + } | |
76 | argvlen = strlen(argv[argind]); | |
77 | if (tcplen == argvlen) | |
78 | - curarea[0] = '\0'; | |
79 | + curarea = ""; | |
80 | else { | |
81 | - (void) strcpy(curarea, argv[argind]); | |
82 | + curarea = xstrdup(argv[argind]); | |
83 | curarea[argvlen-tcplen] = '\0'; | |
84 | } | |
85 | #else | |
86 | tcp = strrchr(argv[argind], '/'); | |
87 | /* split into directory + file name */ | |
88 | if (tcp == NULL) { | |
89 | - curarea[0] = '\0'; | |
90 | + curarea[0] = ""; | |
91 | tcp = argv[argind]; | |
92 | } else { | |
93 | - (void) strcpy(curarea, argv[argind]); | |
94 | + curarea = xstrdup(argv[argind]); | |
95 | curarea[tcp-argv[argind]+1] = '\0'; | |
96 | tcp += 1; | |
97 | } | |
98 | #endif | |
99 | ||
100 | + curname = (char *) xmalloc(strlen(tcp)+5); /* + space for ".dvi" */ | |
101 | (void) strcpy(curname, tcp); | |
102 | /* split into file name + extension */ | |
103 | - tcp1 = strrchr(tcp, '.'); | |
104 | + tcp1 = strrchr(curname, '.'); | |
105 | if (tcp1 == NULL) { | |
106 | - (void) strcpy(rootname, curname); | |
107 | + rootname = xstrdup(curname); | |
108 | strcat(curname, ".dvi"); | |
109 | } else { | |
110 | *tcp1 = '\0'; | |
111 | - (void) strcpy(rootname, curname); | |
112 | + rootname = xstrdup(curname); | |
113 | *tcp1 = '.'; | |
114 | } | |
115 | ||
116 | + filename = (char *) xmalloc(strlen(curarea)+strlen(curname)+1); | |
117 | (void) strcpy(filename, curarea); | |
118 | (void) strcat(filename, curname); | |
119 | ||
120 | if ((dvifp = BINOPEN(filename)) == FPNULL) { | |
121 | /* do not insist on .dvi */ | |
122 | if (tcp1 == NULL) { | |
123 | - int l = strlen(curname); | |
124 | - if (l > 4) | |
125 | - curname[l - 4] = '\0'; | |
126 | - l = strlen(filename); | |
127 | - if (l > 4) | |
128 | - filename[l - 4] = '\0'; | |
129 | + filename[strlen(filename) - 4] = '\0'; | |
130 | + dvifp = BINOPEN(filename); | |
131 | } | |
132 | - if (tcp1 != NULL || (dvifp = BINOPEN(filename)) == FPNULL) { | |
133 | + if (dvifp == FPNULL) { | |
134 | #ifdef MSC5 | |
135 | Fatal("%s: can't find DVI file \"%s\"\n\n", | |
136 | G_progname, filename); | |
137 | @@ -3411,7 +3422,7 @@ Primary author of Dvi2xx: Gustaf Neumann | |
138 | y_goffset = (short) MM_TO_PXL(y_offset) + y_origin; | |
139 | ||
140 | if (dvifp == FPNULL) { | |
141 | - fprintf(ERR_STREAM,"\nThis is the DVI to %s converter version %s", | |
142 | + fprintf(ERR_STREAM,"\nThis is the DVI to %s converter %s", | |
143 | PRINTER, VERSION); | |
144 | #ifdef SEVENBIT | |
145 | fprintf(ERR_STREAM,", 7bit"); | |
146 | @@ -3507,13 +3518,8 @@ Primary author of Dvi2xx: Gustaf Neumann | |
147 | exit(1); | |
148 | } | |
149 | if (EQ(EmitFileName, "")) { | |
150 | - if ((EmitFileName = (char *)malloc( STRSIZE )) != NULL) | |
151 | - allocated_storage += STRSIZE; | |
152 | - else | |
153 | - Fatal("Can't allocate storage of %d bytes\n",STRSIZE); | |
154 | - (void) strcpy(EmitFileName, curname); | |
155 | - if ((tcp1 = strrchr(EmitFileName, '.'))) | |
156 | - *tcp1 = '\0'; | |
157 | + EmitFileName = (char *) xmalloc(strlen(rootname)+sizeof(EMITFILE_EXTENSION)); | |
158 | + (void) strcpy(EmitFileName, rootname); | |
159 | strcat(EmitFileName, EMITFILE_EXTENSION); | |
160 | } | |
161 | if (G_quiet) | |
162 | @@ -3698,6 +3704,8 @@ bool PFlag; | |
163 | #endif | |
164 | } | |
165 | CloseFiles(); | |
166 | + if ( tmp_dir[0] != '\0' ) | |
167 | + rmdir (tmp_dir); /* ignore errors */ | |
168 | exit(G_errenc); | |
169 | } | |
170 | ||
171 | @@ -3895,22 +3903,21 @@ char *str; | |
172 | int n; | |
173 | #endif | |
174 | { | |
175 | - char spbuf[STRSIZE], xs[STRSIZE], ys[STRSIZE]; | |
176 | - char *sf = NULL, *psfile = NULL; | |
177 | + char xs[STRSIZE], ys[STRSIZE]; | |
178 | + char *include_file = NULL; | |
179 | + enum { VerbFile, HPFile, PSFile } file_type; | |
180 | float x,y; | |
181 | long4 x_pos, y_pos; | |
182 | KeyWord k; | |
183 | int i, j, j1; | |
184 | static int GrayScale = 10, Pattern = 1; | |
185 | static bool GrayFill = _TRUE; | |
186 | - static long4 p_x[80], p_y[80]; | |
187 | - int llx=0, lly=0, urx=0, ury=0, rwi=0, rhi=0; | |
188 | -#ifdef WIN32 | |
189 | - char *gs_path; | |
190 | -#endif | |
191 | + static long4 p_x[MAX_SPECIAL_DEFPOINTS], p_y[MAX_SPECIAL_DEFPOINTS]; | |
192 | + int llx=0, lly=0, urx=0, ury=0, rwi=0; | |
193 | ||
194 | str[n] = '\0'; | |
195 | - spbuf[0] = '\0'; | |
196 | + for ( i=0 ; i<MAX_SPECIAL_DEFPOINTS ; i++ ) | |
197 | + p_x[i] = p_y[i] = -1; | |
198 | ||
199 | SetPosn(h, v); | |
200 | #ifdef __riscos | |
201 | @@ -3924,41 +3931,30 @@ int n; | |
202 | /* get all keyword-value pairs */ | |
203 | /* for compatibility, single words are taken as file names */ | |
204 | if ( k.vt == None && access(k.Key, 0) == 0) { | |
205 | - if ( sf | |
206 | -#ifdef KPATHSEA | |
207 | - && !kpse_tex_hush ("special") | |
208 | -#endif | |
209 | - ) | |
210 | - Warning("More than one \\special file name given. %s ignored", sf); | |
211 | - (void) strcpy(spbuf, k.Key); | |
212 | - sf = spbuf; | |
213 | - /* | |
214 | - for (j = 1; ((sf[j]=='/' ? sf[j]='\\':sf[j]) != '\0'); j++); | |
215 | - */ | |
216 | - } else if ( GetKeyVal( &k, KeyTab, NKEYS, &i ) && i != -1 ) | |
217 | + if ( include_file && !kpse_tex_hush ("special") ) { | |
218 | + Warning("More than one \\special file name given. %s ignored", include_file); | |
219 | + free (include_file); | |
220 | + } | |
221 | + include_file = xstrdup(k.Key); | |
222 | + file_type = VerbFile; | |
223 | + } else if ( GetKeyVal( &k, KeyTab, NKEYS, &i ) && i != -1 ) { | |
224 | switch (i) { | |
225 | case PSFILE: | |
226 | - if (sf | |
227 | -#ifdef KPATHSEA | |
228 | - && !kpse_tex_hush ("special") | |
229 | -#endif | |
230 | - ) | |
231 | - Warning("More than one \\special file name given. %s ignored", sf); | |
232 | - (void) strcpy(spbuf, k.Val); | |
233 | - psfile = spbuf; | |
234 | - /* | |
235 | - for (j=1; ((sf[j]=='/' ? sf[j]='\\':sf[j]) != '\0'); j++); | |
236 | - */ | |
237 | + if ( include_file ) { | |
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 = PSFile; | |
243 | break; | |
244 | ||
245 | case HPFILE: | |
246 | - if (sf) | |
247 | - Warning("More than one \\special file name given. %s ignored", sf); | |
248 | - (void) strcpy(spbuf, k.Val); | |
249 | - sf = spbuf; | |
250 | - /* | |
251 | - for (j=1; ((sf[j]=='/' ? sf[j]='\\':sf[j]) != '\0'); j++); | |
252 | - */ | |
253 | + if ( include_file && !kpse_tex_hush ("special") ) { | |
254 | + Warning("More than one \\special file name given. %s ignored", include_file); | |
255 | + free(include_file); | |
256 | + } | |
257 | + include_file = xstrdup(k.Val); | |
258 | + file_type = HPFile; | |
259 | break; | |
260 | ||
261 | case ORIENTATION: | |
262 | @@ -3978,23 +3974,24 @@ int n; | |
263 | } | |
264 | #endif | |
265 | else | |
266 | -#ifdef KPATHSEA | |
267 | - if (!kpse_tex_hush ("special")) | |
268 | -#endif | |
269 | Warning( "Invalid orientation (%d)given; ignored.", k.v.i); | |
270 | break; | |
271 | ||
272 | case RESETPOINTS: | |
273 | - (void) strcpy(spbuf, k.Val); | |
274 | - | |
275 | - sf = NULL; | |
276 | + for ( i=0 ; i<MAX_SPECIAL_DEFPOINTS ; i++ ) | |
277 | + p_x[i] = p_y[i] = -1; | |
278 | break; | |
279 | ||
280 | case DEFPOINT: | |
281 | - (void) strcpy(spbuf, k.Val); | |
282 | - i = sscanf(spbuf,"%d(%[^,],%s)",&j,xs,ys); | |
283 | + /* 254 is STRSIZE-1. cpp should be used to construct that number. */ | |
284 | + i = sscanf(k.Val,"%d(%254[^,],%254s)",&j,xs,ys); | |
285 | if (i>0) { | |
286 | - x_pos = h; | |
287 | + if ( j < 0 || j >= MAX_SPECIAL_DEFPOINTS ) { | |
288 | + Warning ("defpoint %d ignored, must be between 0 and %d", | |
289 | + j, MAX_SPECIAL_DEFPOINTS); | |
290 | + break; | |
291 | + } | |
292 | + x_pos = h; | |
293 | y_pos = v; | |
294 | if (i>1) { | |
295 | if (sscanf(xs,"%fpt",&x)>0) { | |
296 | @@ -4011,19 +4008,32 @@ int n; | |
297 | p_x[j]=x_pos; | |
298 | p_y[j]=y_pos; | |
299 | } else | |
300 | -#ifdef KPATHSEA | |
301 | - if (!kpse_tex_hush ("special")) | |
302 | -#endif | |
303 | Warning("invalid point definition\n"); | |
304 | - | |
305 | - sf = NULL; | |
306 | break; | |
307 | ||
308 | case FILL: | |
309 | - (void) strcpy(spbuf, k.Val); | |
310 | - i = sscanf(spbuf,"%d/%d %s",&j,&j1,xs); | |
311 | + /* 254 is STRSIZE-1. cpp should be used to construct that number. */ | |
312 | + i = sscanf(k.Val,"%d/%d %254s",&j,&j1,xs); | |
313 | if (i>1) { | |
314 | #ifdef LJ | |
315 | + if ( j < 0 || j >= MAX_SPECIAL_DEFPOINTS ) { | |
316 | + Warning ("fill ignored, point %d must be between 0 and %d", | |
317 | + j, MAX_SPECIAL_DEFPOINTS); | |
318 | + break; | |
319 | + } | |
320 | + if ( p_x[j] == -1 ) { | |
321 | + Warning ("fill ignored, point %d is undefined\n", j); | |
322 | + break; | |
323 | + } | |
324 | + if ( j1 < 0 || j1 >= MAX_SPECIAL_DEFPOINTS ) { | |
325 | + Warning ("fill ignored, point %d must be between 0 and %d", | |
326 | + j1, MAX_SPECIAL_DEFPOINTS); | |
327 | + break; | |
328 | + } | |
329 | + if ( p_x[j1] == -1 ) { | |
330 | + Warning ("fill ignored, point %d is undefined\n", j1); | |
331 | + break; | |
332 | + } | |
333 | SetPosn(p_x[j], p_y[j]); | |
334 | x_pos = (long4)PIXROUND(p_x[j1]-p_x[j], hconv); | |
335 | y_pos = (long4)PIXROUND(p_y[j1]-p_y[j], vconv); | |
336 | @@ -4044,9 +4054,6 @@ int n; | |
337 | GrayScale = k.v.i; | |
338 | GrayFill = _TRUE; | |
339 | } else | |
340 | -#ifdef KPATHSEA | |
341 | - if (!kpse_tex_hush ("special")) | |
342 | -#endif | |
343 | Warning( "Invalid gray scale (%d) given; ignored.", k.v.i); | |
344 | break; | |
345 | ||
346 | @@ -4055,9 +4062,6 @@ int n; | |
347 | Pattern = k.v.i; | |
348 | GrayFill = _FALSE; | |
349 | } else | |
350 | -#ifdef KPATHSEA | |
351 | - if (!kpse_tex_hush ("special")) | |
352 | -#endif | |
353 | Warning( "Invalid pattern (%d) given; ignored.", k.v.i); | |
354 | break; | |
355 | ||
356 | @@ -4066,75 +4070,123 @@ int n; | |
357 | case URX: urx = k.v.i; break; | |
358 | case URY: ury = k.v.i; break; | |
359 | case RWI: rwi = k.v.i; break; | |
360 | - case RHI: rhi = k.v.i; break; | |
361 | + case RHI: | |
362 | + if (!kpse_tex_hush ("special")) | |
363 | + Warning("Whatever rhi was good for once, it is ignored now."); | |
364 | + break; | |
365 | ||
366 | default: | |
367 | -#ifdef KPATHSEA | |
368 | - if (!kpse_tex_hush ("special")) | |
369 | -#endif | |
370 | + if ( !kpse_tex_hush ("special") ) | |
371 | Warning("Can't handle %s=%s command; ignored.", k.Key, k.Val); | |
372 | break; | |
373 | } | |
374 | - | |
375 | - else | |
376 | -#ifdef KPATHSEA | |
377 | - if (!kpse_tex_hush ("special")) | |
378 | -#endif | |
379 | + | |
380 | + } else if (!kpse_tex_hush ("special")) { | |
381 | Warning("Invalid keyword or value in \\special - <%s> ignored", k.Key); | |
382 | + } | |
383 | + | |
384 | + free (k.Key); | |
385 | + if ( k.Val != NULL ) free(k.Val); | |
386 | } | |
387 | ||
388 | - if ( sf || psfile ) { | |
389 | + if ( include_file ) { | |
390 | last_rx = last_ry = UNKNOWN; | |
391 | #ifdef IBM3812 | |
392 | PMPflush; | |
393 | #endif | |
394 | - if (sf) { | |
395 | - if (i == HPFILE) | |
396 | - CopyHPFile( sf ); | |
397 | - else | |
398 | - CopyFile( sf ); | |
399 | - } | |
400 | - else | |
401 | + | |
402 | #ifdef LJ | |
403 | - if (psfile) { | |
404 | + if ( file_type == PSFile) { | |
405 | /* int height = rwi * (urx - llx) / (ury - lly);*/ | |
406 | int width = urx - llx; | |
407 | int height = ury - lly; | |
408 | char cmd[255]; | |
409 | - int scale_factor = 3000 * width / rwi; | |
410 | - int adjusted_height = height * 300/scale_factor; | |
411 | - int adjusted_llx = llx * 300/scale_factor; | |
412 | + char *cmd_format = "%s -q -dSIMPLE -dSAFER -dNOPAUSE -sDEVICE=%s -sOutputFile=%s %s %s showpage.ps -c quit"; | |
413 | + char *gs_cmd; | |
414 | + int scale_factor, adjusted_height, adjusted_llx; | |
415 | char *printer = "ljetplus"; /* use the most stupid one */ | |
416 | ||
417 | - | |
418 | - char scale_file_name[255]; | |
419 | - char *scale_file = tmpnam(scale_file_name); | |
420 | - char *pcl_file = tmpnam(NULL); | |
421 | + char pcl_file[STRSIZE]; | |
422 | + char scale_file[STRSIZE]; | |
423 | FILEPTR scalef; | |
424 | ||
425 | - if ( (scalef = BOUTOPEN(scale_file)) == FPNULL ) { | |
426 | - Warning("Unable to open file %s for writing", scale_file ); | |
427 | - return; | |
428 | - } | |
429 | - fprintf(scalef, "%.2f %.2f scale\n%d %d translate\n", | |
430 | - 300.0/scale_factor, 300.0/scale_factor, | |
431 | - 0, adjusted_height == height ? 0 : ury); | |
432 | - BCLOSE( scalef ); | |
433 | + if ( urx == 0 || ury == 0 || rwi == 0 ) { | |
434 | + /* Since dvips' psfile special has a different syntax, this might | |
435 | + well be one of those specials, i.e., a non-dviljk special. Then | |
436 | + the Warning should be suppressable. */ | |
437 | + if ( !kpse_tex_hush ("special") ) | |
438 | + Warning ("Ignoring psfile special without urx, ury and rwi attributes"); | |
439 | + free (include_file); | |
440 | + return; | |
441 | + } | |
442 | + scale_factor = 3000 * width / rwi; | |
443 | + adjusted_height = height * 300/scale_factor; | |
444 | + adjusted_llx = llx * 300/scale_factor; | |
445 | + | |
446 | + /* We cannot use mkstemp, as we cannot pass two open file descriptors | |
447 | + portably to Ghostscript. We don't want to use tmpnam() or tempnam() | |
448 | + either, as they have tempfile creation race conditions. Instead we | |
449 | + create a temporary directory with mkdtemp() -- if that's available. | |
450 | + If not, we are thrown back to tempnam(), to get our functionality | |
451 | + at all. We need to create the temporary directory only once per | |
452 | + run; it will be deleted in AllDone(). */ | |
453 | + if ( tmp_dir[0] == '\0' ) { | |
454 | + char * base_dir; | |
455 | + if ( (base_dir = getenv("TMPDIR")) == NULL ) { | |
456 | + base_dir = "/tmp"; | |
457 | + } else if ( strlen(base_dir) > STRSIZE - sizeof("/dviljkXXXXXX/include.pcl") ) { | |
458 | + Warning ("TMPDIR %s is too long, using /tmp instead", base_dir); | |
459 | + base_dir = "/tmp"; | |
460 | + } | |
461 | + if ( base_dir[0] == '/' && base_dir[1] == '\0' ) { | |
462 | + Warning ("Feeling naughty, do we? / is no temporary directory, dude"); | |
463 | + base_dir = "/tmp"; | |
464 | + } | |
465 | + strcpy (tmp_dir, base_dir); | |
466 | + strcat (tmp_dir, "/dviljkXXXXXX"); | |
467 | + if ( mkdtemp(tmp_dir) == NULL ) { | |
468 | + Warning ("Could not create temporary directory %s, errno = %d; ignoring include file special", | |
469 | + tmp_dir, errno); | |
470 | + return; | |
471 | + } | |
472 | + } | |
473 | + strcpy(pcl_file, tmp_dir); | |
474 | + strcat(pcl_file, "/include.pcl"); | |
475 | + strcpy(scale_file, tmp_dir); | |
476 | + strcat(scale_file, "/scale.ps"); | |
477 | + | |
478 | + if ( (scalef = BOUTOPEN(scale_file)) == FPNULL ) { | |
479 | + Warning("Unable to open file %s for writing", scale_file ); | |
480 | + free (include_file); | |
481 | + unlink(scale_file); /* ignore error */ | |
482 | + return; | |
483 | + } | |
484 | + fprintf(scalef, "%.2f %.2f scale\n%d %d translate\n", | |
485 | + 300.0/scale_factor, 300.0/scale_factor, | |
486 | + 0, adjusted_height == height ? 0 : ury); | |
487 | + BCLOSE( scalef ); | |
488 | ||
489 | #ifdef WIN32 | |
490 | - gs_path = getenv("GS_PATH"); | |
491 | - if (!gs_path) | |
492 | - gs_path = "gswin32c.exe"; | |
493 | - sprintf(cmd,"%s -q -dSIMPLE -dSAFER -dNOPAUSE -sDEVICE=%s -sOutputFile=%s %s %s showpage.ps -c quit", | |
494 | - gs_path, printer, pcl_file, scale_file, psfile); | |
495 | + if ( (gs_cmd = getenv("GS_PATH")) == NULL ) | |
496 | + gs_cmd = "gswin32c.exe"; | |
497 | #else | |
498 | - sprintf(cmd,"gs -q -dSIMPLE -dSAFER -dNOPAUSE -sDEVICE=%s -sOutputFile=%s %s %s showpage.ps -c quit", | |
499 | - printer, pcl_file, scale_file, psfile); | |
500 | + gs_cmd = "gs"; | |
501 | #endif | |
502 | + if ( strlen(cmd_format)-10 + strlen(gs_cmd) + strlen(printer) + | |
503 | + strlen(pcl_file) + strlen(scale_file) + strlen(include_file) +1 > | |
504 | + sizeof(cmd) ) { | |
505 | + Warning ("Ghostscript command for %s would be too long, skipping special", include_file); | |
506 | + free (include_file); | |
507 | + unlink(scale_file); /* ignore errors */ | |
508 | + unlink(pcl_file); | |
509 | + return; | |
510 | + } | |
511 | + sprintf(cmd, cmd_format, | |
512 | + gs_cmd, printer, pcl_file, scale_file, include_file); | |
513 | #ifdef DEBUGGS | |
514 | fprintf(stderr, | |
515 | "PS-file '%s' w=%d, h=%d, urx=%d, ury=%d, llx=%d, lly=%d, rwi=%d\n", | |
516 | - psfile, urx - llx, height, urx,ury,llx,lly, rwi); | |
517 | + include_file, urx - llx, height, urx,ury,llx,lly, rwi); | |
518 | fprintf(stderr,"%s\n",cmd); | |
519 | #endif | |
520 | if (system(cmd)) { | |
521 | @@ -4158,11 +4210,21 @@ int n; | |
522 | #endif | |
523 | ||
524 | CopyHPFile( pcl_file ); | |
525 | - /* unlink(pcl_file); */ | |
526 | - /* unlink(scale_file); */ | |
527 | - } | |
528 | } | |
529 | + unlink(scale_file); /* ignore errors */ | |
530 | + unlink(pcl_file); | |
531 | + } | |
532 | + else | |
533 | #endif /* LJ */ | |
534 | + | |
535 | + if ( file_type == HPFile ) | |
536 | + CopyHPFile( include_file ); | |
537 | + else if ( file_type == VerbFile ) | |
538 | + CopyFile( include_file ); | |
539 | + else | |
540 | + Warning ("This can't happen: unknown file_type value %d", file_type); | |
541 | + | |
542 | + if ( include_file != NULL ) free(include_file); | |
543 | } | |
544 | } | |
545 | ||
546 | @@ -4173,12 +4235,11 @@ int n; | |
547 | /**********************************************************************/ | |
548 | /***************************** GetKeyStr ****************************/ | |
549 | /**********************************************************************/ | |
550 | -/* extract first keyword-value pair from string (value part may be null) | |
551 | - * return pointer to remainder of string | |
552 | - * return NULL if none found | |
553 | +/* Extract first keyword-value pair from string (value part may be null), | |
554 | + * keyword and value are allocated and must be free by caller. | |
555 | + * Return pointer to remainder of string, | |
556 | + * return NULL if none found. | |
557 | */ | |
558 | -char KeyStr[STRSIZE]; | |
559 | -char ValStr[STRSIZE]; | |
560 | #if NeedFunctionPrototypes | |
561 | char *GetKeyStr(char *str, KeyWord *kw ) | |
562 | #else | |
563 | @@ -4187,39 +4248,46 @@ char *str; | |
564 | KeyWord *kw; | |
565 | #endif | |
566 | { | |
567 | - char *s, *k, *v, t; | |
568 | + char *s, *start; | |
569 | + char save_char, quote_char; | |
570 | if ( !str ) | |
571 | return( NULL ); | |
572 | for (s = str; *s == ' '; s++) | |
573 | ; /* skip over blanks */ | |
574 | if (*s == '\0') | |
575 | return( NULL ); | |
576 | - for (k = KeyStr; /* extract keyword portion */ | |
577 | - *s != ' ' && *s != '\0' && *s != '='; | |
578 | - *k++ = *s++) | |
579 | - ; | |
580 | - *k = '\0'; | |
581 | - kw->Key = KeyStr; | |
582 | - kw->Val = v = NULL; | |
583 | + start = s++; /* start of keyword */ | |
584 | + while ( *s != ' ' && *s != '\0' && *s != '=' ) /* locate end */ | |
585 | + s++; | |
586 | + save_char = *s; | |
587 | + *s = '\0'; | |
588 | + kw->Key = xstrdup(start); | |
589 | + kw->Val = NULL; | |
590 | kw->vt = None; | |
591 | - for ( ; *s == ' '; s++) | |
592 | - ; /* skip over blanks */ | |
593 | - if ( *s != '=' ) /* look for "=" */ | |
594 | + if ( save_char == '\0' ) /* shortcut when we're at the end */ | |
595 | + return (s); | |
596 | + *s = save_char; /* restore keyword end char */ | |
597 | + while ( *s == ' ' ) s++ ; /* skip over blanks */ | |
598 | + if ( *s != '=' ) /* no "=" means no value */ | |
599 | return( s ); | |
600 | - for (s++; *s == ' '; s++); /* skip over blanks */ | |
601 | - if ( *s == '\'' || *s == '\"' ) /* get string delimiter */ | |
602 | - t = *s++; | |
603 | + for (s++; *s == ' '; s++) | |
604 | + ; /* skip over blanks */ | |
605 | + if ( *s == '\'' || *s == '\"' ) /* get string delimiter */ | |
606 | + quote_char = *s++; | |
607 | else | |
608 | - t = ' '; | |
609 | - for (v = ValStr; /* copy value portion up to delim */ | |
610 | - *s != t && *s != '\0'; | |
611 | - *v++ = *s++) | |
612 | - ; | |
613 | - if ( t != ' ' && *s == t ) | |
614 | - s++; | |
615 | - *v = '\0'; | |
616 | - kw->Val = ValStr; | |
617 | + quote_char = ' '; | |
618 | + start = s; /* no increment, might be "" as value */ | |
619 | + while ( *s != quote_char && *s != '\0' ) | |
620 | + s++; /* locate end of value portion */ | |
621 | + save_char = *s; | |
622 | + *s = '\0'; | |
623 | + kw->Val = xstrdup(start); | |
624 | kw->vt = String; | |
625 | + if ( save_char != '\0' ) { /* save_char is now quote_char */ | |
626 | + *s = save_char; | |
627 | + if ( quote_char != ' ' ) /* we had real quote chars */ | |
628 | + s++; | |
629 | + } | |
630 | return( s ); | |
631 | } | |
632 | ||
633 | @@ -4819,13 +4887,14 @@ struct font_entry *fontptr; | |
634 | the resident fonts. */ | |
635 | if (tfm_read_info(fontptr->n, &tfm_info) | |
636 | && tfm_info.family[0] | |
637 | - && strcmp((char *)tfm_info.family, "HPAUTOTFM") == 0) { | |
638 | + && EQ((char *)tfm_info.family, "HPAUTOTFM")) { | |
639 | unsigned i; | |
640 | double factor = fontptr->s / (double)0x100000; | |
641 | ||
642 | resident_count++; | |
643 | fontptr->resident_p = _TRUE; | |
644 | - strcpy(fontptr->symbol_set, (char *)tfm_info.coding_scheme); | |
645 | + strncpy(fontptr->symbol_set, (char *)tfm_info.coding_scheme, 39); | |
646 | + fontptr->symbol_set[39] = '\0'; | |
647 | fontptr->resid = tfm_info.typeface_id; | |
648 | fontptr->spacing = tfm_info.spacing; | |
649 | fontptr->style = tfm_info.style; | |
650 | @@ -4878,7 +4947,7 @@ struct font_entry *fontptr; | |
651 | fontptr->resident_p = _FALSE; | |
652 | ||
653 | if (tfm_info.family[0] | |
654 | - && strcmp((char *)tfm_info.family, "UNSPECIFIED") == 0) { | |
655 | + && EQ((char *)tfm_info.family, "UNSPECIFIED")) { | |
656 | Warning("font family for %s is UNSPECIFIED; need to run dvicopy?", | |
657 | fontptr->n); | |
658 | fontptr->font_file_id = NO_FILE; | |
659 | @@ -5031,10 +5100,9 @@ printf("[%ld]=%lf * %lf * %lf + 0.5 = %l | |
660 | if (tfontptr->resident_p) | |
661 | return; | |
662 | ||
663 | - if (!(resident_font_located)) { | |
664 | + if (!(resident_font_located)) | |
665 | #endif | |
666 | ||
667 | -#ifdef KPATHSEA | |
668 | { | |
669 | kpse_glyph_file_type font_ret; | |
670 | char *name; | |
671 | @@ -5047,9 +5115,9 @@ printf("[%ld]=%lf * %lf * %lf + 0.5 = %l | |
672 | if (name) | |
673 | { | |
674 | font_found = _TRUE; | |
675 | - strcpy (tfontptr->name, name); | |
676 | - free (name); | |
677 | - | |
678 | + tfontptr->name = name; | |
679 | + allocated_storage += strlen(name)+1; | |
680 | + | |
681 | if (!FILESTRCASEEQ (tfontptr->n, font_ret.name)) { | |
682 | fprintf (stderr, | |
683 | "dvilj: Font %s not found, using %s at %d instead.\n", | |
684 | @@ -5071,29 +5139,6 @@ printf("[%ld]=%lf * %lf * %lf + 0.5 = %l | |
685 | tfontptr->n, dpi); | |
686 | } | |
687 | } | |
688 | -#else /* not KPATHSEA */ | |
689 | - if (!(findfile(PXLpath, | |
690 | - tfontptr->n, | |
691 | - tfontptr->font_mag, | |
692 | - tfontptr->name, | |
693 | - _FALSE, | |
694 | - 0))) { | |
695 | - Warning(tfontptr->name); /* contains error messsage */ | |
696 | - tfontptr->font_file_id = NO_FILE; | |
697 | -#ifdef __riscos | |
698 | - MakeMetafontFile(PXLpath, tfontptr->n, tfontptr->font_mag); | |
699 | -#endif | |
700 | - } | |
701 | - else { | |
702 | - font_found = _TRUE; | |
703 | - if (G_verbose) | |
704 | - fprintf(ERR_STREAM,"%d: using font <%s>\n", plusid, tfontptr->name); | |
705 | - } | |
706 | -#endif /* not KPATHSEA */ | |
707 | - | |
708 | -#ifdef LJ_RESIDENT_FONTS | |
709 | - } | |
710 | -#endif | |
711 | ||
712 | tfontptr->plusid = plusid; | |
713 | plusid++; | |
714 | diff -U0 tetex-src-3.0/texk/dviljk/ChangeLog.dviljktemp tetex-src-3.0/texk/dviljk/ChangeLog | |
715 | --- tetex-src-3.0/texk/dviljk/ChangeLog.dviljktemp 1998-03-03 11:17:39.000000000 +0100 | |
716 | +++ tetex-src-3.0/texk/dviljk/ChangeLog 2007-11-13 14:59:19.000000000 +0100 | |
717 | @@ -0,0 +1,39 @@ | |
718 | +2007-07-02 Joachim Schrod <jschrod@acm.org> | |
719 | + | |
720 | + * dvi2xx.c (DoSpecial): Security issue: usage of tmpnam() caused | |
721 | + tempfile race condition. I use mkdtemp() if it's available and | |
722 | + fall back to tmpnam. | |
723 | + | |
724 | + Special parsing of include files was inconsistent, unify it. The | |
725 | + current parsing code still allows lots of non-sensical special | |
726 | + commands, but at least it doesn't access unrelated variables any | |
727 | + more. | |
728 | + | |
729 | +2007-06-28 Joachim Schrod <jschrod@acm.org> | |
730 | + | |
731 | + * dvi2xx.c: Fixed a whole bunch of buffer overflows: The program | |
732 | + did not check memory bounds for any string operation. All places | |
733 | + where strings are copied with strcpy are replaced by dynamically | |
734 | + allocated strings (with xstrdup from kpathsea) or bounded string | |
735 | + operations. Fixed also manual string copy operations on special | |
736 | + strings. Fixed array buffer overflow in defpoint and fill special | |
737 | + operations. | |
738 | + (DoSpecial): Call of ghostscript for psfile special had also a | |
739 | + potential buffer overflow caused by unchecked usage of sprintf. | |
740 | + Fix core dump: Check if all required parameters of psfile special | |
741 | + are passed. | |
742 | + | |
743 | + Bumped version number up to 2.6p3. | |
744 | + | |
745 | + * dvi2xx.h: Some fixed sized string arrays are pointers now, they | |
746 | + get dynamically allocated. | |
747 | + (GetBytes): Another buffer overflow: Check that the buffer size is | |
748 | + sufficient to store the read bytes. That relies on the invariant | |
749 | + that the GetBytes macro is always called with an array as argument | |
750 | + and not with a pointer. | |
751 | + | |
752 | + * config.h: Throw an error if kpathsea is not used. dvi2xx.c | |
753 | + had previously already kpathsea dependencies without protecting | |
754 | + them with #if KPATHSEA. We go that road further since upstream | |
755 | + does not exist any more. | |
756 | + | |
757 | diff -up tetex-src-3.0/texk/dviljk/configure.dviljktemp tetex-src-3.0/texk/dviljk/configure | |
758 | diff -up tetex-src-3.0/texk/dviljk/configure.in.dviljktemp tetex-src-3.0/texk/dviljk/configure.in | |
759 | --- tetex-src-3.0/texk/dviljk/configure.in.dviljktemp 1999-02-08 22:42:01.000000000 +0100 | |
760 | +++ tetex-src-3.0/texk/dviljk/configure.in 2007-11-13 14:55:04.000000000 +0100 | |
761 | @@ -13,6 +13,7 @@ sinclude(../kpathsea/withenable.ac) | |
762 | dnl These tests prevent reliable cross-compilation. Sigh. | |
763 | AC_C_CHAR_UNSIGNED | |
764 | AC_CHECK_SIZEOF(long) | |
765 | +AC_CHECK_FUNCS(rmdir unlink mkdtemp) | |
766 | ||
767 | AC_OUTPUT(Makefile) | |
768 | dnl Update stamp-auto, since we just remade `c-auto.h'. | |
769 | diff -up tetex-src-3.0/texk/dviljk/dvi2xx.h.dviljktemp tetex-src-3.0/texk/dviljk/dvi2xx.h | |
770 | --- tetex-src-3.0/texk/dviljk/dvi2xx.h.dviljktemp 1999-03-16 08:03:33.000000000 +0100 | |
771 | +++ tetex-src-3.0/texk/dviljk/dvi2xx.h 2007-11-13 14:53:45.000000000 +0100 | |
772 | @@ -10,8 +10,8 @@ | |
773 | ||
774 | #ifdef KPATHSEA | |
775 | #include <kpathsea/config.h> | |
776 | +#include <kpathsea/c-std.h> | |
777 | #include <kpathsea/c-limits.h> | |
778 | -#include <kpathsea/c-memstr.h> | |
779 | #include <kpathsea/magstep.h> | |
780 | #include <kpathsea/proginit.h> | |
781 | #include <kpathsea/progname.h> | |
782 | @@ -24,6 +24,7 @@ | |
783 | #include <string.h> | |
784 | #include <stdio.h> | |
785 | #include <stdlib.h> | |
786 | +#include <unistd.h> | |
787 | #ifdef unix | |
788 | #include <limits.h> | |
789 | #endif | |
790 | @@ -41,9 +42,6 @@ | |
791 | #ifdef MSC5 | |
792 | #include <dos.h> /* only for binaryopen on device */ | |
793 | #endif | |
794 | -#if defined (unix) && !defined (KPATHSEA) | |
795 | -#include <limits.h> | |
796 | -#endif | |
797 | ||
798 | ||
799 | #include "config.h" | |
800 | @@ -116,6 +114,7 @@ | |
801 | #define HUGE_SIZE (unsigned char) 2 | |
802 | #define HUGE_CHAR_PATTERN 32767l | |
803 | #define BYTES_PER_PIXEL_LINE 500 /* max number of bytes per pixel line */ | |
804 | +#define MAX_SPECIAL_DEFPOINTS 80 /* max number of defpoint specials */ | |
805 | ||
806 | ||
807 | #define PK_POST 245 | |
808 | @@ -281,7 +280,14 @@ char *MFMODE = MFMODE600; | |
809 | #define VisChar(c) (unsigned char)(c) | |
810 | #endif | |
811 | ||
812 | -#define GetBytes(fp,buf,n) read_multi(buf,1,n,fp) /* used to be a function */ | |
813 | +/* Used to be a function. buf is always an array, never a pointer. | |
814 | + Without that invariant, we would have to introduce full dynamic | |
815 | + memory management in this driver -- probably it would be easier to | |
816 | + write a new one. [27 Jun 07 -js] */ | |
817 | +#define GetBytes(fp,buf,n) \ | |
818 | + ( sizeof(buf) != sizeof(void *) && sizeof(buf) > n ? \ | |
819 | + read_multi(buf, 1, n, fp) \ | |
820 | + : Fatal("Try to read %d bytes in an array of size %d", n, sizeof(buf)) ) | |
821 | ||
822 | ||
823 | /**********************************************************************/ | |
824 | @@ -307,6 +313,7 @@ int printf(); | |
825 | int sscanf(); | |
826 | int strcmp(); | |
827 | char *strcpy(); | |
828 | +char *strncpy(); | |
829 | # ifdef MSC5 | |
830 | unsigned int strlen(); | |
831 | # endif | |
832 | @@ -393,7 +400,7 @@ struct font_entry { /* font entry */ | |
833 | char n[STRSIZE]; /* FNT_DEF command parameters */ | |
834 | long4 font_mag; /* computed from FNT_DEF s and d parameters */ | |
835 | /*char psname[STRSIZE];*/ /* PostScript name of the font */ | |
836 | - char name[STRSIZE]; /* full name of PXL file */ | |
837 | + char *name; /* full name of PXL file */ | |
838 | FILEPTR font_file_id; /* file identifier (NO_FILE if none) */ | |
839 | #ifdef USEPXL | |
840 | long4 magnification; /* magnification read from PXL file */ | |
841 | @@ -487,8 +494,8 @@ void LoadAChar DVIPROTO((long4, regis | |
842 | long4 NoSignExtend DVIPROTO((FILEPTR, int)); | |
843 | void OpenFontFile DVIPROTO((void)); | |
844 | long4 PixRound DVIPROTO((long4, long4)); | |
845 | -void PkRaster DVIPROTO((struct char_entry *, int)); | |
846 | -void RasterLine DVIPROTO((struct char_entry *, unsigned int, | |
847 | +void PkRaster DVIPROTO((struct char_entry *, int)); | |
848 | +void RasterLine DVIPROTO((struct char_entry *, unsigned int, | |
849 | unsigned int, unsigned char *)); | |
850 | void RasterChar DVIPROTO((struct char_entry *)); | |
851 | void ReadFontDef DVIPROTO((long4)); | |
852 | @@ -534,11 +541,12 @@ bool LastPageSpecified = _FALSE; | |
853 | #ifndef KPATHSEA | |
854 | char *PXLpath = FONTAREA; | |
855 | #endif | |
856 | -char G_progname[STRSIZE]; /* program name */ | |
857 | -char filename[STRSIZE]; /* DVI file name */ | |
858 | -char rootname[STRSIZE]; /* DVI filename without extension */ | |
859 | +char *G_progname; /* program name */ | |
860 | +char *filename; /* DVI file name */ | |
861 | +char *rootname; /* DVI filename without extension */ | |
862 | char *HeaderFileName = ""; /* file name & path of Headerfile */ | |
863 | char *EmitFileName = ""; /* file name & path for output */ | |
864 | +char tmp_dir[STRSIZE] = ""; /* temporary directory for auxilliary files */ | |
865 | #ifdef IBM3812 | |
866 | bool FirstAlternate = _FALSE; /* first page from alternate casette ? */ | |
867 | #endif | |
868 | diff -up tetex-src-3.0/texk/dviljk/c-auto.in.dviljktemp tetex-src-3.0/texk/dviljk/c-auto.in | |
869 | --- tetex-src-3.0/texk/dviljk/c-auto.in.dviljktemp 1999-03-23 23:40:08.000000000 +0100 | |
870 | +++ tetex-src-3.0/texk/dviljk/c-auto.in 2007-11-13 14:53:45.000000000 +0100 | |
871 | @@ -1,9 +1,23 @@ | |
872 | -/* c-auto.in. Generated automatically from configure.in by autoheader. */ | |
873 | +/* c-auto.in. Generated from configure.in by autoheader. */ | |
874 | +/* acconfig.h -- used by autoheader when generating c-auto.in. | |
875 | ||
876 | -/* Define if type char is unsigned and you are not using gcc. */ | |
877 | -#ifndef __CHAR_UNSIGNED__ | |
878 | -#undef __CHAR_UNSIGNED__ | |
879 | -#endif | |
880 | + If you're thinking of editing acconfig.h to fix a configuration | |
881 | + problem, don't. Edit the c-auto.h file created by configure, | |
882 | + instead. Even better, fix configure to give the right answer. */ | |
883 | + | |
884 | +/* Define to 1 if you have the `mkdtemp' function. */ | |
885 | +#undef HAVE_MKDTEMP | |
886 | + | |
887 | +/* Define to 1 if you have the `rmdir' function. */ | |
888 | +#undef HAVE_RMDIR | |
889 | ||
890 | -/* The number of bytes in a long. */ | |
891 | +/* Define to 1 if you have the `unlink' function. */ | |
892 | +#undef HAVE_UNLINK | |
893 | + | |
894 | +/* The size of a `long', as computed by sizeof. */ | |
895 | #undef SIZEOF_LONG | |
896 | + | |
897 | +/* Define to 1 if type `char' is unsigned and you are not using gcc. */ | |
898 | +#ifndef __CHAR_UNSIGNED__ | |
899 | +# undef __CHAR_UNSIGNED__ | |
900 | +#endif | |
901 | diff -up tetex-src-3.0/texk/dviljk/config.h.dviljktemp tetex-src-3.0/texk/dviljk/config.h | |
902 | --- tetex-src-3.0/texk/dviljk/config.h.dviljktemp 2002-01-03 17:40:25.000000000 +0100 | |
903 | +++ tetex-src-3.0/texk/dviljk/config.h 2007-11-13 14:53:45.000000000 +0100 | |
904 | @@ -216,12 +216,7 @@ typedef SCHAR_TYPE signed_char; | |
905 | #endif | |
906 | ||
907 | #ifndef KPATHSEA | |
908 | -extern bool findfile( | |
909 | -#if NeedFunctionPrototypes | |
910 | -char path[], char n[], long4 fontmag, char name[], | |
911 | - bool tfm, int level | |
912 | -#endif | |
913 | - ); | |
914 | +#error "Would need changed findfile, dviljk has changed allocation semantic of name member in tfontptr" | |
915 | #endif | |
916 | ||
917 | ||
918 | @@ -444,3 +439,24 @@ typedef FILE *FILEPTR; | |
919 | /* If we have neither, should fall back to fprintf with fixed args. */ | |
920 | #endif | |
921 | #endif | |
922 | + | |
923 | +/* If unlink and rmdir are not there, we don't delete the temporary files. */ | |
924 | +#ifndef HAVE_RMDIR | |
925 | +#define rmdir(dir) | |
926 | +#endif | |
927 | +#ifndef HAVE_UNLINK | |
928 | +#define unlink(file) | |
929 | +#endif | |
930 | + | |
931 | +/* If mkdtemp() does not exist, we have to use tmpnam(). */ | |
932 | +#ifndef HAVE_MKDTEMP | |
933 | +#define mkdtemp(dir) (tmpnam(dir) ? \ | |
934 | + ( mkdir(dir, 0700) == -1 ? NULL : dir ) : \ | |
935 | + ( errno = EINVAL, NULL ) ) | |
936 | +#endif | |
937 | + | |
938 | +#ifndef KPATHSEA | |
939 | +/* FIXME: Should provide a strdup function. But currently this tree is | |
940 | + only used in connection with kpathsea anyhow. */ | |
941 | +#error "Need xstrdup and xmalloc function, e.g. from kpathsea" | |
942 | +#endif |