/src/ghostpdl/base/szlibd.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Copyright (C) 2001-2023 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., 39 Mesa Street, Suite 108A, San Francisco, |
13 | | CA 94129, USA, for further information. |
14 | | */ |
15 | | |
16 | | |
17 | | /* zlib decoding (decompression) filter stream */ |
18 | | #include "memory_.h" |
19 | | #include "std.h" |
20 | | #include "strimpl.h" |
21 | | #include "szlibxx.h" |
22 | | |
23 | | /* Initialize the filter. */ |
24 | | static int |
25 | | s_zlibD_init(stream_state * st) |
26 | 156k | { |
27 | 156k | stream_zlib_state *const ss = (stream_zlib_state *)st; |
28 | 156k | int code = s_zlib_alloc_dynamic_state(ss); |
29 | | |
30 | 156k | if (code < 0) |
31 | 0 | return ERRC; /****** WRONG ******/ |
32 | 156k | if (inflateInit2(&ss->dynamic->zstate, |
33 | 156k | (ss->no_wrapper ? -ss->windowBits : ss->windowBits)) |
34 | 156k | != Z_OK |
35 | 156k | ) { |
36 | 0 | s_zlib_free_dynamic_state(ss); |
37 | 0 | return ERRC; /****** WRONG ******/ |
38 | 0 | } |
39 | 156k | st->min_left=1; |
40 | 156k | return 0; |
41 | 156k | } |
42 | | |
43 | | /* Reinitialize the filter. */ |
44 | | static int |
45 | | s_zlibD_reset(stream_state * st) |
46 | 0 | { |
47 | 0 | stream_zlib_state *const ss = (stream_zlib_state *)st; |
48 | |
|
49 | 0 | if (inflateReset(&ss->dynamic->zstate) != Z_OK) |
50 | 0 | return ERRC; /****** WRONG ******/ |
51 | 0 | return 0; |
52 | 0 | } |
53 | | |
54 | | /* Process a buffer */ |
55 | | static int |
56 | | s_zlibD_process(stream_state * st, stream_cursor_read * pr, |
57 | | stream_cursor_write * pw, bool ignore_last) |
58 | 1.04M | { |
59 | 1.04M | stream_zlib_state *const ss = (stream_zlib_state *)st; |
60 | 1.04M | z_stream *zs = &ss->dynamic->zstate; |
61 | 1.04M | const byte *p = pr->ptr; |
62 | 1.04M | int status; |
63 | 1.04M | static const unsigned char jaws_empty[] = {0x58, 0x85, 1, 0, 0, 0, 0, 0, 1, 0x0A}; |
64 | | |
65 | | /* Detect no input or full output so that we don't get */ |
66 | | /* a Z_BUF_ERROR return. */ |
67 | 1.04M | if (pw->ptr == pw->limit) |
68 | 0 | return 1; |
69 | 1.04M | if (pr->ptr == pr->limit) |
70 | 153k | return 0; |
71 | 887k | zs->next_in = (Bytef *)p + 1; |
72 | 887k | zs->avail_in = pr->limit - p; |
73 | 887k | zs->next_out = pw->ptr + 1; |
74 | 887k | zs->avail_out = pw->limit - pw->ptr; |
75 | 887k | if (zs->total_in == 0 && zs->avail_in >= 10 && !memcmp(zs->next_in, jaws_empty, 10)) { |
76 | | /* JAWS PDF generator encodes empty stream as jaws_empty[]. |
77 | | * The stream declares that the data block length is zero |
78 | | * but zlib routines regard a zero length data block to be an error. |
79 | | */ |
80 | 0 | pr->ptr += 10; |
81 | 0 | return EOFC; |
82 | 0 | } |
83 | 887k | status = inflate(zs, Z_PARTIAL_FLUSH); |
84 | 887k | pr->ptr = zs->next_in - 1; |
85 | 887k | pw->ptr = zs->next_out - 1; |
86 | 887k | switch (status) { |
87 | 818k | case Z_OK: |
88 | 818k | return (pw->ptr == pw->limit ? 1 : pr->ptr > p ? 0 : 1); |
89 | 51.8k | case Z_STREAM_END: |
90 | 51.8k | return EOFC; |
91 | 16.7k | default: |
92 | 16.7k | if (zs->msg && !strcmp("incorrect data check", zs->msg)) |
93 | 5.99k | { |
94 | | /* Ignore errors when zlib streams fail on the checksum. |
95 | | * Adobe, Apple and xpdf don't fail on pdf:s where this happens, |
96 | | * so neither should we. fixes bug 688716. |
97 | | */ |
98 | 5.99k | dmprintf1(st->memory, |
99 | 5.99k | "warning: ignoring zlib error: %s\n", zs->msg); |
100 | 5.99k | return EOFC; |
101 | 5.99k | } |
102 | 10.7k | return ERRC; |
103 | 887k | } |
104 | 887k | } |
105 | | |
106 | | /* Release the stream */ |
107 | | static void |
108 | | s_zlibD_release(stream_state * st) |
109 | 156k | { |
110 | 156k | stream_zlib_state *const ss = (stream_zlib_state *)st; |
111 | | |
112 | 156k | if (ss->dynamic != NULL) |
113 | 156k | inflateEnd(&ss->dynamic->zstate); |
114 | 156k | s_zlib_free_dynamic_state(ss); |
115 | 156k | } |
116 | | |
117 | | /* Stream template */ |
118 | | const stream_template s_zlibD_template = { |
119 | | &st_zlib_state, s_zlibD_init, s_zlibD_process, 1, 1, s_zlibD_release, |
120 | | s_zlib_set_defaults, s_zlibD_reset |
121 | | }; |