Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4680 right-hear 1
#include "fitz.h"
2
 
3
/* Pretend we have a filter that just copies data forever */
4
 
5
fz_stream *
6
fz_open_copy(fz_stream *chain)
7
{
8
	return fz_keep_stream(chain);
9
}
10
 
11
/* Null filter copies a specified amount of data */
12
 
13
struct null_filter
14
{
15
	fz_stream *chain;
16
	int remain;
17
};
18
 
19
static int
20
read_null(fz_stream *stm, unsigned char *buf, int len)
21
{
22
	struct null_filter *state = stm->state;
23
	int amount = MIN(len, state->remain);
24
	int n = fz_read(state->chain, buf, amount);
25
	if (n < 0)
26
		return fz_rethrow(n, "read error in null filter");
27
	state->remain -= n;
28
	return n;
29
}
30
 
31
static void
32
close_null(fz_stream *stm)
33
{
34
	struct null_filter *state = stm->state;
35
	fz_close(state->chain);
36
	fz_free(state);
37
}
38
 
39
fz_stream *
40
fz_open_null(fz_stream *chain, int len)
41
{
42
	struct null_filter *state;
43
 
44
	state = fz_malloc(sizeof(struct null_filter));
45
	state->chain = chain;
46
	state->remain = len;
47
 
48
	return fz_new_stream(state, read_null, close_null);
49
}
50
 
51
/* ASCII Hex Decode */
52
 
53
typedef struct fz_ahxd_s fz_ahxd;
54
 
55
struct fz_ahxd_s
56
{
57
	fz_stream *chain;
58
	int eod;
59
};
60
 
61
static inline int iswhite(int a)
62
{
63
	switch (a) {
64
	case '\n': case '\r': case '\t': case ' ':
65
	case '\0': case '\f': case '\b': case 0177:
66
		return 1;
67
	}
68
	return 0;
69
}
70
 
71
static inline int ishex(int a)
72
{
73
	return (a >= 'A' && a <= 'F') ||
74
		(a >= 'a' && a <= 'f') ||
75
		(a >= '0' && a <= '9');
76
}
77
 
78
static inline int unhex(int a)
79
{
80
	if (a >= 'A' && a <= 'F') return a - 'A' + 0xA;
81
	if (a >= 'a' && a <= 'f') return a - 'a' + 0xA;
82
	if (a >= '0' && a <= '9') return a - '0';
83
	return 0;
84
}
85
 
86
static int
87
read_ahxd(fz_stream *stm, unsigned char *buf, int len)
88
{
89
	fz_ahxd *state = stm->state;
90
	unsigned char *p = buf;
91
	unsigned char *ep = buf + len;
92
	int a, b, c, odd;
93
 
94
	odd = 0;
95
 
96
	while (p < ep)
97
	{
98
		if (state->eod)
99
			return p - buf;
100
 
101
		c = fz_read_byte(state->chain);
102
		if (c < 0)
103
			return p - buf;
104
 
105
		if (ishex(c))
106
		{
107
			if (!odd)
108
			{
109
				a = unhex(c);
110
				odd = 1;
111
			}
112
			else
113
			{
114
				b = unhex(c);
115
				*p++ = (a << 4) | b;
116
				odd = 0;
117
			}
118
		}
119
		else if (c == '>')
120
		{
121
			if (odd)
122
				*p++ = (a << 4);
123
			state->eod = 1;
124
		}
125
		else if (!iswhite(c))
126
		{
127
			return fz_throw("bad data in ahxd: '%c'", c);
128
		}
129
	}
130
 
131
	return p - buf;
132
}
133
 
134
static void
135
close_ahxd(fz_stream *stm)
136
{
137
	fz_ahxd *state = stm->state;
138
	fz_close(state->chain);
139
	fz_free(state);
140
}
141
 
142
fz_stream *
143
fz_open_ahxd(fz_stream *chain)
144
{
145
	fz_ahxd *state;
146
 
147
	state = fz_malloc(sizeof(fz_ahxd));
148
	state->chain = chain;
149
	state->eod = 0;
150
 
151
	return fz_new_stream(state, read_ahxd, close_ahxd);
152
}
153
 
154
/* ASCII 85 Decode */
155
 
156
typedef struct fz_a85d_s fz_a85d;
157
 
158
struct fz_a85d_s
159
{
160
	fz_stream *chain;
161
	unsigned char bp[4];
162
	unsigned char *rp, *wp;
163
	int eod;
164
};
165
 
