Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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
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
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
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
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
};