Coverage Report

Created: 2022-10-31 07:00

/src/ghostpdl/pdf/pdf_file.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2018-2022 Artifex Software, Inc.
2
   All Rights Reserved.
3
4
   This software is provided AS-IS with no warranty, either express or
5
   implied.
6
7
   This software is distributed under license and may not be copied,
8
   modified or distributed except as expressly authorized under the terms
9
   of the license contained in the file LICENSE in this distribution.
10
11
   Refer to licensing information at http://www.artifex.com or contact
12
   Artifex Software, Inc.,  1305 Grant Avenue - Suite 200, Novato,
13
   CA 94945, U.S.A., +1(415)492-9861, for further information.
14
*/
15
16
#include "ghostpdf.h"
17
#include "pdf_types.h"
18
#include "pdf_stack.h"
19
#include "pdf_dict.h"
20
#include "pdf_file.h"
21
#include "pdf_int.h"
22
#include "pdf_array.h"
23
#include "pdf_misc.h"
24
#include "pdf_sec.h"
25
#include "stream.h"
26
#include "strimpl.h"
27
#include "strmio.h"
28
#include "gpmisc.h"
29
#include "simscale.h"   /* SIMScaleDecode */
30
#include "szlibx.h"     /* Flate */
31
#include "spngpx.h"     /* PNG Predictor */
32
#include "spdiffx.h"    /* Horizontal differencing predictor */
33
#include "slzwx.h"      /* LZW ZLib */
34
#include "sstring.h"    /* ASCIIHexDecode */
35
#include "sa85d.h"      /* ASCII85Decode */
36
#include "scfx.h"       /* CCITTFaxDecode */
37
#include "srlx.h"       /* RunLengthDecode */
38
#include "jpeglib_.h"
39
#include "sdct.h"       /* DCTDecode */
40
#include "sjpeg.h"
41
#include "sfilter.h"    /* SubFileDecode and PFBDecode */
42
#include "sarc4.h"      /* Arc4Decode */
43
#include "saes.h"       /* AESDecode */
44
#include "ssha2.h"      /* SHA256Encode */
45
#include "gxdevsop.h"       /* For special ops */
46
47
#ifdef USE_LDF_JB2
48
#include "sjbig2_luratech.h"
49
#else
50
#include "sjbig2.h"
51
#endif
52
#if defined(USE_LWF_JP2)
53
#  include "sjpx_luratech.h"
54
#elif defined(USE_OPENJPEG_JP2)
55
#  include "sjpx_openjpeg.h"
56
#else
57
#  include "sjpx.h"
58
#endif
59
60
extern const uint file_default_buffer_size;
61
62
static void pdfi_close_filter_chain(pdf_context *ctx, stream *s, stream *target);
63
64
/* Utility routine to create a pdf_c_stream object */
65
static int pdfi_alloc_stream(pdf_context *ctx, stream *source, stream *original, pdf_c_stream **new_stream)
66
6.06M
{
67
6.06M
    *new_stream = NULL;
68
6.06M
    *new_stream = (pdf_c_stream *)gs_alloc_bytes(ctx->memory, sizeof(pdf_c_stream), "pdfi_alloc_stream");
69
6.06M
    if (*new_stream == NULL)
70
0
        return_error(gs_error_VMerror);
71
6.06M
    memset(*new_stream, 0x00, sizeof(pdf_c_stream));
72
6.06M
    (*new_stream)->eof = false;
73
6.06M
    ((pdf_c_stream *)(*new_stream))->s = source;
74
6.06M
    ((pdf_c_stream *)(*new_stream))->original = original;
75
6.06M
    return 0;
76
6.06M
}
77
78
/***********************************************************************************/
79
/* Decompression filters.                                                          */
80
81
static int
82
pdfi_filter_report_error(stream_state * st, const char *str)
83
1.40k
{
84
1.40k
    if_debug1m('s', st->memory, "[s]stream error: %s\n", str);
85
1.40k
    strncpy(st->error_string, str, STREAM_MAX_ERROR_STRING);
86
    /* Ensure null termination. */
87
1.40k
    st->error_string[STREAM_MAX_ERROR_STRING] = 0;
88
1.40k
    return 0;
89
1.40k
}
90
91
/* Open a file stream for a filter. */
92
static int
93
pdfi_filter_open(uint buffer_size,
94
            const stream_procs * procs, const stream_template * templat,
95
            const stream_state * st, gs_memory_t *mem, stream **new_stream)
96
5.84M
{
97
5.84M
    stream *s;
98
5.84M
    uint ssize = gs_struct_type_size(templat->stype);
99
5.84M
    stream_state *sst = NULL;
100
5.84M
    int code;
101
102
5.84M
    if (templat->stype != &st_stream_state) {
103
5.84M
        sst = s_alloc_state(mem, templat->stype, "pdfi_filter_open(stream_state)");
104
5.84M
        if (sst == NULL)
105
0
            return_error(gs_error_VMerror);
106
5.84M
    }
107
5.84M
    if (buffer_size < 128)
108
13.5k
        buffer_size = file_default_buffer_size;
109
110
5.84M
    code = file_open_stream((char *)0, 0, "r", buffer_size, &s,
111
5.84M
                                (gx_io_device *)0, (iodev_proc_fopen_t)0, mem);
112
5.84M
    if (code < 0) {
113
0
        gs_free_object(mem, sst, "pdfi_filter_open(stream_state)");
114
0
        return code;
115
0
    }
116
5.84M
    s_std_init(s, s->cbuf, s->bsize, procs, s_mode_read);
117
5.84M
    s->procs.process = templat->process;
118
5.84M
    s->save_close = s->procs.close;
119
5.84M
    s->procs.close = file_close_file;
120
5.84M
    s->close_at_eod = 0;
121
5.84M
    if (sst == NULL) {
122
        /* This stream doesn't have any state of its own. */
123
        /* Hack: use the stream itself as the state. */
124
0
        sst = (stream_state *) s;
125
5.84M
    } else if (st != NULL)         /* might not have client parameters */
126
5.84M
        memcpy(sst, st, ssize);
127
5.84M
    s->state = sst;
128
5.84M
    s_init_state(sst, templat, mem);
129
5.84M
    sst->report_error = pdfi_filter_report_error;
130
131
5.84M
    if (templat->init != NULL) {
132
5.84M
        code = (*templat->init)(sst);
133
5.84M
        if (code < 0) {
134
0
            gs_free_object(mem, sst, "filter_open(stream_state)");
135
0
            gs_free_object(mem, s->cbuf, "filter_open(buffer)");
136
0
            gs_free_object(mem, s, "filter_open(stream)");
137
0
            return code;
138
0
        }
139
5.84M
    }
140
5.84M
    *new_stream = s;
141
5.84M
    return 0;
142
5.84M
}
143
144
static int pdfi_Predictor_filter(pdf_context *ctx, pdf_dict *d, stream *source, stream **new_stream)
145
14.0k
{
146
14.0k
    int code;
147
14.0k
    int64_t Predictor, Colors, BPC, Columns;
148
14.0k
    uint min_size;
149
14.0k
    stream_PNGP_state pps;
150
14.0k
    stream_PDiff_state ppds;
151
    /* NOTE: 'max_min_left=1' is a horribly named definition from stream.h */
152
153
14.0k
    code = pdfi_dict_get_int_def(ctx, d, "Predictor", &Predictor, 1);
154
14.0k
    if (code < 0)
155
0
        return code;
156
157
    /* Predictor values 0,1 are identity (use the existing stream).
158
     * The other values need to be cascaded.
159
     */
160
14.0k
    switch(Predictor) {
161
0
        case 0:
162
0
            Predictor = 1;
163
0
            break;
164
244
        case 1:
165
244
            break;
166
2
        case 2:
167
2
        case 10:
168
3
        case 11:
169
5.97k
        case 12:
170
5.97k
        case 13:
171
5.97k
        case 14:
172
13.7k
        case 15:
173
            /* grab values common to both kinds of predictors */
174
13.7k
            min_size = s_zlibD_template.min_out_size + max_min_left;
175
13.7k
            code = pdfi_dict_get_int_def(ctx, d, "Colors", &Colors, 1);
176
13.7k
            if (code < 0)
177
2
                return code;
178
13.7k
            if (Colors < 1 || Colors > s_PNG_max_Colors)
179
224
                return_error(gs_error_rangecheck);
180
181
13.5k
            code = pdfi_dict_get_int_def(ctx, d, "BitsPerComponent", &BPC, 8);
182
13.5k
            if (code < 0)
183
0
                return code;
184
            /* tests for 1-16, powers of 2 */
185
13.5k
            if (BPC < 1 || BPC > 16 || (BPC & (BPC - 1)) != 0)
186
7
                return_error(gs_error_rangecheck);
187
188
13.5k
            code = pdfi_dict_get_int_def(ctx, d, "Columns", &Columns, 1);
189
13.5k
            if (code < 0)
190
0
                return code;
191
13.5k
            if (Columns < 1)
192
2
                return_error(gs_error_rangecheck);
193
13.5k
            break;
194
13.5k
        default:
195
50
            return_error(gs_error_rangecheck);
196
14.0k
    }
197
198
13.7k
    switch(Predictor) {
199
244
        case 1:
200
244
            *new_stream = source;
201
244
            break;
202
2
        case 2:
203
            /* zpd_setup, componentwise horizontal differencing */
204
2
            ppds.Colors = (int)Colors;
205
2
            ppds.BitsPerComponent = (int)BPC;
206
2
            ppds.Columns = (int)Columns;
207
2
            code = pdfi_filter_open(min_size, &s_filter_read_procs,
208
2
                             (const stream_template *)&s_PDiffD_template,
209
2
                             (const stream_state *)&ppds, ctx->memory->non_gc_memory, new_stream);
210
2
            if (code < 0)
211
0
                return code;
212
213
2
            (*new_stream)->strm = source;
214
2
            break;
215
13.5k
        default:
216
            /* zpp_setup, PNG predictor */
217
13.5k
            pps.Colors = (int)Colors;
218
13.5k
            pps.BitsPerComponent = (int)BPC;
219
13.5k
            pps.Columns = (uint)Columns;
220
13.5k
            pps.Predictor = Predictor;
221
13.5k
            code = pdfi_filter_open(min_size, &s_filter_read_procs,
222
13.5k
                             (const stream_template *)&s_PNGPD_template,
223
13.5k
                             (const stream_state *)&pps, ctx->memory->non_gc_memory, new_stream);
224
13.5k
            if (code < 0)
225
0
                return code;
226
227
13.5k
            (*new_stream)->strm = source;
228
13.5k
            break;
229
13.7k
    }
230
13.7k
    return 0;
231
13.7k
}
232
233
int pdfi_apply_Arc4_filter(pdf_context *ctx, pdf_string *Key, pdf_c_stream *source, pdf_c_stream **new_stream)
234
2.97k
{
235
2.97k
    int code = 0;
236
2.97k
    stream_arcfour_state state;
237
2.97k
    stream *new_s;
238
2.97k
    int min_size = 2048;
239
240
2.97k
    s_arcfour_set_key(&state, (const unsigned char *)Key->data, Key->length); /* lgtm [cpp/weak-cryptographic-algorithm] */
241
242
2.97k
    code = pdfi_filter_open(min_size, &s_filter_read_procs, (const stream_template *)&s_arcfour_template, (const stream_state *)&state, ctx->memory->non_gc_memory, &new_s);
243
2.97k
    if (code < 0)
244
0
        return code;
245
246
2.97k
    code = pdfi_alloc_stream(ctx, new_s, source->s, new_stream);
247
2.97k
    new_s->strm = source->s;
248
2.97k
    return code;
249
2.97k
}
250
251
int pdfi_apply_AES_filter(pdf_context *ctx, pdf_string *Key, bool use_padding, pdf_c_stream *source, pdf_c_stream **new_stream)
252
5.25k
{
253
5.25k
    stream_aes_state state;
254
5.25k
    uint min_size = 2048;
255
5.25k
    int code = 0;
256
5.25k
    stream *new_s;
257
258
5.25k
    s_aes_set_key(&state, Key->data, Key->length);
259
5.25k
    s_aes_set_padding(&state, use_padding);
260
261
5.25k
    code = pdfi_filter_open(min_size, &s_filter_read_procs, (const stream_template *)&s_aes_template, (const stream_state *)&state, ctx->memory->non_gc_memory, &new_s);
262
263
5.25k
    if (code < 0)
264
0
        return code;
265
266
5.25k
    code = pdfi_alloc_stream(ctx, new_s, source->s, new_stream);
267
5.25k
    new_s->strm = source->s;
268
5.25k
    return code;
269
5.25k
}
270
271
#ifdef UNUSED_FILTER
272
int pdfi_apply_SHA256_filter(pdf_context *ctx, pdf_c_stream *source, pdf_c_stream **new_stream)
273
{
274
    stream_SHA256E_state state;
275
    uint min_size = 2048;
276
    int code = 0;
277
    stream *new_s;
278
279
    pSHA256_Init(&state.sha256);
280
    code = pdfi_filter_open(min_size, &s_filter_read_procs, (const stream_template *)&s_SHA256E_template, (const stream_state *)&state, ctx->memory->non_gc_memory, &new_s);
281
282
    if (code < 0)
283
        return code;
284
285
    code = pdfi_alloc_stream(ctx, new_s, source->s, new_stream);
286
    new_s->strm = source->s;
287
    return code;
288
}
289
#endif
290
291
int pdfi_apply_imscale_filter(pdf_context *ctx, pdf_string *Key, int width, int height, pdf_c_stream *source, pdf_c_stream **new_stream)
292
0
{
293
0
    int code = 0;
294
0
    stream_imscale_state state;
295
0
    stream *new_s;
296
297
0
    state.params.spp_decode = 1;
298
0
    state.params.spp_interp = 1;
299
0
    state.params.BitsPerComponentIn = 1;
300
0
    state.params.MaxValueIn = 1;
301
0
    state.params.WidthIn = width;
302
0
    state.params.HeightIn = height;
303
0
    state.params.BitsPerComponentOut = 1;
304
0
    state.params.MaxValueOut = 1;
305
0
    state.params.WidthOut = width << 2;
306
0
    state.params.HeightOut = height << 2;
307
308
0
    code = pdfi_filter_open(2048, &s_filter_read_procs, (const stream_template *)&s_imscale_template, (const stream_state *)&state, ctx->memory->non_gc_memory, &new_s);
309
310
0
    if (code < 0)
311
0
        return code;
312
313
0
    code = pdfi_alloc_stream(ctx, new_s, source->s, new_stream);
314
0
    new_s->strm = source->s;
315
0
    return code;
316
0
}
317
318
static int pdfi_Flate_filter(pdf_context *ctx, pdf_dict *d, stream *source, stream **new_stream)
319
2.17M
{
320
2.17M
    stream_zlib_state zls;
321
2.17M
    uint min_size = 2048;
322
2.17M
    int code;
323
2.17M
    stream *Flate_source = NULL;
324
325
2.17M
    memset(&zls, 0, sizeof(zls));
326
327
    /* s_zlibD_template defined in base/szlibd.c */
328
2.17M
    (*s_zlibD_template.set_defaults)((stream_state *)&zls);
329
330
2.17M
    code = pdfi_filter_open(min_size, &s_filter_read_procs, (const stream_template *)&s_zlibD_template, (const stream_state *)&zls, ctx->memory->non_gc_memory, new_stream);
331
2.17M
    if (code < 0)
332
0
        return code;
333
334
2.17M
    (*new_stream)->strm = source;
335
2.17M
    source = *new_stream;
336
337
2.17M
    if (d && pdfi_type_of(d) == PDF_DICT) {
338
14.0k
        Flate_source = (*new_stream)->strm;
339
14.0k
        code = pdfi_Predictor_filter(ctx, d, source, new_stream);
340
14.0k
        if (code < 0)
341
285
            pdfi_close_filter_chain(ctx, source, Flate_source);
342
14.0k
    }
343
2.17M
    return code;
344
2.17M
}
345
346
static int
347
pdfi_JBIG2Decode_filter(pdf_context *ctx, pdf_dict *dict, pdf_dict *decode,
348
                        stream *source, stream **new_stream)