166
static int
167
read_a85d(fz_stream *stm, unsigned char *buf, int len)
168
{
169
	fz_a85d *state = stm->state;
170
	unsigned char *p = buf;
171
	unsigned char *ep = buf + len;
172
	int count = 0;
173
	int word = 0;
174
	int c;
175
 
176
	while (state->rp < state->wp && p < ep)
177
		*p++ = *state->rp++;
178
 
179
	while (p < ep)
180
	{
181
		if (state->eod)
182
			return p - buf;
183
 
184
		c = fz_read_byte(state->chain);
185
		if (c < 0)
186
			return p - buf;
187
 
188
		if (c >= '!' && c <= 'u')
189
		{
190
			if (count == 4)
191
			{
192
				word = word * 85 + (c - '!');
193
 
194
				state->bp[0] = (word >> 24) & 0xff;
195
				state->bp[1] = (word >> 16) & 0xff;
196
				state->bp[2] = (word >> 8) & 0xff;
197
				state->bp[3] = (word) & 0xff;
198
				state->rp = state->bp;
199
				state->wp = state->bp + 4;
200
 
201
				word = 0;
202
				count = 0;
203
			}
204
			else
205
			{
206
				word = word * 85 + (c - '!');
207
				count ++;
208
			}
209
		}
210
 
211
		else if (c == 'z' && count == 0)
212
		{
213
			state->bp[0] = 0;
214
			state->bp[1] = 0;
215
			state->bp[2] = 0;
216
			state->bp[3] = 0;
217
			state->rp = state->bp;
218
			state->wp = state->bp + 4;
219
		}
220
 
221
		else if (c == '~')
222
		{
223
			c = fz_read_byte(state->chain);
224
			if (c != '>')
225
				fz_warn("bad eod marker in a85d");
226
 
227
			switch (count) {
228
			case 0:
229
				break;
230
			case 1:
231
				return fz_throw("partial final byte in a85d");
232
			case 2:
233
				word = word * (85 * 85 * 85) + 0xffffff;
234
				state->bp[0] = word >> 24;
235
				state->rp = state->bp;
236
				state->wp = state->bp + 1;
237
				break;
238
			case 3:
239
				word = word * (85 * 85) + 0xffff;
240
				state->bp[0] = word >> 24;
241
				state->bp[1] = word >> 16;
242
				state->rp = state->bp;
243
				state->wp = state->bp + 2;
244
				break;
245
			case 4:
246
				word = word * 85 + 0xff;
247
				state->bp[0] = word >> 24;
248
				state->bp[1] = word >> 16;
249
				state->bp[2] = word >> 8;
250
				state->rp = state->bp;
251
				state->wp = state->bp + 3;
252
				break;
253
			}
254
			state->eod = 1;
255
		}
256
 
257
		else if (!iswhite(c))
258
		{
259
			return fz_throw("bad data in a85d: '%c'", c);
260
		}
261
 
262
		while (state->rp < state->wp && p < ep)
263
			*p++ = *state->rp++;
264
	}
265
 
266
	return p - buf;
267
}
268
 
269
static void
270
close_a85d(fz_stream *stm)
271
{
272
	fz_a85d *state = stm->state;
273
	fz_close(state->chain);
274
	fz_free(state);
275
}
276
 
277
fz_stream *
278
fz_open_a85d(fz_stream *chain)
279
{
280
	fz_a85d *state;
281
 
282
	state = fz_malloc(sizeof(fz_a85d));
283
	state->chain = chain;
284
	state->rp = state->bp;
285
	state->wp = state->bp;
286
	state->eod = 0;
287
 
288
	return fz_new_stream(state, read_a85d, close_a85d);
289
}
290
 
291
/* Run Length Decode */
292
 
293
typedef struct fz_rld_s fz_rld;
294
 
295
struct fz_rld_s
296
{
297
	fz_stream *chain;
298
	int run, n, c;
299
};
300
 
301
static int
302
read_rld(fz_stream *stm, unsigned char *buf, int len)
303
{
304
	fz_rld *state = stm->state;
305
	unsigned char *p = buf;
306
	unsigned char *ep = buf + len;
307
 
308
	while (p < ep)
309
	{
310
		if (state->run == 128)
311
			return p - buf;
312
 
313
		if (state->n == 0)
314
		{
315
			state->run = fz_read_byte(state->chain);
316
			if (state->run < 0)
317
				state->run = 128;
318
			if (state->run < 128)
319
				state->n = state->run + 1;
320
			if (state->run > 128)
321
			{
322
				state->n = 257 - state->run;
323
				state->c = fz_read_byte(state->chain);
324
				if (state->c < 0)
325
					return fz_throw("premature end of data in run length decode");
326
			}
327
		}
328
 
329
		if (state->run < 128)
330
		{
331
			while (p < ep && state->n)
332
			{
333
				int c = fz_read_byte(state->chain);
334
				if (c < 0)
335
					return fz_throw("premature end of data in run length decode");
336
				*p++ = c;
337
				state->n--;
338
			}
339
		}
340
 
341
		if (state->run > 128)
342
		{
343
			while (p < ep && state->n)
344
			{
345
				*p++ = state->c;
346
				state->n--;
347
			}
348
		}
349
	}
350
 
351
	return p - buf;
352
}
353
 
