Coverage Report

Created: 2022-10-31 07:00

/src/ghostpdl/base/sbcp.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2021 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
17
/* BCP and TBCP filters */
18
#include "stdio_.h"
19
#include "strimpl.h"
20
#include "sbcp.h"
21
22
327
#define CtrlA 0x01
23
1.33k
#define CtrlC 0x03
24
49
#define CtrlD 0x04
25
218
#define CtrlE 0x05
26
282
#define CtrlQ 0x11
27
517
#define CtrlS 0x13
28
439
#define CtrlT 0x14
29
#define ESC 0x1b
30
466
#define CtrlBksl 0x1c
31
32
/* The following is not used yet. */
33
/*static const char *TBCP_end_protocol_string = "\033%-12345X";*/
34
35
/* ------ BCPEncode and TBCPEncode ------ */
36
37
/* Process a buffer */
38
static int
39
s_xBCPE_process(stream_state * st, stream_cursor_read * pr,
40
                stream_cursor_write * pw, bool last, const byte * escaped)
41
0
{
42
0
    const byte *p = pr->ptr;
43
0
    const byte *rlimit = pr->limit;
44
0
    uint rcount = rlimit - p;
45
0
    byte *q = pw->ptr;
46
0
    uint wcount = pw->limit - q;
47
0
    const byte *end = p + min(rcount, wcount);
48
49
0
    while (p < end) {
50
0
        byte ch = *++p;
51
52
0
        if (ch <= 31 && escaped[ch]) {
53
0
            if (p == rlimit) {
54
0
                p--;
55
0
                break;
56
0
            }
57
0
            *++q = CtrlA;
58
0
            ch ^= 0x40;
59
0
            if (--wcount < rcount)
60
0
                end--;
61
0
        }
62
0
        *++q = ch;
63
0
    }
64
0
    pr->ptr = p;
65
0
    pw->ptr = q;
66
0
    return (p == rlimit ? 0 : 1);
67
0
}
68
69
/* Actual process procedures */
70
static int
71
s_BCPE_process(stream_state * st, stream_cursor_read * pr,
72
               stream_cursor_write * pw, bool last)
73
0
{
74
0
    static const byte escaped[32] =
75
0
    {
76
0
        0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
77
0
        0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0
78
0
    };
79
80
0
    return s_xBCPE_process(st, pr, pw, last, escaped);
81
0
}
82
static int
83
s_TBCPE_process(stream_state * st, stream_cursor_read * pr,
84
                stream_cursor_write * pw, bool last)
85
0
{
86
0
    static const byte escaped[32] =
87
0
    {
88
0
        0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
89
0
        0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0
90
0
    };
91
92
0
    return s_xBCPE_process(st, pr, pw, last, escaped);
93
0
}
94
95
/* Stream templates */
96
const stream_template s_BCPE_template =
97
{&st_stream_state, NULL, s_BCPE_process, 1, 2
98
};
99
const stream_template s_TBCPE_template =
100
{&st_stream_state, NULL, s_TBCPE_process, 1, 2
101
};
102
103
/* ------ BCPDecode and TBCPDecode ------ */
104
105
private_st_BCPD_state();
106
107
/* Initialize the state */
108
static int
109
s_BCPD_init(stream_state * st)
110
290
{
111
290
    stream_BCPD_state *const ss = (stream_BCPD_state *) st;
112
113
290
    ss->escaped = 0;
114
290
    ss->matched = ss->copy_count = 0;
115
290
    return 0;
116
290
}
117
118
/* Process a buffer */
119
static int
120
s_xBCPD_process(stream_state * st, stream_cursor_read * pr,
121
                stream_cursor_write * pw, bool last, bool tagged)