349
64
{
350
64
    stream_jbig2decode_state state;
351
64
    uint min_size = s_jbig2decode_template.min_out_size;
352
64
    int code;
353
64
    pdf_stream *Globals = NULL;
354
64
    byte *buf = NULL;
355
64
    int64_t buflen = 0;
356
64
    void *globalctx;
357
358
64
    s_jbig2decode_set_global_data((stream_state*)&state, NULL, NULL);
359
360
64
    if (decode) {
361
0
        code = pdfi_dict_knownget_type(ctx, decode, "JBIG2Globals", PDF_STREAM,
362
0
                                       (pdf_obj **)&Globals);
363
0
        if (code < 0) {
364
0
            goto cleanupExit;
365
0
        }
366
367
        /* read in the globals from stream */
368
0
        if (code > 0) {
369
0
            code = pdfi_stream_to_buffer(ctx, Globals, &buf, &buflen);
370
0
            if (code == 0) {
371
0
                code = s_jbig2decode_make_global_data(ctx->memory->non_gc_memory,
372
0
                                                      buf, buflen, &globalctx);
373
0
                if (code < 0)
374
0
                    goto cleanupExit;
375
376
0
                s_jbig2decode_set_global_data((stream_state*)&state, NULL, globalctx);
377
0
            }
378
0
        }
379
0
    }
380
381
64
    code = pdfi_filter_open(min_size, &s_filter_read_procs,
382
64
                            (const stream_template *)&s_jbig2decode_template,
383
64
                            (const stream_state *)&state, ctx->memory->non_gc_memory, new_stream);
384
64
    if (code < 0)
385
0
        goto cleanupExit;
386
387
64
    (*new_stream)->strm = source;
388
64
    code = 0;
389
390
64
 cleanupExit:
391
64
    gs_free_object(ctx->memory, buf, "pdfi_JBIG2Decode_filter (Globals buf)");
392
64
    pdfi_countdown(Globals);
393
64
    return code;
394
64
}
395
396
static int pdfi_LZW_filter(pdf_context *ctx, pdf_dict *d, stream *source, stream **new_stream)
397
26
{
398
26
    stream_LZW_state lzs;
399
26
    uint min_size = 2048;
400
26
    int code;
401
26
    int64_t i;
402
403
    /* s_zlibD_template defined in base/szlibd.c */
404
26
    s_LZW_set_defaults_inline(&lzs);
405
406
26
    if (d && pdfi_type_of(d) == PDF_DICT) {
407
0
        code = pdfi_dict_get_int(ctx, d, "EarlyChange", &i);
408
0
        if (code < 0 && code != gs_error_undefined)
409
0
            return code;
410
0
        if (code == 0) {
411
0
            if (i == 0)
412
0
                lzs.EarlyChange = false;
413
0
            else
414
0
                lzs.EarlyChange = true;
415
0
        }
416
0
    }
417
418
26
    code = pdfi_filter_open(min_size, &s_filter_read_procs, (const stream_template *)&s_LZWD_template, (const stream_state *)&lzs, ctx->memory->non_gc_memory, new_stream);
419
26
    if (code < 0)
420
0
        return code;
421
26
    (*new_stream)->strm = source;
422
26
    source = *new_stream;
423
424
26
    if (d && pdfi_type_of(d) == PDF_DICT)
425
0
        pdfi_Predictor_filter(ctx, d, source, new_stream);
426
26
    return 0;
427
26
}
428
429
static int PS_JPXD_PassThrough(void *d, byte *Buffer, int Size)
430
24.0k
{
431
24.0k
    gx_device *dev = (gx_device *)d;
432
433
24.0k
    if (Buffer == NULL) {
434
520
        if (Size == 0)
435
260
            dev_proc(dev, dev_spec_op)(dev, gxdso_JPX_passthrough_end, NULL, 0);
436
260
        else
437
260
            dev_proc(dev, dev_spec_op)(dev, gxdso_JPX_passthrough_begin, NULL, 0);
438
23.5k
    } else {
439
23.5k
        dev_proc(dev, dev_spec_op)(dev, gxdso_JPX_passthrough_data, Buffer, Size);
440
23.5k
    }
441
24.0k
    return 0;
442
24.0k
}
443
444
/*
445
 * dict -- the dict that contained the decoder (i.e. the image dict)
446
 * decode -- the decoder dict
447
 */
448
static int
449
pdfi_JPX_filter(pdf_context *ctx, pdf_dict *dict, pdf_dict *decode,
450
                stream *source, stream **new_stream)
