1 /* Copyright (C) 1994, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
2
3 This software is provided AS-IS with no warranty, either express or
4 implied.
5
6 This software is distributed under license and may not be copied,
7 modified or distributed except as expressly authorized under the terms
8 of the license contained in the file LICENSE in this distribution.
9
10 For more information about licensing, please refer to
11 http://www.ghostscript.com/licensing/. For information on
12 commercial licensing, go to http://www.artifex.com/licensing/ or
13 contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14 San Rafael, CA 94903, U.S.A., +1(415)492-9861.
15 */
16
17 /* $Id: seexec.c,v 1.8 2002/09/02 22:09:15 ray Exp $ */
18 /* eexec filters */
19 #include "stdio_.h" /* includes std.h */
20 #include "strimpl.h"
21 #include "sfilter.h"
22 #include "gscrypt1.h"
23 #include "scanchar.h"
24
25 /* ------ eexecEncode ------ */
26
27 /* Encoding is much simpler than decoding, because we don't */
28 /* worry about initial characters or hex vs. binary (the client */
29 /* has to take care of these aspects). */
30
31 private_st_exE_state();
32
33 /* Process a buffer */
34 private int
s_exE_process(stream_state * st,stream_cursor_read * pr,stream_cursor_write * pw,bool last)35 s_exE_process(stream_state * st, stream_cursor_read * pr,
36 stream_cursor_write * pw, bool last)
37 {
38 stream_exE_state *const ss = (stream_exE_state *) st;
39 const byte *p = pr->ptr;
40 byte *q = pw->ptr;
41 uint rcount = pr->limit - p;
42 uint wcount = pw->limit - q;
43 uint count;
44 int status;
45
46 if (rcount <= wcount)
47 count = rcount, status = 0;
48 else
49 count = wcount, status = 1;
50 gs_type1_encrypt(q + 1, p + 1, count, (crypt_state *)&ss->cstate);
51 pr->ptr += count;
52 pw->ptr += count;
53 return status;
54 }
55
56 /* Stream template */
57 const stream_template s_exE_template = {
58 &st_exE_state, NULL, s_exE_process, 1, 2
59 };
60
61 /* ------ eexecDecode ------ */
62
63 private_st_exD_state();
64
65 /* Set defaults. */
66 private void
s_exD_set_defaults(stream_state * st)67 s_exD_set_defaults(stream_state * st)
68 {
69 stream_exD_state *const ss = (stream_exD_state *) st;
70
71 ss->binary = -1; /* unknown */
72 ss->lenIV = 4;
73 ss->record_left = max_long;
74 ss->hex_left = max_long;
75 /* Clear pointers for GC */
76 ss->pfb_state = 0;
77 }
78
79 /* Initialize the state for reading and decrypting. */
80 /* Decrypting streams are not positionable. */
81 private int
s_exD_init(stream_state * st)82 s_exD_init(stream_state * st)
83 {
84 stream_exD_state *const ss = (stream_exD_state *) st;
85
86 ss->odd = -1;
87 ss->skip = ss->lenIV;
88 return 0;
89 }
90
91 /* Process a buffer. */
92 private int
s_exD_process(stream_state * st,stream_cursor_read * pr,stream_cursor_write * pw,bool last)93 s_exD_process(stream_state * st, stream_cursor_read * pr,
94 stream_cursor_write * pw, bool last)
95 {
96 stream_exD_state *const ss = (stream_exD_state *) st;
97 const byte *p = pr->ptr;
98 byte *q = pw->ptr;
99 int skip = ss->skip;
100 int rcount = pr->limit - p;
101 int wcount = pw->limit - q;
102 int status = 0;
103 int count = (wcount < rcount ? (status = 1, wcount) : rcount);
104
105 if (ss->binary < 0) {
106 /*
107 * This is the very first time we're filling the buffer.
108 */
109 const byte *const decoder = scan_char_decoder;
110 int i;
111
112 if (ss->pfb_state == 0) {
113 /*
114 * Skip '\t', '\r', '\n', ' ' at the beginning of the input stream,
115 * because Adobe interpreters do this. Don't skip '\0' or '\f'.
116 */
117 for (; rcount; rcount--, p++) {
118 byte c = p[1];
119 if(c != '\t' && c != char_CR && c != char_EOL && c != ' ')
120 break;
121 }
122 pr->ptr = p;
123 count = min(wcount, rcount);
124 }
125
126 /*
127 * Determine whether this is ASCII or hex encoding.
128 * Adobe's documentation doesn't actually specify the test
129 * that eexec should use, but we believe the following
130 * gives correct answers even on certain non-conforming
131 * PostScript files encountered in practice:
132 */
133 if (rcount < 8 && !last)
134 return 0;
135
136 ss->binary = 0;
137 for (i = min(8, rcount); i > 0; i--)
138 if (!(decoder[p[i]] <= 0xf ||
139 decoder[p[i]] == ctype_space)
140 ) {
141 ss->binary = 1;
142 if (ss->pfb_state != 0) {
143 /* Stop at the end of the .PFB binary data. */
144 ss->record_left = ss->pfb_state->record_left;
145 }
146 break;
147 }
148 }
149 if (ss->binary) {
150 if (count > ss->record_left) {
151 count = ss->record_left;
152 status = 0;
153 }
154 /*
155 * We pause at the end of the .PFB binary data,
156 * in an attempt to keep from reading beyond the end of
157 * the encrypted data.
158 */
159 if ((ss->record_left -= count) == 0)
160 ss->record_left = max_long;
161 pr->ptr = p + count;
162 } else {
163 /*
164 * We only ignore leading whitespace, in an attempt to
165 * keep from reading beyond the end of the encrypted data;
166 * but some badly coded files require us to ignore % also.
167 */
168 stream_cursor_read r;
169 const byte *start;
170
171 hp: r = *pr;
172 start = r.ptr;
173 if (r.limit - r.ptr > ss->hex_left)
174 r.limit = r.ptr + ss->hex_left;
175 status = s_hex_process(&r, pw, &ss->odd,
176 hex_ignore_leading_whitespace);
177 pr->ptr = r.ptr;
178 ss->hex_left -= r.ptr - start;
179 /*
180 * Check for having finished a prematurely decoded hex section of
181 * a PFB file.
182 */
183 if (ss->hex_left == 0)
184 ss->binary = 1;
185 count = pw->ptr - q;
186 if (status < 0 && ss->odd < 0) {
187 if (count) {
188 --p;
189 status = 0; /* reprocess error next time */
190 } else if (*p == '%')
191 goto hp; /* ignore % */
192 }
193 p = q;
194 }
195 if (skip >= count && skip != 0) {
196 gs_type1_decrypt(q + 1, p + 1, count,
197 (crypt_state *) & ss->cstate);
198 ss->skip -= count;
199 count = 0;
200 status = 0;
201 } else {
202 gs_type1_decrypt(q + 1, p + 1, skip,
203 (crypt_state *) & ss->cstate);
204 count -= skip;
205 gs_type1_decrypt(q + 1, p + 1 + skip, count,
206 (crypt_state *) & ss->cstate);
207 ss->skip = 0;
208 }
209 pw->ptr = q + count;
210 return status;
211 }
212
213 /* Stream template */
214 /*
215 * The specification of eexec decoding requires that it never read more than
216 * 512 source bytes ahead. The only reliable way to ensure this is to
217 * limit the size of the output buffer to 256. We set it a little smaller
218 * so that it will stay under the limit even after adding min_in_size
219 * for a subsequent filter in a pipeline. Note that we have to specify
220 * a size of at least 128 so that filter_read won't round it up.
221 */
222 const stream_template s_exD_template = {
223 &st_exD_state, s_exD_init, s_exD_process, 8, 200,
224 NULL, s_exD_set_defaults
225 };
226