354
static void
355
close_rld(fz_stream *stm)
356
{
357
	fz_rld *state = stm->state;
358
	fz_close(state->chain);
359
	fz_free(state);
360
}
361
 
362
fz_stream *
363
fz_open_rld(fz_stream *chain)
364
{
365
	fz_rld *state;
366
 
367
	state = fz_malloc(sizeof(fz_rld));
368
	state->chain = chain;
369
	state->run = 0;
370
	state->n = 0;
371
	state->c = 0;
372
 
373
	return fz_new_stream(state, read_rld, close_rld);
374
}
375
 
376
/* RC4 Filter */
377
 
378
typedef struct fz_arc4c_s fz_arc4c;
379
 
380
struct fz_arc4c_s
381
{
382
	fz_stream *chain;
383
	fz_arc4 arc4;
384
};
385
 
386
static int
387
read_arc4(fz_stream *stm, unsigned char *buf, int len)
388
{
389
	fz_arc4c *state = stm->state;
390
	int n;
391
 
392
	n = fz_read(state->chain, buf, len);
393
	if (n < 0)
394
		return fz_rethrow(n, "read error in arc4 filter");
395
 
396
	fz_arc4_encrypt(&state->arc4, buf, buf, n);
397
 
398
	return n;
399
}
400
 
401
static void
402
close_arc4(fz_stream *stm)
403
{
404
	fz_arc4c *state = stm->state;
405
	fz_close(state->chain);
406
	fz_free(state);
407
}
408
 
409
fz_stream *
410
fz_open_arc4(fz_stream *chain, unsigned char *key, unsigned keylen)
411
{
412
	fz_arc4c *state;
413
 
414
	state = fz_malloc(sizeof(fz_arc4c));
415
	state->chain = chain;
416
	fz_arc4_init(&state->arc4, key, keylen);
417
 
418
	return fz_new_stream(state, read_arc4, close_arc4);
419
}
420
 
421
/* AES Filter */
422
 
423
typedef struct fz_aesd_s fz_aesd;
424
 
425
struct fz_aesd_s
426
{
427
	fz_stream *chain;
428
	fz_aes aes;
429
	unsigned char iv[16];
430
	int ivcount;
431
	unsigned char bp[16];
432
	unsigned char *rp, *wp;
433
};
434
 
435
static int
436
read_aesd(fz_stream *stm, unsigned char *buf, int len)
437
{
438
	fz_aesd *state = stm->state;
439
	unsigned char *p = buf;
440
	unsigned char *ep = buf + len;
441
 
442
	while (state->ivcount < 16)
443
	{
444
		int c = fz_read_byte(state->chain);
445
		if (c < 0)
446
			return fz_throw("premature end in aes filter");
447
		state->iv[state->ivcount++] = c;
448
	}
449
 
450
	while (state->rp < state->wp && p < ep)
451
		*p++ = *state->rp++;
452
 
453
	while (p < ep)
454
	{
455
		int n = fz_read(state->chain, state->bp, 16);
456
		if (n < 0)
457
			return fz_rethrow(n, "read error in aes filter");
458
		else if (n == 0)
459
			return p - buf;
460
		else if (n < 16)
461
			return fz_throw("partial block in aes filter");
462
 
463
		aes_crypt_cbc(&state->aes, AES_DECRYPT, 16, state->iv, state->bp, state->bp);
464
		state->rp = state->bp;
465
		state->wp = state->bp + 16;
466
 
467
		/* strip padding at end of file */
468
		if (fz_is_eof(state->chain))
469
		{
470
			int pad = state->bp[15];
471
			if (pad < 1 || pad > 16)
472
				return fz_throw("aes padding out of range: %d", pad);
473
			state->wp -= pad;
474
		}
475
 
476
		while (state->rp < state->wp && p < ep)
477
			*p++ = *state->rp++;
478
	}
479
 
480
	return p - buf;
481
}
482
 
483
static void
484
close_aesd(fz_stream *stm)
485
{
486
	fz_aesd *state = stm->state;
487
	fz_close(state->chain);
488
	fz_free(state);
489
}
490
 
491
fz_stream *
492
fz_open_aesd(fz_stream *chain, unsigned char *key, unsigned keylen)
493
{
494
	fz_aesd *state;
495
 
496
	state = fz_malloc(sizeof(fz_aesd));
497
	state->chain = chain;
498
	aes_setkey_dec(&state->aes, key, keylen * 8);
499
	state->ivcount = 0;
500
	state->rp = state->bp;
501
	state->wp = state->bp;
502
 
503
	return fz_new_stream(state, read_aesd, close_aesd);
504
}