451
2.44k
{
452
2.44k
    stream_jpxd_state state;
453
2.44k
    uint min_size = s_jpxd_template.min_out_size;
454
2.44k
    int code;
455
2.44k
    pdf_obj *csobj = NULL;
456
2.44k
    pdf_name *csname = NULL;
457
2.44k
    bool alpha;
458
2.44k
    gx_device *dev = gs_currentdevice(ctx->pgs);
459
460
2.44k
    state.memory = ctx->memory->non_gc_memory;
461
2.44k
    if (s_jpxd_template.set_defaults)
462
2.44k
      (*s_jpxd_template.set_defaults)((stream_state *)&state);
463
464
    /* Pull some extra params out of the image dict */
465
2.44k
    if (dict) {
466
        /* This Alpha is a thing that gs code uses to tell that we
467
         * are doing an SMask.  It's a bit of a hack, but
468
         * I guess we can do the same.
469
         */
470
2.44k
        code = pdfi_dict_get_bool(ctx, dict, "Alpha", &alpha);
471
2.44k
        if (code == 0)
472
0
            state.alpha = alpha;
473
2.44k
    }
474
2.44k
    if (dict && pdfi_dict_get(ctx, dict, "ColorSpace", &csobj) == 0) {
475
        /* parse the value */
476
1.20k
        switch (pdfi_type_of(csobj)) {
477
0
        case PDF_ARRAY:
478
            /* assume it's the first array element */
479
0
            code = pdfi_array_get(ctx, (pdf_array *)csobj, (uint64_t)0, (pdf_obj **)&csname);
480
0
            if (code < 0) {
481
0
                pdfi_countdown(csobj);
482
0
                return code;
483
0
            }
484
0
            break;
485
1.20k
        case PDF_NAME:
486
            /* use the name directly */
487
1.20k
            csname = (pdf_name *)csobj;
488
1.20k
            csobj = NULL; /* To keep ref counting straight */
489
1.20k
            break;
490
0
        default:
491
0
            dmprintf(ctx->memory, "warning: JPX ColorSpace value is an unhandled type!\n");
492
0
            break;
493
1.20k
        }
494
1.20k
        if (csname != NULL && pdfi_type_of(csname) == PDF_NAME) {
495
            /* request raw index values if the colorspace is /Indexed */
496
1.20k
            if (pdfi_name_is(csname, "Indexed"))
497
0
                state.colorspace = gs_jpx_cs_indexed;
498
            /* tell the filter what output we want for other spaces */
499
1.20k
            else if (pdfi_name_is(csname, "DeviceGray"))
500
501
                state.colorspace = gs_jpx_cs_gray;
501
702
            else if (pdfi_name_is(csname, "DeviceRGB"))
502
702
                state.colorspace = gs_jpx_cs_rgb;
503
0
            else if (pdfi_name_is(csname, "DeviceCMYK"))
504
0
                state.colorspace = gs_jpx_cs_cmyk;
505
0
            else if (pdfi_name_is(csname, "ICCBased")) {
506
                /* TODO: I don't think this even happens without PS wrapper code? */
507
#if 0
508
                /* The second array element should be the profile's
509
                   stream dict */
510
                ref *csdict = csobj->value.refs + 1;
511
                ref *nref;
512
                ref altname;
513
                if (r_is_array(csobj) && (r_size(csobj) > 1) &&
514
                    r_has_type(csdict, t_dictionary)) {
515
                    check_dict_read(*csdict);
516
                    /* try to look up the alternate space */
517
                    if (dict_find_string(csdict, "Alternate", &nref) > 0) {
518
                        name_string_ref(imemory, csname, &altname);
519
                        if (pdfi_name_is(&altname, "DeviceGray"))
520
                            state.colorspace = gs_jpx_cs_gray;
521
                        else if (pdfi_name_is(&altname, "DeviceRGB"))
522
                            state.colorspace = gs_jpx_cs_rgb;
523
                        else if (pdfi_name_is(&altname, "DeviceCMYK"))
524
                            state.colorspace = gs_jpx_cs_cmyk;
525
                    }
526
                    /* else guess based on the number of components */
527
                    if (state.colorspace == gs_jpx_cs_unset &&
528
                        dict_find_string(csdict, "N", &nref) > 0) {
529
                        if_debug1m('w', imemory, "[w] JPX image has an external %"PRIpsint
530
                                   " channel colorspace\n", nref->value.intval);
531
                        switch (nref->value.intval) {
532
                        case 1: state.colorspace = gs_jpx_cs_gray;
533
                            break;
534
                        case 3: state.colorspace = gs_jpx_cs_rgb;
535
                            break;
536
                        case 4: state.colorspace = gs_jpx_cs_cmyk;
537
                            break;
538
                        }
539
                    }
540
                }
541
#endif
542
0
            }
543
1.20k
        }
544
1.20k
    }
545
546
2.44k
    if (csobj)
547
0
        pdfi_countdown(csobj);
548
2.44k
    if (csname)
549
1.20k
        pdfi_countdown(csname);
550
551
552
2.44k
    if (dev_proc(dev, dev_spec_op)(dev, gxdso_JPX_passthrough_query, NULL, 0) > 0) {
553
266
        state.StartedPassThrough = 0;
554
266
        state.PassThrough = 1;
555
266
        state.PassThroughfn = (PS_JPXD_PassThrough);
556
266
        state.device = (void *)dev;
557
266
    }
558
2.17k
    else {
559
2.17k
        state.PassThrough = 0;
560
2.17k
        state.device = (void *)NULL;
561
2.17k
    }
562
563
2.44k
    code = pdfi_filter_open(min_size, &s_filter_read_procs, (const stream_template *)&s_jpxd_template,
564
2.44k
                            (const stream_state *)&state, ctx->memory->non_gc_memory, new_stream);
565
2.44k
    if (code < 0)
566
0
        return code;
567
2.44k
    (*new_stream)->strm = source;
568
2.44k
    source = *new_stream;
569
570
2.44k
    return 0;
571
2.44k
}
572
573
private_st_jpeg_decompress_data();
574
575
static int PDF_DCTD_PassThrough(void *d, byte *Buffer, int Size)
576
142k
{
577
142k
    gx_device *dev = (gx_device *)d;
578
579
142k
    if (Buffer == NULL) {
580
3.33k
        if (Size == 0)
581
1.67k
            dev_proc(dev, dev_spec_op)(dev, gxdso_JPEG_passthrough_end, NULL, 0);
582
1.66k
        else
583
1.66k
            dev_proc(dev, dev_spec_op)(dev, gxdso_JPEG_passthrough_begin, NULL, 0);
584
139k
    } else {
585
139k
        dev_proc(dev, dev_spec_op)(dev, gxdso_JPEG_passthrough_data, Buffer, Size);
586
139k
    }
587
142k
    return 0;
588
142k
}
589
590
static int pdfi_DCT_filter(pdf_context *ctx, pdf_dict *stream_dict, pdf_dict *decode,
591
                           stream *source, stream **new_stream)
592
6.44k
{
593
6.44k
    stream_DCT_state dcts;
594
6.44k
    uint min_size = s_DCTD_template.min_out_size;
595
6.44k
    int code;
596
6.44k
    int64_t i;
597
6.44k
    jpeg_decompress_data *jddp;
598
6.44k
    gx_device *dev = gs_currentdevice_inline(ctx->pgs);
599
6.44k
    double Height = 0;
600
601
6.44k
    dcts.memory = ctx->memory;
602
    /* First allocate space for IJG parameters. */
603
6.44k
    jddp = gs_alloc_struct_immovable(ctx->memory, jpeg_decompress_data,
604
6.44k
      &st_jpeg_decompress_data, "pdfi_DCT");
605
6.44k
    if (jddp == 0)
606
0
        return_error(gs_error_VMerror);
607
6.44k
    if (s_DCTD_template.set_defaults)
608
6.44k
        (*s_DCTD_template.set_defaults) ((stream_state *) & dcts);
609
610
6.44k
    dcts.data.decompress = jddp;
611
6.44k
    jddp->memory = dcts.jpeg_memory = ctx->memory;  /* set now for allocation */
612
6.44k
    jddp->scanline_buffer = NULL;                 /* set this early for safe error exit */
613
6.44k
    dcts.report_error = pdfi_filter_report_error;     /* in case create fails */
614
6.44k
    if ((code = gs_jpeg_create_decompress(&dcts)) < 0) {
615
1
        gs_jpeg_destroy(&dcts);
616
1
        gs_free_object(ctx->memory, jddp, "zDCTD fail");
617
1
        return code;
618
1
    }
619
620
6.44k
    if (decode && pdfi_type_of(decode) == PDF_DICT) {
621
        /* TODO: Why is this here?  'i' never gets used? */
622
199
        code = pdfi_dict_get_int(ctx, decode, "ColorTransform", &i);
623
199
        if (code < 0 && code != gs_error_undefined)
624
0
            return code;
625
199
    }
626
627
6.44k
    if (dev_proc(dev, dev_spec_op)(dev, gxdso_JPEG_passthrough_query, NULL, 0) > 0) {
628
1.67k
        jddp->StartedPassThrough = 0;
629
1.67k
        jddp->PassThrough = 1;
630
1.67k
        jddp->PassThroughfn = (PDF_DCTD_PassThrough);
631
1.67k
        jddp->device = (void *)dev;
632
1.67k
    }
633
4.77k
    else {
634
4.77k
        jddp->PassThrough = 0;
635
4.77k
        jddp->device = (void *)NULL;
636
4.77k
    }
637
638
    /* Hack for Bug695112.pdf to grab a height in case it is missing from the JPEG data */
639
6.44k
    code = pdfi_dict_knownget_number(ctx, stream_dict, "Height", &Height);
640
6.44k
    if (code < 0)
641
0
        return code;
642
6.44k
    jddp->Height = (int)floor(Height);
643
644
6.44k
    jddp->templat = s_DCTD_template;
645
646
6.44k
    code = pdfi_filter_open(min_size, &s_filter_read_procs, (const stream_template *)&jddp->templat, (const stream_state *)&dcts, ctx->memory->non_gc_memory, new_stream);
647
6.44k
    if (code < 0)
648
0
        return code;
649
6.44k
    (*new_stream)->strm = source;
650
6.44k
    source = *new_stream;
651
652
6.44k
    return 0;
653
6.44k
}
654
655
static int pdfi_ASCII85_filter(pdf_context *ctx, pdf_dict *d, stream *source, stream **new_stream)
656
225
{
657
225
    stream_A85D_state ss;
658
225
    uint min_size = 2048;
659
225
    int code;
660
661
225
    ss.pdf_rules = true;
662
663
225
    code = pdfi_filter_open(min_size, &s_filter_read_procs, (const stream_template *)&s_A85D_template, (const stream_state *)&ss, ctx->memory->non_gc_memory, new_stream);
664
225
    if (code < 0)
665
0
        return code;
666
667
225
    (*new_stream)->strm = source;
668
225
    return 0;
669
225
}
670
671
static int pdfi_CCITTFax_filter(pdf_context *ctx, pdf_dict *d, stream *source, stream **new_stream)
672
509
{
673
509
    stream_CFD_state ss;
674
509
    uint min_size = 2048;
675
509
    bool bval;
676
509
    int code;
677
509
    int64_t i;
678
679
509
    s_CF_set_defaults_inline(&ss);
680
681
509
    if (d && pdfi_type_of(d) == PDF_DICT) {
682
498
        code = pdfi_dict_get_int(ctx, d, "K", &i);
683
498
        if (code < 0 && code != gs_error_undefined)
684
0
            return code;
685
498
        if (code == 0)
686
483
            ss.K = i;
687
688
498
        code = pdfi_dict_get_bool(ctx, d, "EndOfLine", &bval);
689
498
        if (code < 0 && code != gs_error_undefined)
690
0
            return code;
691
498
        if (code == 0)
692
0
            ss.EndOfLine = bval ? 1 : 0;
693
694
498
        code = pdfi_dict_get_bool(ctx, d, "EncodedByteAlign", &bval);
695
498
        if (code < 0 && code != gs_error_undefined)
696
0
            return code;
697
498
        if (code == 0)
698
0
            ss.EncodedByteAlign = bval ? 1 : 0;
699
700
498
        code = pdfi_dict_get_bool(ctx, d, "EndOfBlock", &bval);
701
498
        if (code < 0 && code != gs_error_undefined)
702
0
            return code;
703
498
        if (code == 0)
704
113
            ss.EndOfBlock = bval ? 1 : 0;
705
706
498
        code = pdfi_dict_get_bool(ctx, d, "BlackIs1", &bval);
707
498
        if (code < 0 && code != gs_error_undefined)
708
0
            return code;
709
498
        if (code == 0)
710
10
            ss.BlackIs1 = bval ? 1 : 0;
711
712
498
        code = pdfi_dict_get_int(ctx, d, "Columns", &i);
713
498
        if (code < 0 && code != gs_error_undefined)
714
0
            return code;
715
498
        if (code == 0)
716
494
            ss.Columns = i;
717
718
498
        code = pdfi_dict_get_int(ctx, d, "Rows", &i);
719
498
        if (code < 0 && code != gs_error_undefined)
720
0
            return code;
721
498
        if (code == 0)
722
243
            ss.Rows = i;
723
724
498
        code = pdfi_dict_get_int(ctx, d, "DamagedRowsBeforeError", &i);
725
498
        if (code < 0 && code != gs_error_undefined)
726
0
            return code;
727
498
        if (code == 0)
728
0
            ss.DamagedRowsBeforeError = i;
729
730
498
    }
731
732
509
    code = pdfi_filter_open(min_size, &s_filter_read_procs,
733
509
                            (const stream_template *)&s_CFD_template,
734
509
                            (const stream_state *)&ss,
735
509
                            ctx->memory->non_gc_memory, new_stream);
736
509
    if (code < 0)
737
0
        return code;
738
739
509
    (*new_stream)->strm = source;
740
509
    return 0;
741
509
}
742
743
static int pdfi_RunLength_filter(pdf_context *ctx, pdf_dict *d, stream *source, stream **new_stream)
744
0
{
745
0
    stream_RLD_state ss;
746
0
    uint min_size = 2048;
747
0
    int code;
748
749
0
    if (s_RLD_template.set_defaults)
750
0
        (*s_RLD_template.set_defaults) ((stream_state *) & ss);
751
752
0
    code = pdfi_filter_open(min_size, &s_filter_read_procs, (const stream_template *)&s_RLD_template, (const stream_state *)&ss, ctx->memory->non_gc_memory, new_stream);
753
0
    if (code < 0)
754
0
        return code;
755
756
0
    (*new_stream)->strm = source;
757
0
    return 0;
758
0
}
759
760
static int pdfi_simple_filter(pdf_context *ctx, const stream_template *tmplate, stream *source, stream **new_stream)
761
405
{
762
405
    uint min_size = 2048;
763
405
    int code;
764
765
405
    code = pdfi_filter_open(min_size, &s_filter_read_procs, tmplate, NULL, ctx->memory->non_gc_memory, new_stream);
766
405
    if (code < 0)
767
0
        return code;
768
769
405
    (*new_stream)->strm = source;
770
405
    return 0;
771
405
}
772
773
static int pdfi_apply_filter(pdf_context *ctx, pdf_dict *dict, pdf_name *n, pdf_dict *decode,
774
                             stream *source, stream **new_stream, bool inline_image)
