/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 | 2.13M | { |
27 | 2.13M | stream_zlib_state *const ss = (stream_zlib_state *)st; |
28 | 2.13M | int code = s_zlib_alloc_dynamic_state(ss); |
29 | | |
30 | 2.13M | if (code < 0) |
31 | 0 | return ERRC; /****** WRONG ******/ |
32 | 2.13M | if (inflateInit2(&ss->dynamic->zstate, |
33 | 2.13M | (ss->no_wrapper ? -ss->windowBits : ss->windowBits)) |
34 | 2.13M | != Z_OK |
35 | 2.13M | ) { |
36 | 0 | s_zlib_free_dynamic_state(ss); |
37 | 0 | return ERRC; /****** WRONG ******/ |
38 | 0 | } |
39 | 2.13M | st->min_left=1; |
40 | 2.13M | return 0; |
41 | 2.13M | } |
42 | | |
43 | | /* Reinitialize the filter. */ |
44 | | static int |
45 | | s_zlibD_reset(stream_state * st) |
46 | 18 | { |
47 | 18 | stream_zlib_state *const ss = (stream_zlib_state *)st; |
48 | | |
49 | 18 | if (inflateReset(&ss->dynamic->zstate) != Z_OK) |
50 | 0 | return ERRC; /****** WRONG ******/ |
51 | 18 | return 0; |
52 | 18 | } |
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 | 17.8M | { |
59 | 17.8M | stream_zlib_state *const ss = (stream_zlib_state *)st; |
60 | 17.8M | z_stream *zs = &ss->dynamic->zstate; |
61 | 17.8M | const byte *p = pr->ptr; |
62 | 17.8M | int status; |
63 | 17.8M | 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 | 17.8M | if (pw->ptr == pw->limit) |
68 | 0 | return 1; |
69 | 17.8M | if (pr->ptr == pr->limit) |
70 | 2.09M | return 0; |
71 | 15.7M | zs->next_in = (Bytef *)p + 1; |
72 | 15.7M | zs->avail_in = pr->limit - p; |
73 | 15.7M | zs->next_out = pw->ptr + 1; |
74 | 15.7M | zs->avail_out = pw->limit - pw->ptr; |
75 | 15.7M | 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 | 15.7M | status = inflate(zs, Z_PARTIAL_FLUSH); |
84 | 15.7M | pr->ptr = zs->next_in - 1; |
85 | 15.7M | pw->ptr = zs->next_out - 1; |
86 | 15.7M | switch (status) { |
87 | 14.6M | case Z_OK: |
88 | 14.6M | return (pw->ptr == pw->limit ? 1 : pr->ptr > p ? 0 : 1); |
89 | 789k | case Z_STREAM_END: |
90 | 789k | return EOFC; |
91 | 315k | default: |
92 | 315k | if (zs->msg && !strcmp("incorrect data check", zs->msg)) |
93 | 108k | { |
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 | 108k | dmprintf1(st->memory, |
99 | 108k | "warning: ignoring zlib error: %s\n", zs->msg); |
100 | 108k | return EOFC; |
101 | 108k | } |
102 | 206k | return ERRC; |
103 | 15.7M | } |
104 | 15.7M | } |
105 | | |
106 | | /* Release the stream */ |
107 | | static void |
108 | | s_zlibD_release(stream_state * st) |
109 | 2.13M | { |
110 | 2.13M | stream_zlib_state *const ss = (stream_zlib_state *)st; |
111 | | |
112 | 2.13M | if (ss->dynamic != NULL) |
113 | 2.13M | inflateEnd(&ss->dynamic->zstate); |
114 | 2.13M | s_zlib_free_dynamic_state(ss); |
115 | 2.13M | } |
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 | | }; |