122
1.38k
{
123
1.38k
    stream_BCPD_state *const ss = (stream_BCPD_state *) st;
124
1.38k
    const byte *p = pr->ptr;
125
1.38k
    const byte *rlimit = pr->limit;
126
1.38k
    byte *q = pw->ptr;
127
1.38k
    byte *wlimit = pw->limit;
128
1.38k
    int copy_count = ss->copy_count;
129
1.38k
    int status;
130
1.38k
    bool escaped = ss->escaped;
131
132
762k
    for (;;) {
133
762k
        byte ch;
134
135
762k
        if (copy_count) {
136
0
            if (q == wlimit) {
137
0
                status = (p < rlimit ? 1 : 0);
138
0
                break;
139
0
            }
140
0
            *++q = *++(ss->copy_ptr);
141
0
            copy_count--;
142
0
            continue;
143
0
        }
144
762k
        if (p == rlimit) {
145
983
            status = 0;
146
983
            break;
147
983
        }
148
761k
        ch = *++p;
149
761k
        if (ch <= 31)
150
22.9k
            switch (ch) {
151
327
                case CtrlA:
152
327
                    if (escaped) {
153
11
                        status = ERRC;
154
11
                        goto out;
155
11
                    }
156
316
                    escaped = true;
157
316
                    continue;
158
1.33k
                case CtrlC:
159
1.33k
                    status = (*ss->signal_interrupt) (st);
160
1.33k
                    if (status < 0)
161
0
                        goto out;
162
1.33k
                    continue;
163
1.33k
                case CtrlD:
164
49
                    if (escaped) {
165
3
                        status = ERRC;
166
3
                        goto out;
167
3
                    }
168
46
                    status = EOFC;
169
46
                    goto out;
170
218
                case CtrlE:
171
218
                    continue;
172
282
                case CtrlQ:
173
282
                    continue;
174
517
                case CtrlS:
175
517
                    continue;
176
439
                case CtrlT:
177
439
                    status = (*ss->request_status) (st);
178
439
                    if (status < 0)
179
0
                        goto out;
180
439
                    continue;
181
466
                case CtrlBksl:
182
466
                    continue;
183
22.9k
            }
184
757k
        if (q == wlimit) {
185
266
            p--;
186
266
            status = 1;
187
266
            break;
188
266
        }
189
757k
        if (escaped) {
190
296
            escaped = false;
191
296
            switch (ch) {
192
41
                case '[':
193
41
                    if (!tagged) {
194
0
                        status = ERRC;
195
0
                        goto out;
196
0
                    }
197
                    /* falls through */
198
45
                case 'A':
199
46
                case 'C':
200
46
                case 'D':
201
46
                case 'E':
202
46
                case 'Q':
203
46
                case 'S':
204
46
                case 'T':
205
60
                case '\\':
206
60
                    ch ^= 0x40;
207
60
                    break;
208
162
                case 'M':
209
162
                    if (!tagged) {
210
0
                        status = ERRC;
211
0
                        goto out;
212
0
                    }
213
162
                    continue;
214
162
                default:
215
74
                    status = ERRC;
216
74
                    goto out;
217
296
            }
218
296
        }
219
757k
        *++q = ch;
220
757k
    }
221
1.38k
  out:ss->copy_count = copy_count;
222
1.38k
    ss->escaped = escaped;
223
1.38k
    pr->ptr = p;
224
1.38k
    pw->ptr = q;
225
1.38k
    return status;
226
1.38k
}
227
228
/* Actual process procedures */
229
static int
230
s_BCPD_process(stream_state * st, stream_cursor_read * pr,
231
               stream_cursor_write * pw, bool last)
232
0
{
233
0
    return s_xBCPD_process(st, pr, pw, last, false);
234
0
}
235
static int
236
s_TBCPD_process(stream_state * st, stream_cursor_read * pr,
237
                stream_cursor_write * pw, bool last)
238
1.38k
{
239
1.38k
    return s_xBCPD_process(st, pr, pw, last, true);
240
1.38k
}
241
242
/* Stream templates */
243
const stream_template s_BCPD_template =
244
{&st_BCPD_state, s_BCPD_init, s_BCPD_process, 1, 1,
245
 NULL, NULL, s_BCPD_init
246
};
247
const stream_template s_TBCPD_template =
248
{&st_BCPD_state, s_BCPD_init, s_TBCPD_process, 1, 1,
249
 NULL, NULL, s_BCPD_init
250
};