775
2.18M
{
776
2.18M
    int code;
777
778
2.18M
    if (ctx->args.pdfdebug)
779
0
    {
780
0
        char str[100];
781
0
        memcpy(str, (const char *)n->data, n->length);
782
0
        str[n->length] = '\0';
783
0
        dmprintf1(ctx->memory, "FILTER NAME:%s\n", str);
784
0
    }
785
786
2.18M
    if (pdfi_name_is(n, "RunLengthDecode")) {
787
0
        code = pdfi_RunLength_filter(ctx, decode, source, new_stream);
788
0
        return code;
789
0
    }
790
2.18M
    if (pdfi_name_is(n, "CCITTFaxDecode")) {
791
291
        code = pdfi_CCITTFax_filter(ctx, decode, source, new_stream);
792
291
        return code;
793
291
    }
794
2.18M
    if (pdfi_name_is(n, "ASCIIHexDecode")) {
795
252
        code = pdfi_simple_filter(ctx, &s_AXD_template, source, new_stream);
796
252
        return code;
797
252
    }
798
2.18M
    if (pdfi_name_is(n, "ASCII85Decode")) {
799
137
        code = pdfi_ASCII85_filter(ctx, decode, source, new_stream);
800
137
        return code;
801
137
    }
802
2.18M
    if (pdfi_name_is(n, "SubFileDecode")) {
803
0
        code = pdfi_simple_filter(ctx, &s_SFD_template, source, new_stream);
804
0
        return code;
805
0
    }
806
2.18M
    if (pdfi_name_is(n, "FlateDecode")) {
807
2.17M
        code = pdfi_Flate_filter(ctx, decode, source, new_stream);
808
2.17M
        return code;
809
2.17M
    }
810
10.1k
    if (pdfi_name_is(n, "JBIG2Decode")) {
811
64
        code = pdfi_JBIG2Decode_filter(ctx, dict, decode, source, new_stream);
812
64
        return code;
813
64
    }
814
10.0k
    if (pdfi_name_is(n, "LZWDecode")) {
815
26
        code = pdfi_LZW_filter(ctx, decode, source, new_stream);
816
26
        return code;
817
26
    }
818
10.0k
    if (pdfi_name_is(n, "DCTDecode")) {
819
6.43k
        code = pdfi_DCT_filter(ctx, dict, decode, source, new_stream);
820
6.43k
        return code;
821
6.43k
    }
822
3.61k
    if (pdfi_name_is(n, "JPXDecode")) {
823
2.44k
        code = pdfi_JPX_filter(ctx, dict, decode, source, new_stream);
824
2.44k
        return code;
825
2.44k
    }
826
827
1.17k
    if (pdfi_name_is(n, "AHx")) {
828
153
        if (!inline_image) {
829
42
            pdfi_set_warning(ctx, 0, NULL, W_PDF_BAD_INLINEFILTER, "pdfi_apply_filter", NULL);
830
42
            if (ctx->args.pdfstoponwarning)
831
0
                return_error(gs_error_syntaxerror);
832
42
        }
833
153
        code = pdfi_simple_filter(ctx, &s_AXD_template, source, new_stream);
834
153
        return code;
835
153
    }
836
1.02k
    if (pdfi_name_is(n, "A85")) {
837
88
        if (!inline_image) {
838
67
            pdfi_set_warning(ctx, 0, NULL, W_PDF_BAD_INLINEFILTER, "pdfi_apply_filter", NULL);
839
67
            if (ctx->args.pdfstoponwarning)
840
0
                return_error(gs_error_syntaxerror);
841
67
        }
842
88
        code = pdfi_ASCII85_filter(ctx, decode, source, new_stream);
843
88
        return code;
844
88
    }
845
938
    if (pdfi_name_is(n, "LZW")) {
846
0
        if (!inline_image) {
847
0
            pdfi_set_warning(ctx, 0, NULL, W_PDF_BAD_INLINEFILTER, "pdfi_apply_filter", NULL);
848
0
            if (ctx->args.pdfstoponwarning)
849
0
                return_error(gs_error_syntaxerror);
850
0
        }
851
0
        code = pdfi_LZW_filter(ctx, decode, source, new_stream);
852
0
        return code;
853
0
    }
854
938
    if (pdfi_name_is(n, "CCF")) {
855
218
        if (!inline_image) {
856
0
            pdfi_set_warning(ctx, 0, NULL, W_PDF_BAD_INLINEFILTER, "pdfi_apply_filter", NULL);
857
0
            if (ctx->args.pdfstoponwarning)
858
0
                return_error(gs_error_syntaxerror);
859
0
        }
860
218
        code = pdfi_CCITTFax_filter(ctx, decode, source, new_stream);
861
218
        return code;
862
218
    }
863
720
    if (pdfi_name_is(n, "DCT")) {
864
18
        if (!inline_image) {
865
0
            pdfi_set_warning(ctx, 0, NULL, W_PDF_BAD_INLINEFILTER, "pdfi_apply_filter", NULL);
866
0
            if (ctx->args.pdfstoponwarning)
867
0
                return_error(gs_error_syntaxerror);
868
0
        }
869
18
        code = pdfi_DCT_filter(ctx, dict, decode, source, new_stream);
870
18
        return code;
871
18
    }
872
702
    if (pdfi_name_is(n, "Fl")) {
873
35
        if (!inline_image) {
874
2
            pdfi_set_warning(ctx, 0, NULL, W_PDF_BAD_INLINEFILTER, "pdfi_apply_filter", NULL);
875
2
            if (ctx->args.pdfstoponwarning)
876
0
                return_error(gs_error_syntaxerror);
877
2
        }
878
35
        code = pdfi_Flate_filter(ctx, decode, source, new_stream);
879
35
        return code;
880
35
    }
881
667
    if (pdfi_name_is(n, "RL")) {
882
0
        if (!inline_image) {
883
0
            pdfi_set_warning(ctx, 0, NULL, W_PDF_BAD_INLINEFILTER, "pdfi_apply_filter", NULL);
884
0
            if (ctx->args.pdfstoponwarning)
885
0
                return_error(gs_error_syntaxerror);
886
0
        }
887
0
        code = pdfi_RunLength_filter(ctx, decode, source, new_stream);
888
0
        return code;
889
0
    }
890
891
667
    pdfi_set_error(ctx, 0, NULL, E_PDF_UNKNOWNFILTER, "pdfi_apply_filter", NULL);
892
667
    return_error(gs_error_undefined);
893
667
}
894
895
int pdfi_filter_no_decryption(pdf_context *ctx, pdf_stream *stream_obj,
896
                              pdf_c_stream *source, pdf_c_stream **new_stream, bool inline_image)
897
2.25M
{
898
2.25M
    pdf_obj *o = NULL, *o1 = NULL;
899
2.25M
    pdf_obj *decode = NULL;
900
2.25M
    pdf_obj *Filter = NULL;
901
2.25M
    pdf_dict *stream_dict = NULL;
902
2.25M
    pdf_array *DecodeParams = NULL;
903
2.25M
    int code;
904
2.25M
    int64_t i, j, duplicates;
905
2.25M
    stream *s = source->s, *new_s = NULL;
906
907
2.25M
    *new_stream = NULL;
908
909
2.25M
    if (ctx->args.pdfdebug) {
910
0
        gs_offset_t stream_offset = pdfi_stream_offset(ctx, stream_obj);
911
0
        dmprintf2(ctx->memory, "Filter: offset %ld(0x%lx)\n", stream_offset, stream_offset);
912
0
    }
913
914
2.25M
    code = pdfi_dict_from_obj(ctx, (pdf_obj *)stream_obj, &stream_dict);
915
2.25M
    if (code < 0)
916
0
        goto exit;
917
918
2.25M
    code = pdfi_dict_knownget(ctx, stream_dict, "Filter", &Filter);
919
2.25M
    if (code == 0 && inline_image)
920
6.98k
        code = pdfi_dict_knownget(ctx, stream_dict, "F", &Filter);
921
2.25M
    if (code < 0)
922
0
        goto exit;
923
2.25M
    if (code == 0) {
924
        /* No filter, just open the stream */
925
78.6k
        code = pdfi_alloc_stream(ctx, s, source->s, new_stream);
926
78.6k
        goto exit;
927
78.6k
    }
928
929
2.18M
    switch (pdfi_type_of(Filter)) {
930
1
    default:
931
1
        code = gs_note_error(gs_error_typecheck);
932
1
        goto exit;
933
2.16M
    case PDF_NAME:
934
2.16M
        code = pdfi_dict_knownget(ctx, stream_dict, "DecodeParms", &decode);
935
2.16M
        if (code == 0 && inline_image)
936
235
            code = pdfi_dict_knownget(ctx, stream_dict, "DP", &decode);
937
2.16M
        if (code < 0)
938
4
            goto exit;
939
940
2.16M
        code = pdfi_apply_filter(ctx, stream_dict, (pdf_name *)Filter,
941
2.16M
                                 (pdf_dict *)decode, s, &new_s, inline_image);
942
2.16M
        if (code < 0)
943
941
            goto exit;
944
945
2.16M
        code = pdfi_alloc_stream(ctx, new_s, source->s, new_stream);
946
2.16M
        break;
947
14.1k
    case PDF_ARRAY:
948
14.1k
    {
949
14.1k
        pdf_array *filter_array = (pdf_array *)Filter;
950
951
14.1k
        code = pdfi_dict_knownget_type(ctx, stream_dict, "DecodeParms", PDF_ARRAY, (pdf_obj **)&DecodeParams);
952
14.1k
        if (code == 0 && inline_image)
953
164
            code = pdfi_dict_knownget_type(ctx, stream_dict, "DP", PDF_ARRAY, (pdf_obj **)&DecodeParams);
954
14.1k
        if (code < 0)
955
0
            goto exit;
956
957
14.1k
        if (DecodeParams != NULL) {
958
1.83k
            if (pdfi_array_size(DecodeParams) == 0 || pdfi_array_size(DecodeParams) != pdfi_array_size(filter_array)) {
959
8
                pdfi_countdown(DecodeParams);
960
8
                DecodeParams = NULL;
961
8
                pdfi_set_warning(ctx, 0, NULL, W_PDF_STREAM_BAD_DECODEPARMS, "pdfi_filter_no_decryption", NULL);
962
1.83k
            } else {
963
1.83k
                if (pdfi_array_size(DecodeParams) != pdfi_array_size(filter_array)) {
964
0
                    code = gs_note_error(gs_error_typecheck);
965
0
                    goto exit;
966
0
                }
967
1.83k
            }
968
1.83k
        }
969
970
        /* Check the Filter array to see if we have any duplicates (to prevent filter bombs)
971
         * For now we will allow one duplicate (in case people do stupid things like ASCIIEncode
972
         * and Flate and ASCIIEncode again or something).
973
         */
974
14.4k
        for (i = 0; i < (int)pdfi_array_size(filter_array) - 1;i++) {
975
231
            code = pdfi_array_get_type(ctx, filter_array, i, PDF_NAME, &o);
976
231
            if (code < 0)
977
0
                goto exit;
978
231
            duplicates = 0;
979
980
461
            for (j = i + 1; j < pdfi_array_size(filter_array);j++) {
981
231
                code = pdfi_array_get_type(ctx, filter_array, j, PDF_NAME, &o1);
982
231
                if (code < 0) {
983
1
                    goto exit;
984
1
                }
985
230
                if (((pdf_name *)o)->length == ((pdf_name *)o1)->length) {
986
2
                    if (memcmp(((pdf_name *)o)->data, ((pdf_name *)o1)->data, ((pdf_name *)o)->length) == 0)
987
0
                        duplicates++;
988
2
                }
989
230
                pdfi_countdown(o1);
990
230
                o1 = NULL;
991
230
            }
992
230
            pdfi_countdown(o);
993
230
            o = NULL;
994
230
            if (duplicates > 2) {
995
0
                pdfi_set_error(ctx, 0, NULL, E_PDF_BADSTREAM, "pdfi_filter_nodecryption", (char *)"**** ERROR Detected possible filter bomb (duplicate Filters).  Aborting processing");
996
0
                code = gs_note_error(gs_error_syntaxerror);
997
0
                goto exit;
998
0
            }
999
230
        }
1000
1001
28.5k
        for (i = 0; i < pdfi_array_size(filter_array);i++) {
1002
14.4k
            code = pdfi_array_get_type(ctx, filter_array, i, PDF_NAME, &o);
1003
14.4k
            if (code < 0)
1004
0
                goto error;
1005
14.4k
            if (DecodeParams != NULL) {
1006
1.97k
                code = pdfi_array_get(ctx, DecodeParams, i, &decode);
1007
1.97k
                if (code < 0) {
1008
2
                    goto error;
1009
2
                }
1010
1.97k
            }
1011
14.4k
            if (decode && decode != PDF_NULL_OBJ && pdfi_type_of(decode) != PDF_DICT) {
1012
0
                pdfi_countdown(decode);
1013
0
                decode = NULL;
1014
0
                pdfi_set_warning(ctx, 0, NULL, W_PDF_STREAM_BAD_DECODEPARMS, "pdfi_filter_no_decryption", NULL);
1015
0
            }
1016
14.4k
            if (decode && decode == PDF_NULL_OBJ) {
1017
182
                pdfi_countdown(decode);
1018
182
                decode = NULL;
1019
182
            }
1020
1021
14.4k
            code = pdfi_apply_filter(ctx, stream_dict, (pdf_name *)o,
1022
14.4k
                                     (pdf_dict *)decode, s, &new_s, inline_image);
1023
14.4k
            pdfi_countdown(decode);
1024
14.4k
            decode = NULL;
1025
14.4k
            pdfi_countdown(o);
1026
14.4k
            o = NULL;
1027
14.4k
            if (code < 0)
1028
12
                goto error;
1029
1030
14.3k
            s = new_s;
1031
14.3k
        }
1032
14.1k
        code = pdfi_alloc_stream(ctx, s, source->s, new_stream);
1033
14.1k
    }
1034
2.18M
    }
1035
1036
2.25M
 exit:
1037
2.25M
    pdfi_countdown(o);
1038
2.25M
    pdfi_countdown(o1);
1039
2.25M
    pdfi_countdown(DecodeParams);
1040
2.25M
    pdfi_countdown(decode);
1041
2.25M
    pdfi_countdown(Filter);
1042
2.25M
    return code;
1043
1044
14
 error:
1045
14
    if (s)
1046
14
        pdfi_close_filter_chain(ctx, s, source->s);
1047
14
    *new_stream = NULL;
1048
14
    pdfi_countdown(o);
1049
14
    pdfi_countdown(o1);
1050
14
    pdfi_countdown(DecodeParams);
1051
14
    pdfi_countdown(decode);
1052
14
    pdfi_countdown(Filter);
1053
14
    return code;
1054
2.18M
}
1055
1056
int pdfi_filter(pdf_context *ctx, pdf_stream *stream_obj, pdf_c_stream *source,
1057
                pdf_c_stream **new_stream, bool inline_image)
1058
2.25M
{
1059
2.25M
    int code;
1060
2.25M
    pdf_c_stream *crypt_stream = NULL, *SubFile_stream = NULL;
1061
2.25M
    pdf_string *StreamKey = NULL;
1062
2.25M
    pdf_dict *stream_dict = NULL;
1063
2.25M
    pdf_obj *FileSpec = NULL;
1064
2.25M
    pdf_stream *NewStream = NULL;
1065
2.25M
    bool known = false;
1066
1067
2.25M
    *new_stream = NULL;
1068
1069
2.25M
    code = pdfi_dict_from_obj(ctx, (pdf_obj *)stream_obj, &stream_dict);
1070
2.25M
    if (code < 0)
1071
0
        goto error;
1072
1073
    /* Horrifyingly, any stream dictionary can contain a file specification, which means that
1074
     * instead of using the stream from the PDF file we must use an external file.
1075
     * So much for portability!
1076
     * Note: We must not do this for inline images as an inline image dictionary can
1077
     * contain the abbreviation /F for the Filter, and an inline image is never a
1078
     * separate stream, it is (obviously) contained in the current stream.
1079
     */
1080
2.25M
    if (!inline_image) {
1081
2.24M
        code = pdfi_dict_known(ctx, stream_dict, "F", &known);
1082
2.24M
        if (code >= 0 && known) {
1083
1
            pdf_obj *FS = NULL, *o = NULL;
1084
1
            pdf_dict *dict = NULL;
1085
1
            stream *gstream = NULL;
1086
1087
1
            code = pdfi_dict_get(ctx, stream_dict, "F", &FileSpec);
1088
1
            if (code < 0)
1089
0
                goto error;
1090
1
            if (pdfi_type_of(FileSpec) == PDF_DICT) {
1091
                /* We don't really support FileSpec dictionaries, partly because we
1092
                 * don't really know which platform to use. If there is a /F string
1093
                 * then we will use that, just as if we had been given a string in
1094
                 * the first place.
1095
                 */
1096
0
                code = pdfi_dict_knownget(ctx, (pdf_dict *)FileSpec, "F", &FS);
1097
0
                if (code < 0) {
1098
0
                    goto error;
1099
0
                }
1100
0
                pdfi_countdown(FileSpec);
1101
0
                FileSpec = FS;
1102
0
                FS = NULL;
1103
0
            }
1104
1
            if (pdfi_type_of(FileSpec) != PDF_STRING) {
1105
1
                code = gs_note_error(gs_error_typecheck);
1106
1
                goto error;
1107
1
            }
1108
            /* We should now have a string with the filename (or URL). We need
1109
             * to open the file and create a stream, if that succeeds.
1110
             */
1111
0
            gstream = sfopen((const char *)((pdf_string *)FileSpec)->data, "r", ctx->memory);
1112
0
            if (gstream == NULL) {
1113
0
                emprintf1(ctx->memory, "Failed to open file %s\n", (const char *)((pdf_string *)FileSpec)->data);
1114
0
                code = gs_note_error(gs_error_ioerror);
1115
0
                goto error;
1116
0
            }
1117
1118
0
            source = (pdf_c_stream *)gs_alloc_bytes(ctx->memory, sizeof(pdf_c_stream), "external stream");
1119
0
            if (source == NULL) {
1120
0
                code = gs_note_error(gs_error_VMerror);
1121
0
                goto error;
1122
0
            }
1123
0
            memset(source, 0x00, sizeof(pdf_c_stream));
1124
0
            source->s = gstream;
1125
1126
0
            code = pdfi_object_alloc(ctx, PDF_STREAM, 0, (pdf_obj **)&NewStream);
1127
0
            if (code < 0)
1128
0
                goto error;
1129
0
            pdfi_countup(NewStream);
1130
0
            code = pdfi_dict_alloc(ctx, 32, &dict);
1131
0
            if (code < 0){
1132
0
                pdfi_countdown(NewStream);
1133
0
                goto error;
1134
0
            }
1135
0
            pdfi_countup(dict);
1136
0
            NewStream->stream_dict = dict;
1137
0
            code = pdfi_dict_get(ctx, stream_dict, "FFilter", &o);
1138
0
            if (code >= 0) {
1139
0
                code = pdfi_dict_put(ctx, NewStream->stream_dict, "Filter", o);
1140
0
                if (code < 0) {
1141
0
                    pdfi_countdown(NewStream);
1142
0
                    goto error;
1143
0
                }
1144
0
            }
1145
0
            code = pdfi_dict_get(ctx, stream_dict, "FPredictor", &o);
1146
0
            if (code >= 0) {
1147
0
                code = pdfi_dict_put(ctx, NewStream->stream_dict, "Predictor", o);
1148
0
                if (code < 0) {
1149
0
                    pdfi_countdown(NewStream);
1150
0
                    goto error;
1151
0
                }
1152
0
            }
1153
0
            pdfi_countup(NewStream->stream_dict);
1154
0
            NewStream->stream_offset = 0;
1155
0
            NewStream->Length = 0;
1156
0
            NewStream->length_valid = 0;
1157
0
            NewStream->stream_written = 0;
1158
0
            NewStream->is_marking = 0;
1159
0
            NewStream->parent_obj = NULL;
1160
0
            stream_obj = NewStream;
1161
0
            stream_dict = NewStream->stream_dict;
1162
0
        }
1163
2.24M
    }
1164
1165
    /* If the file isn't encrypted, don't apply encryption. If this is an inline
1166
     * image then its in a content stream and will already be decrypted, so don't
1167
     * apply decryption again.
1168
     */
1169
2.25M
    if (ctx->encryption.is_encrypted && !inline_image) {
1170
3.11k
        int64_t Length;
1171
1172
3.11k
        if (ctx->encryption.StmF == CRYPT_IDENTITY)
1173
0
            return pdfi_filter_no_decryption(ctx, stream_obj, source, new_stream, inline_image);
1174
1175
3.11k
        code = pdfi_dict_get_type(ctx, stream_dict, "StreamKey", PDF_STRING, (pdf_obj **)&StreamKey);
1176
3.11k
        if (code == gs_error_undefined) {
1177
1.74k
            code = pdfi_compute_objkey(ctx, (pdf_obj *)stream_dict, &StreamKey);
1178
1.74k
            if (code < 0)
1179
0
                return code;
1180
1.74k
            code = pdfi_dict_put(ctx, stream_dict, "StreamKey", (pdf_obj *)StreamKey);
1181
1.74k
            if (code < 0)
1182
0
                goto error;
1183
1.74k
        }
1184
3.11k
        if (code < 0)
1185
0
            return code;
1186
1187
        /* If we are applying a decryption filter we must also apply a SubFileDecode filter.
1188
         * This is because the underlying stream may not have a compression filter, if it doesn't
1189
         * then we have no way of detecting the end of the data. Normally we would get an 'endstream'
1190
         * token but if we have applied a decryption filter then we'll 'decrypt' that token
1191
         * and that will corrupt it. So make sure we can't read past the end of the stream
1192
         * by applying a SubFileDecode.
1193
         * NB applying a SubFileDecode filter with an EODString seems to limit the amount of data
1194
         * that the decode filter is prepared to return at any time to the size of the EODString.
1195
         * This doesn't play well with other filters (eg the AESDecode filter) which require a
1196
         * larger minimum to be returned (16 bytes for AESDecode). So I'm using the filter
1197
         * Length here, even though I'd prefer not to.....
1198
         */
1199
3.11k
        Length = pdfi_stream_length(ctx, stream_obj);
1200
1201
3.11k
        if (Length <= 0) {
1202
            /* Don't treat as an encrypted stream if Length is 0 */
1203
10
            pdfi_countdown(StreamKey);
1204
10
            return pdfi_filter_no_decryption(ctx, stream_obj, source, new_stream, inline_image);
1205
10
        }
1206
1207
3.10k
        code = pdfi_apply_SubFileDecode_filter(ctx, Length, NULL, source, &SubFile_stream, false);
1208
3.10k
        if (code < 0)
1209
0
            goto error;
1210
1211
3.10k
        SubFile_stream->original = source->s;
1212
1213
3.10k
        switch(ctx->encryption.StrF) {
1214
0
            case CRYPT_IDENTITY:
1215
                /* Can't happen, handled above */
1216
0
                break;
1217
            /* There are only two possible filters, RC4 or AES, we take care
1218
             * of the number of bits in the key by using ctx->Length.
1219
             */
1220
644
            case CRYPT_V1:
1221
644
            case CRYPT_V2:
1222
644
                code = pdfi_apply_Arc4_filter(ctx, StreamKey, SubFile_stream, &crypt_stream);
1223
644
                break;
1224
2.12k
            case CRYPT_AESV2:
1225
2.46k
            case CRYPT_AESV3:
1226
2.46k
                code = pdfi_apply_AES_filter(ctx, StreamKey, 1, SubFile_stream, &crypt_stream);
1227
2.46k
                break;
1228
0
            default:
1229
0
                code = gs_error_rangecheck;
1230
3.10k
        }
1231
3.10k
        if (code < 0) {
1232
0
            pdfi_close_file(ctx, SubFile_stream);
1233
0
            goto error;
1234
0
        }
1235
1236
3.10k
        crypt_stream->original = SubFile_stream->original;
1237
3.10k
        gs_free_object(ctx->memory, SubFile_stream, "pdfi_filter");
1238
1239
3.10k
        code = pdfi_filter_no_decryption(ctx, stream_obj, crypt_stream, new_stream, false);
1240
3.10k
        if (code < 0) {
1241
4
            pdfi_close_file(ctx, crypt_stream);
1242
4
            goto error;
1243
4
        }
1244
1245
3.10k
        (*new_stream)->original = source->s;
1246
3.10k
        gs_free_object(ctx->memory, crypt_stream, "pdfi_filter");
1247
2.25M
    } else {
1248
2.25M
        code = pdfi_filter_no_decryption(ctx, stream_obj, source, new_stream, inline_image);
1249
2.25M
    }
1250
2.25M
error:
1251
2.25M
    pdfi_countdown(NewStream);
1252
2.25M
    pdfi_countdown(StreamKey);
1253
2.25M
    pdfi_countdown(FileSpec);
1254
2.25M
    return code;
1255
2.25M
}
1256
1257
/* This is just a convenience routine. We could use pdfi_filter() above, but because PDF
1258
 * doesn't support the SubFileDecode filter that would mean callers having to manufacture
1259
 * a dictionary in order to use it. That's excessively convoluted, so just supply a simple
1260
 * means to instantiate a SubFileDecode filter.
1261
 *
1262
 * NB! The EODString can't be tracked by the stream code. The caller is responsible for
1263
 * managing the lifetime of this object. It must remain valid until the filter is closed.
1264
 */
1265
int pdfi_apply_SubFileDecode_filter(pdf_context *ctx, int EODCount, const char *EODString, pdf_c_stream *source, pdf_c_stream **new_stream, bool inline_image)
1266
3.64M
{
1267
3.64M
    int code;
1268
3.64M
    stream_SFD_state state;
1269
3.64M
    stream *new_s = NULL;
1270
3.64M
    int min_size = 2048;
1271
1272
3.64M
    *new_stream = NULL;
1273
1274
3.64M
    memset(&state, 0, sizeof(state));
1275
1276
3.64M
    if (s_SFD_template.set_defaults)
1277
3.64M
        s_SFD_template.set_defaults((stream_state *)&state);
1278
1279
3.64M
    if (EODString != NULL) {
1280
801k
        state.eod.data = (const byte *)EODString;
1281
801k
        state.eod.size = strlen(EODString);
1282
801k
    }
1283
1284
3.64M
    if (EODCount > 0)
1285
2.84M
        state.count = EODCount - source->unread_size;
1286
803k
    else
1287
803k
        state.count = EODCount;
1288
1289
3.64M
    code = pdfi_filter_open(min_size, &s_filter_read_procs, (const stream_template *)&s_SFD_template, (const stream_state *)&state, ctx->memory->non_gc_memory, &new_s);
1290
3.64M
    if (code < 0)
1291
0
        return code;
1292
1293
3.64M
    code = pdfi_alloc_stream(ctx, new_s, source->s, new_stream);
1294
3.64M
    if (code < 0) {
1295
0
        gs_free_object(ctx->memory->non_gc_memory, new_s->state, "pdfi_apply_SubFileDecode_filter");
1296
0
        gs_free_object(ctx->memory->non_gc_memory, new_s->cbuf, "pdfi_apply_SubFileDecode_filter");
1297
0
        gs_free_object(ctx->memory->non_gc_memory, new_s, "pdfi_apply_SubFileDecode_filter");
1298
0
        return code;
1299
0
    }
1300
3.64M
    new_s->strm = source->s;
1301
3.64M
    if (source->unread_size != 0) {
1302
0
        (*new_stream)->unread_size = source->unread_size;
1303
0
        memcpy((*new_stream)->unget_buffer, source->unget_buffer, source->unread_size);
1304
0
        source->unread_size = 0;
1305
0
    }
1306
3.64M
    return code;
1307
3.64M
}
1308
1309
/* We would really like to use a ReusableStreamDecode filter here, but that filter is defined
1310
 * purely in the PostScript interpreter. So instead we make a temporary stream from a
1311
 * memory buffer. Its icky (we can end up with the same data in memory multiple times)
1312
 * but it works, and is used elsewhere in Ghostscript.
1313
 * If retain_ownership is true then the calling function is responsible for buffer pointer lifetime.
1314
 * Otherwise the buffer will be freed when the stream is closed.
1315
 */
1316
int pdfi_open_memory_stream_from_stream(pdf_context *ctx, unsigned int size, byte **Buffer, pdf_c_stream *source, pdf_c_stream **new_pdf_stream, bool retain_ownership)
1317
36.4k
{
1318
36.4k
    stream *new_stream;
1319
36.4k
    int code;
1320
1321
36.4k
    new_stream = file_alloc_stream(ctx->memory, "open memory stream(stream)");
1322
36.4k
    if (new_stream == NULL)
1323
0
        return_error(gs_error_VMerror);
1324
1325
36.4k
    *Buffer = gs_alloc_bytes(ctx->memory, size, "open memory stream (buffer)");
1326
36.4k
    if (*Buffer == NULL) {
1327
0
        gs_free_object(ctx->memory, new_stream, "open memory stream(stream)");
1328
0
        return_error(gs_error_VMerror);
1329
0
    }
1330
36.4k
    code = pdfi_read_bytes(ctx, *Buffer, 1, size, source);
1331
36.4k
    if (code < 0) {
1332
0
        gs_free_object(ctx->memory, *Buffer, "open memory stream(buffer)");
1333
0
        gs_free_object(ctx->memory, new_stream, "open memory stream(stream)");
1334
0
        return code;
1335
0
    }
1336
1337
36.4k
    if (retain_ownership)
1338
17.5k
        sread_string_reusable(new_stream, *Buffer, size);
1339
18.8k
    else
1340
18.8k
        sread_transient_string_reusable(new_stream, ctx->memory, *Buffer, size);
1341
1342
36.4k
    code = pdfi_alloc_stream(ctx, new_stream, source->s, new_pdf_stream);
1343
36.4k
    if (code < 0) {
1344
0
        sclose(new_stream);
1345
0
        gs_free_object(ctx->memory, *Buffer, "open memory stream(buffer)");
1346
0
        gs_free_object(ctx->memory, new_stream, "open memory stream(stream)");
1347
0
    }
1348
1349
36.4k
    return code;
1350
36.4k
}
1351
1352
/*
1353
 * Like pdfi_open_memory_stream_from_stream (and makes use of it) this is a way to read from a stream into
1354
 * memory, and return a stream which reads from that memory. The difference is that this function takes
1355
 * any filters into account, decompressing them. We could layer a decompression stream onto the memory
1356
 * stream returned by open_memory_stream_from_stream above instead.
1357
 *
1358
 * This function returns < 0 for an error, and the length of the uncompressed data on success.
1359
 */
1360
int pdfi_open_memory_stream_from_filtered_stream(pdf_context *ctx, pdf_stream *stream_obj,
1361
                                                 unsigned int size, byte **Buffer, pdf_c_stream *source,
1362
                                                 pdf_c_stream **new_pdf_stream, bool retain_ownership)
1363
36.4k
{
1364
36.4k
    int code;
1365
36.4k
    pdf_dict *dict = NULL;
1366
36.4k
    int decompressed_length = 0;
1367
36.4k
    byte *decompressed_Buffer = NULL;
1368
36.4k
    pdf_c_stream *compressed_stream = NULL, *decompressed_stream = NULL;
1369
36.4k
    bool known = false;
1370
1371
36.4k
    code = pdfi_open_memory_stream_from_stream(ctx, (unsigned int)size, Buffer, source, new_pdf_stream, retain_ownership);
1372
36.4k
    if (code < 0) {
1373
0
        pdfi_close_memory_stream(ctx, *Buffer, *new_pdf_stream);
1374
0
        *Buffer = NULL;
1375
0
        *new_pdf_stream = NULL;
1376
0
        return code;
1377
0
    }
1378
1379
36.4k
    if (stream_obj == NULL)
1380
0
        return size;
1381
1382
36.4k
    code = pdfi_dict_from_obj(ctx, (pdf_obj *)stream_obj, &dict);
1383
36.4k
    if (code < 0)
1384
0
        return code;
1385
1386
36.4k
    pdfi_dict_known(ctx, dict, "F", &known);
1387
36.4k
    if (!known)
1388
36.4k
        pdfi_dict_known(ctx, dict, "Filter", &known);
1389
1390
36.4k
    if (!known)
1391
4.32k
        return size;
1392
1393
32.0k
    compressed_stream = *new_pdf_stream;
1394
    /* This is again complicated by requiring a seekable stream, and the fact that,
1395
     * unlike fonts, there is no Length2 key to tell us how large the uncompressed
1396
     * stream is.
1397
     */
1398
32.0k
    code = pdfi_filter(ctx, stream_obj, compressed_stream, &decompressed_stream, false);
1399
32.0k
    if (code < 0) {
1400
126
        pdfi_close_memory_stream(ctx, *Buffer, *new_pdf_stream);
1401
126
        *Buffer = NULL;
1402
126
        *new_pdf_stream = NULL;
1403
126
        return code;
1404
126
    }
1405
123k
    do {
1406
123k
        byte b[512];
1407
123k
        code = pdfi_read_bytes(ctx, (byte *)&b, 1, 512, decompressed_stream);
1408
123k
        if (code <= 0)
1409
10.1k
            break;
1410
113k
        decompressed_length+=code;
1411
113k
        if (code < 512)
1412
21.8k
            break;
1413
113k
    } while (true);
1414
0
    pdfi_close_file(ctx, decompressed_stream);
1415
1416
31.9k
    decompressed_Buffer = gs_alloc_bytes(ctx->memory, decompressed_length, "pdfi_open_memory_stream_from_filtered_stream (decompression buffer)");
1417
31.9k
    if (decompressed_Buffer != NULL) {
1418
31.9k
        code = srewind(compressed_stream->s);
1419
31.9k
        if (code >= 0) {
1420
31.9k
            code = pdfi_filter(ctx, stream_obj, compressed_stream,
1421
31.9k
                               &decompressed_stream, false);
1422
31.9k
            if (code >= 0) {
1423
31.9k
                code = pdfi_read_bytes(ctx, decompressed_Buffer, 1, decompressed_length, decompressed_stream);
1424
31.9k
                pdfi_close_file(ctx, decompressed_stream);
1425
31.9k
                code = pdfi_close_memory_stream(ctx, *Buffer, *new_pdf_stream);
1426
31.9k
                if (code >= 0) {
1427
31.9k
                    *Buffer = decompressed_Buffer;
1428
31.9k
                    code = pdfi_open_memory_stream_from_memory(ctx, (unsigned int)decompressed_length,
1429
31.9k
                                                               *Buffer, new_pdf_stream, retain_ownership);
1430
31.9k
                } else {
1431
0
                    *Buffer = NULL;
1432
0
                    *new_pdf_stream = NULL;
1433
0
                }
1434
31.9k
            }
1435
31.9k
        } else {
1436
0
            pdfi_close_memory_stream(ctx, *Buffer, *new_pdf_stream);
1437
0
            gs_free_object(ctx->memory, decompressed_Buffer, "pdfi_open_memory_stream_from_filtered_stream");
1438
0
            gs_free_object(ctx->memory, Buffer, "pdfi_open_memory_stream_from_filtered_stream");
1439
0
            *Buffer = NULL;
1440
0
            *new_pdf_stream = NULL;
1441
0
            return code;
1442
0
        }
1443
31.9k
    } else {
1444
0
        pdfi_close_memory_stream(ctx, *Buffer, *new_pdf_stream);
1445
0
        gs_free_object(ctx->memory, Buffer, "pdfi_open_memory_stream_from_filtered_stream");
1446
0
        *Buffer = NULL;
1447
0
        *new_pdf_stream = NULL;
1448
0
        return_error(gs_error_VMerror);
1449
0
    }
1450
31.9k
    if (code < 0) {
1451
0
        gs_free_object(ctx->memory, Buffer, "pdfi_build_function_4");
1452
0
        *Buffer = NULL;
1453
0
        *new_pdf_stream = NULL;
1454
0
        return code;
1455
0
    }
1456
31.9k
    return decompressed_length;
1457
31.9k
}
1458
1459
int pdfi_open_memory_stream_from_memory(pdf_context *ctx, unsigned int size, byte *Buffer, pdf_c_stream **new_pdf_stream, bool retain_ownership)
1460
112k
{
1461
112k
    int code;
1462
112k
    stream *new_stream;
1463
1464
112k
    new_stream = file_alloc_stream(ctx->memory, "open memory stream from memory(stream)");
1465
112k
    if (new_stream == NULL)
1466
0
        return_error(gs_error_VMerror);
1467
112k
    new_stream->close_at_eod = false;
1468
112k
    if (retain_ownership)
1469
97.4k
        sread_string(new_stream, Buffer, size);
1470
14.7k
    else
1471
14.7k
        sread_transient_string(new_stream, ctx->memory, Buffer, size);
1472
1473
112k
    code = pdfi_alloc_stream(ctx, new_stream, NULL, new_pdf_stream);
1474
112k
    if (code < 0) {
1475
0
        sclose(new_stream);
1476
0
        gs_free_object(ctx->memory, new_stream, "open memory stream from memory(stream)");
1477
0
    }
1478
1479
112k
    return code;
1480
112k
}
1481
1482
int pdfi_close_memory_stream(pdf_context *ctx, byte *Buffer, pdf_c_stream *source)
1483
102k
{
1484
102k
    gs_free_object(ctx->memory, Buffer, "open memory stream(buffer)");
1485
102k
    if (source != NULL) {
1486
102k
        if (source->s != NULL) {
1487
102k
            sclose(source->s);
1488
102k
            gs_free_object(ctx->memory, source->s, "open memory stream(stream)");
1489
102k
        }
1490
102k
        gs_free_object(ctx->memory, source, "open memory stream(pdf_stream)");
1491
102k
    }
1492
102k
    return 0;
1493
102k
}
1494
1495
/***********************************************************************************/
1496
/* Basic 'file' operations. Because of the need to 'unread' bytes we need our own  */
1497
1498
static void pdfi_close_filter_chain(pdf_context *ctx, stream *s, stream *target)
1499
5.93M
{
1500
5.93M
    stream *next_s = s;
1501
1502
11.8M
    while(next_s && next_s != target){
1503
5.88M
        stream *curr_s = next_s;
1504
5.88M
        next_s = next_s->strm;
1505
5.88M
        if (curr_s != ctx->main_stream->s)
1506
5.88M
            sfclose(curr_s);
1507
5.88M
    }
1508
5.93M
}
1509
1510
void pdfi_close_file(pdf_context *ctx, pdf_c_stream *s)
1511
5.93M
{
1512
5.93M
    pdfi_close_filter_chain(ctx, s->s, s->original);
1513
1514
5.93M
    gs_free_object(ctx->memory, s, "closing pdf_file");
1515
5.93M
}
1516
1517
int pdfi_seek(pdf_context *ctx, pdf_c_stream *s, gs_offset_t offset, uint32_t origin)
1518
9.10M
{
1519
9.10M
    if (origin == SEEK_CUR && s->unread_size != 0)
1520
0
        offset -= s->unread_size;
1521
1522
9.10M
    s->unread_size = 0;;
1523
1524
9.10M
    return (sfseek(s->s, offset, origin));
1525
9.10M
}
1526
1527
/* We use 'stell' sometimes to save the position of the underlying file
1528
 * when reading a compressed stream, so that we can return to the same
1529
 * point in the underlying file after performing some other operation. This
1530
 * allows us (for instance) to load a font while interpreting a content stream.
1531
 * However, if we've 'unread' any bytes we need to take that into account.
1532
 * NOTE! this is only going to be valid when performed on the main stream
1533
 * the original PDF file, not any compressed stream!
1534
 */
1535
gs_offset_t pdfi_unread_tell(pdf_context *ctx)
1536
72.7M
{
1537
72.7M
    gs_offset_t off = stell(ctx->main_stream->s);
1538
1539
72.7M
    return (off - ctx->main_stream->unread_size);
1540
72.7M
}
1541
1542
gs_offset_t pdfi_tell(pdf_c_stream *s)
1543
519k
{
1544
519k
    return stell(s->s);
1545
519k
}
1546
1547
int pdfi_unread_byte(pdf_context *ctx, pdf_c_stream *s, char c)
1548
1.07G
{
1549
1.07G
    if (s->unread_size == UNREAD_BUFFER_SIZE)
1550
0
        return_error(gs_error_ioerror);
1551
1552
1.07G
    s->unget_buffer[s->unread_size++] = c;
1553
1554
1.07G
    return 0;
1555
1.07G
}
1556
1557
int pdfi_unread(pdf_context *ctx, pdf_c_stream *s, byte *Buffer, uint32_t size)
1558
97.2k
{
1559
97.2k
    if (size + s->unread_size > UNREAD_BUFFER_SIZE)
1560
6
        return_error(gs_error_ioerror);
1561
1562
97.2k
    Buffer += size;
1563
370k
    while (size) {
1564
273k
        s->unget_buffer[s->unread_size++] = *--Buffer;
1565
273k
        size--;
1566
273k
    }
1567
1568
97.2k
    return 0;
1569
97.2k
}
1570
1571
int pdfi_read_byte(pdf_context *ctx, pdf_c_stream *s)
1572
10.0G
{
1573
10.0G
    int32_t code;
1574
1575
10.0G
    if (s->eof && s->unread_size == 0)
1576
253k
        return EOFC;
1577
1578
10.0G
    if (s->unread_size)
1579
1.07G
        return (byte)s->unget_buffer[--s->unread_size];
1580
1581
    /* TODO the Ghostscript code uses sbufptr(s) to avoid a memcpy
1582
     * at some point we should modify this code to do so as well.
1583
     */
1584
9.01G
    code = spgetc(s->s);
1585
9.01G
    if (code == EOFC) {
1586
345k
        s->eof = true;
1587
345k
        return EOFC;
1588
9.01G
    } else if (code == gs_error_ioerror) {
1589
0
        pdfi_set_error(ctx, code, "sgets", E_PDF_BADSTREAM, "pdfi_read_bytes", NULL);
1590
0
        s->eof = true;
1591
0
        return EOFC;
1592
9.01G
    } else if(code == ERRC) {
1593
67.4k
        return ERRC;
1594
67.4k
    }
1595
9.01G
    return (int)code;
1596
9.01G
}
1597
1598
1599
int pdfi_read_bytes(pdf_context *ctx, byte *Buffer, uint32_t size, uint32_t count, pdf_c_stream *s)
1600
2.66M
{
1601
2.66M
    uint32_t i = 0, total = size * count;
1602
2.66M
    uint32_t bytes = 0;
1603
2.66M
    int32_t code;
1604
1605
2.66M
    if (s->eof && s->unread_size == 0)
1606
3.68k
        return 0;
1607
1608
2.66M
    if (s->unread_size) {
1609
17.7k
        i = s->unread_size;
1610
17.7k
        if (i >= total)
1611
0
            i = total;
1612
17.7k
        bytes = i;
1613
36.1k
        while (bytes) {
1614
18.4k
            *Buffer++ = s->unget_buffer[--s->unread_size];
1615
18.4k
            bytes--;
1616
18.4k
        }
1617
17.7k
        total -= i;
1618
17.7k
        if (total == 0 || s->eof)
1619
0
            return i;
1620
17.7k
    }
1621
1622
    /* TODO the Ghostscript code uses sbufptr(s) to avoid a memcpy
1623
     * at some point we should modify this code to do so as well.
1624
     */
1625
2.66M
    code = sgets(s->s, Buffer, total, &bytes);
1626
2.66M
    if (code == EOFC) {
1627
25.5k
        s->eof = true;
1628
2.63M
    } else if (code == gs_error_ioerror) {
1629
0
        pdfi_set_error(ctx, code, "sgets", E_PDF_BADSTREAM, "pdfi_read_bytes", NULL);
1630
0
        s->eof = true;
1631
2.63M
    } else if(code == ERRC) {
1632
7.55k
        bytes = ERRC;
1633
2.63M
    } else {
1634
2.63M
        bytes = bytes + i;
1635
2.63M
    }
1636
1637
2.66M
    return bytes;
1638
2.66M
}
1639
1640
/* Read bytes from stream object into buffer.
1641
 * Handles both plain streams and filtered streams.
1642
 * Buffer gets allocated here, and must be freed by caller.
1643
 * Preserves the location of the current stream file position.
1644
 */
1645
int
1646
pdfi_stream_to_buffer(pdf_context *ctx, pdf_stream *stream_obj, byte **buf, int64_t *bufferlen)
1647
41.1k
{
1648
41.1k
    byte *Buffer = NULL;
1649
41.1k
    int code = 0;
1650
41.1k
    int64_t buflen = 0, read = 0, ToRead = *bufferlen;
1651
41.1k
    gs_offset_t savedoffset;
1652
41.1k
    pdf_c_stream *stream;
1653
41.1k
    bool filtered;
1654
41.1k
    pdf_dict *stream_dict = NULL;
1655
1656
41.1k
    savedoffset = pdfi_tell(ctx->main_stream);
1657
1658
41.1k
    pdfi_seek(ctx, ctx->main_stream, pdfi_stream_offset(ctx, stream_obj), SEEK_SET);
1659
1660
41.1k
    code = pdfi_dict_from_obj(ctx, (pdf_obj *)stream_obj, &stream_dict);
1661
41.1k
    if (code < 0)
1662
0
        goto exit;
1663
1664
    /* See if this is a filtered stream */
1665
41.1k
    code = pdfi_dict_known(ctx, stream_dict, "Filter", &filtered);
1666
41.1k
    if (code < 0)
1667
0
        goto exit;
1668
1669
41.1k
    if (!filtered) {
1670
4.02k
        code = pdfi_dict_known(ctx, stream_dict, "F", &filtered);
1671
4.02k
        if (code < 0)
1672
0
            goto exit;
1673
4.02k
    }
1674
1675
41.1k
retry:
1676
41.1k
    if (ToRead == 0) {
1677
38.3k
        if (filtered || ctx->encryption.is_encrypted) {
1678
36.1k
            code = pdfi_filter(ctx, stream_obj, ctx->main_stream, &stream, false);
1679
36.1k
            if (code < 0) {
1680
36
                goto exit;
1681
36
            }
1682
522k
            while (seofp(stream->s) != true && serrorp(stream->s) != true) {
1683
486k
                (void)sbufskip(stream->s, sbufavailable(stream->s));
1684
486k
                s_process_read_buf(stream->s);
1685
486k
                buflen += sbufavailable(stream->s);
1686
486k
            }
1687
36.0k
            pdfi_close_file(ctx, stream);
1688
36.0k
        } else {
1689
2.25k
            buflen = pdfi_stream_length(ctx, stream_obj);
1690
2.25k
        }
1691
38.3k
    } else
1692
2.82k
        buflen = *bufferlen;
1693
1694
    /* Alloc buffer */
1695
41.1k
    Buffer = gs_alloc_bytes(ctx->memory, buflen, "pdfi_stream_to_buffer (Buffer)");
1696
41.1k
    if (!Buffer) {
1697
4
        code = gs_note_error(gs_error_VMerror);
1698
4
        goto exit;
1699
4
    }
1700
1701
41.1k
    code = pdfi_seek(ctx, ctx->main_stream, pdfi_stream_offset(ctx, stream_obj), SEEK_SET);
1702
41.1k
    if (code < 0) {
1703
0
        buflen = 0;
1704
0
        goto exit;
1705
0
    }
1706
41.1k
    if (filtered || ctx->encryption.is_encrypted) {
1707
37.1k
        code = pdfi_filter(ctx, stream_obj, ctx->main_stream, &stream, false);
1708
37.1k
        if (code < 0)
1709
4
            goto exit;
1710
37.1k
        read = sfread(Buffer, 1, buflen, stream->s);
1711
37.1k
        if (read == ERRC) {
1712
            /* Error reading the expected number of bytes. If we already calculated the number of
1713
             * bytes in the loop above, then ignore the error and carry on. If, however, we were
1714
             * told how many bytes to expect, and failed to read that many, go back and do this
1715
             * the slow way to determine how many bytes are *really* available.
1716
             */
1717
77
            if(ToRead != 0) {
1718
51
                buflen = ToRead = 0;
1719
51
                pdfi_close_file(ctx, stream);
1720
51
                code = pdfi_seek(ctx, ctx->main_stream, pdfi_stream_offset(ctx, stream_obj), SEEK_SET);
1721
51
                if (code < 0)
1722
0
                    goto exit;
1723
51
                gs_free_object(ctx->memory, Buffer, "pdfi_stream_to_buffer (Buffer)");
1724
51
                goto retry;
1725
51
            }
1726
77
        }
1727
37.0k
        pdfi_close_file(ctx, stream);
1728
37.0k
    } else {
1729
4.01k
        read = sfread(Buffer, 1, buflen, ctx->main_stream->s);
1730
4.01k
        if (read == ERRC) {
1731
            /* Error reading the expected number of bytes. If we already calculated the number of
1732
             * bytes in the loop above, then ignore the error and carry on. If, however, we were
1733
             * told how many bytes to expect, and failed to read that many, go back and do this
1734
             * the slow way to determine how many bytes are *really* available.
1735
             */
1736
0
            if(ToRead != 0) {
1737
0
                buflen = ToRead = 0;
1738
0
                code = pdfi_seek(ctx, ctx->main_stream, pdfi_stream_offset(ctx, stream_obj), SEEK_SET);
1739
0
                if (code < 0)
1740
0
                    goto exit;
1741
0
                gs_free_object(ctx->memory, Buffer, "pdfi_stream_to_buffer (Buffer)");
1742
0
                goto retry;
1743
0
            }
1744
0
        }
1745
4.01k
    }
1746
1747
41.1k
 exit:
1748
41.1k
    pdfi_seek(ctx, ctx->main_stream, savedoffset, SEEK_SET);
1749
41.1k
    if (Buffer && code < 0)
1750
4
        gs_free_object(ctx->memory, Buffer, "pdfi_stream_to_buffer (Buffer)");
1751
41.1k
    else
1752
41.1k
        *buf = Buffer;
1753
41.1k
    *bufferlen = buflen;
1754
41.1k
    return code;
1755
41.1k
}
1756
1757
int pdfi_open_resource_file(pdf_context *ctx, const char *fname, const int fnamelen, stream **s)
1758
323k
{
1759
323k
    int code = 0;
1760
323k
    if (fname == NULL || fnamelen == 0)
1761
0
        *s = NULL;
1762
323k
    else if (gp_file_name_is_absolute(fname, fnamelen) || fname[0] == '%') {
1763
        /* If it's an absolute path or an explicit PS style device, just try to open it */
1764
0
        *s = sfopen(fname, "r", ctx->memory);
1765
0
    }
1766
323k
    else {
1767
323k
        char fnametotry[gp_file_name_sizeof];
1768
323k
        uint fnlen;
1769
323k
        gs_parsed_file_name_t pname;
1770
323k
        gp_file_name_combine_result r;
1771
323k
        int i, total;
1772
1773
323k
        *s = NULL;
1774
323k
        i = 0;
1775
323k
        total = ctx->search_paths.num_resource_paths - ctx->search_paths.num_init_resource_paths - 1;
1776
622k
retry:
1777
4.61M
        for (; i < total; i++) {
1778
4.00M
            gs_param_string *ss = &ctx->search_paths.resource_paths[i];
1779
1780
4.00M
            if (ss->data[0] == '%') {
1781
631k
                code = gs_parse_file_name(&pname, (char *)ss->data, ss->size, ctx->memory);
1782
631k
                if (code < 0 || (pname.len + fnamelen >= gp_file_name_sizeof)) {
1783
0
                    continue;
1784
0
                }
1785
631k
                memcpy(fnametotry, pname.fname, pname.len);
1786
631k
                memcpy(fnametotry + pname.len, fname, fnamelen);
1787
631k
                code = pname.iodev->procs.open_file(pname.iodev, fnametotry, pname.len + fnamelen, "r", s, ctx->memory);
1788
631k
                if (code < 0) {
1789
615k
                    continue;
1790
615k
                }
1791
16.3k
                break;
1792
631k
            }
1793
3.37M
            else {
1794
3.37M
                fnlen = gp_file_name_sizeof;
1795
3.37M
                r = gp_file_name_combine((char *)ss->data, ss->size, fname, fnamelen, false, fnametotry, &fnlen);
1796
3.37M
                if (r != gp_combine_success || fnlen > gp_file_name_sizeof - 1)
1797
0
                    continue;
1798
3.37M
                fnametotry[fnlen] = '\0';
1799
3.37M
                *s = sfopen(fnametotry, "r", ctx->memory);
1800
3.37M
                if (*s != NULL)
1801
0
                    break;
1802
3.37M
            }
1803
4.00M
        }
1804
622k
        if (*s == NULL && i < ctx->search_paths.num_resource_paths) {
1805
307k
            gs_param_string *ss = &ctx->search_paths.genericresourcedir;
1806
307k
            fnlen = gp_file_name_sizeof;
1807
307k
            r = gp_file_name_combine((char *)ss->data, ss->size, fname, fnamelen, false, fnametotry, &fnlen);
1808
307k
            if (r == gp_combine_success || fnlen < gp_file_name_sizeof) {
1809
307k
                fnametotry[fnlen] = '\0';
1810
307k
                *s = sfopen(fnametotry, "r", ctx->memory);
1811
307k
            }
1812
307k
        }
1813
622k
        if (*s == NULL && i < ctx->search_paths.num_resource_paths) {
1814
298k
            total = ctx->search_paths.num_resource_paths;
1815
298k
            goto retry;
1816
298k
        }
1817
622k
    }
1818
323k
    if (*s == NULL)
1819
298k
        return_error(gs_error_invalidfileaccess);
1820
1821
25.4k
    return 0;
1822
323k
}
1823
1824
int pdfi_open_font_file(pdf_context *ctx, const char *fname, const int fnamelen, stream **s)
1825
316k
{
1826
316k
    int code = 0;
1827
316k
    const char *fontdirstr = "Font/";
1828
316k
    const int fontdirstrlen = strlen(fontdirstr);
1829
1830
316k
    if (fname == NULL || fnamelen == 0)
1831
0
        *s = NULL;
1832
316k
    else if (gp_file_name_is_absolute(fname, fnamelen) || fname[0] == '%') {
1833
        /* If it's an absolute path or an explicit PS style device, just try to open it */
1834
0
        *s = sfopen(fname, "r", ctx->memory);
1835
0
    }
1836
316k
    else {
1837
316k
        char fnametotry[gp_file_name_sizeof];
1838
316k
        uint fnlen;
1839
316k
        gs_parsed_file_name_t pname;
1840
316k
        gp_file_name_combine_result r;
1841
316k
        int i;
1842
1843
316k
        *s = NULL;
1844
316k
        for (i = 0; i < ctx->search_paths.num_font_paths; i++) {
1845
0
            gs_param_string *ss = &ctx->search_paths.font_paths[i];
1846
1847
0
            if (ss->data[0] == '%') {
1848
0
                code = gs_parse_file_name(&pname, (char *)ss->data, ss->size, ctx->memory);
1849
0
                if (code < 0 || (pname.len + fnamelen >= gp_file_name_sizeof)) {
1850
0
                    continue;
1851
0
                }
1852
0
                memcpy(fnametotry, pname.fname, pname.len);
1853
0
                memcpy(fnametotry + pname.len, fname, fnamelen);
1854
0
                code = pname.iodev->procs.open_file(pname.iodev, fnametotry, pname.len + fnamelen, "r", s, ctx->memory);
1855
0
                if (code < 0) {
1856
0
                    continue;
1857
0
                }
1858
0
                break;
1859
0
            }
1860
0
            else {
1861
0
                fnlen = gp_file_name_sizeof;
1862
0
                r = gp_file_name_combine((char *)ss->data, ss->size, fname, fnamelen, false, fnametotry, &fnlen);
1863
0
                if (r != gp_combine_success || fnlen > gp_file_name_sizeof - 1)
1864
0
                    continue;
1865
0
                fnametotry[fnlen] = '\0';
1866
0
                *s = sfopen(fnametotry, "r", ctx->memory);
1867
0
                if (*s != NULL)
1868
0
                    break;
1869
0
            }
1870
0
        }
1871
316k
        if (*s == NULL && i < ctx->search_paths.num_resource_paths) {
1872
316k
            gs_param_string *ss = &ctx->search_paths.genericresourcedir;
1873
316k
            char fstr[gp_file_name_sizeof];
1874
1875
316k
            fnlen = gp_file_name_sizeof;
1876
1877
316k
            memcpy(fstr, fontdirstr, fontdirstrlen);
1878
316k
            memcpy(fstr + fontdirstrlen, fname, fnamelen);
1879
1880
316k
            r = gp_file_name_combine((char *)ss->data, ss->size, fstr, fontdirstrlen + fnamelen, false, fnametotry, &fnlen);
1881
316k
            if (r == gp_combine_success || fnlen < gp_file_name_sizeof) {
1882
316k
                fnametotry[fnlen] = '\0';
1883
316k
                *s = sfopen(fnametotry, "r", ctx->memory);
1884
316k
            }
1885
316k
        }
1886
316k
    }
1887
316k
    if (*s == NULL)
1888
295k
        return pdfi_open_resource_file(ctx, fname, fnamelen, s);
1889
1890
20.4k
    return 0;
1891
316k
}