Coverage Report

Created: 2026-09-28 07:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/dcmtk/oficonv/libsrc/citrus_euctw.c
Line
Count
Source
1
/*-
2
 * Copyright (c)2002 Citrus Project,
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
7
 * are met:
8
 * 1. Redistributions of source code must retain the above copyright
9
 *    notice, this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright
11
 *    notice, this list of conditions and the following disclaimer in the
12
 *    documentation and/or other materials provided with the distribution.
13
 *
14
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24
 * SUCH DAMAGE.
25
 */
26
27
/*-
28
 * Copyright (c)1999 Citrus Project,
29
 * All rights reserved.
30
 *
31
 * Redistribution and use in source and binary forms, with or without
32
 * modification, are permitted provided that the following conditions
33
 * are met:
34
 * 1. Redistributions of source code must retain the above copyright
35
 *    notice, this list of conditions and the following disclaimer.
36
 * 2. Redistributions in binary form must reproduce the above copyright
37
 *    notice, this list of conditions and the following disclaimer in the
38
 *    documentation and/or other materials provided with the distribution.
39
 *
40
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
41
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50
 * SUCH DAMAGE.
51
 *
52
 */
53
54
#include "dcmtk/config/osconfig.h"
55
#include "citrus_euctw.h"
56
57
#include <sys/types.h>
58
#include <errno.h>
59
#include <limits.h>
60
#include <stddef.h>
61
#include <stdio.h>
62
#include <stdlib.h>
63
#include <string.h>
64
#include <wchar.h>
65
66
#include "citrus_bcs.h"
67
#include "citrus_types.h"
68
#include "citrus_module.h"
69
#include "citrus_stdenc.h"
70
71
72
/* ----------------------------------------------------------------------
73
 * private stuffs used by templates
74
 */
75
76
typedef struct {
77
    int  chlen;
78
    char     ch[4];
79
} _EUCTWState;
80
81
typedef struct {
82
    int  dummy;
83
} _EUCTWEncodingInfo;
84
85
0
#define _SS2    0x008e
86
#define _SS3    0x008f
87
88
#define _CEI_TO_EI(_cei_)       (&(_cei_)->ei)
89
#define _CEI_TO_STATE(_cei_, _func_)    (_cei_)->states.s_##_func_
90
91
0
#define _FUNCNAME(m)            _citrus_EUCTW_##m
92
0
#define _ENCODING_INFO          _EUCTWEncodingInfo
93
#define _ENCODING_STATE         _EUCTWState
94
0
#define _ENCODING_MB_CUR_MAX(_ei_)  4
95
#define _ENCODING_IS_STATE_DEPENDENT    0
96
#define _STATE_NEEDS_EXPLICIT_INIT(_ps_)    0
97
98
static __inline int
99
_citrus_EUCTW_cs(unsigned int c)
100
0
{
101
102
0
    c &= 0xff;
103
104
0
    return ((c & 0x80) ? (c == _SS2 ? 2 : 1) : 0);
105
0
}
106
107
static __inline int
108
_citrus_EUCTW_count(int cs)
109
0
{
110
111
0
    switch (cs) {
112
0
    case 0:
113
        /*FALLTHROUGH*/
114
0
    case 1:
115
        /*FALLTHROUGH*/
116
0
    case 2:
117
0
        return (1 << cs);
118
0
    case 3:
119
0
        abort();
120
        /*NOTREACHED*/
121
0
    }
122
0
    return (0);
123
0
}
124
125
static __inline void
126
/*ARGSUSED*/
127
_citrus_EUCTW_init_state(_EUCTWEncodingInfo * ei ,
128
    _EUCTWState * s)
129
0
{
130
0
    (void) ei;
131
0
    memset(s, 0, sizeof(*s));
132
0
}
133
134
static int
135
/*ARGSUSED*/
136
_citrus_EUCTW_encoding_module_init(_EUCTWEncodingInfo * ei,
137
    const void * var , size_t lenvar )
138
0
{
139
0
    (void) var;
140
0
    (void) lenvar;
141
0
    memset((void *)ei, 0, sizeof(*ei));
142
143
0
    return (0);
144
0
}
145
146
static void
147
/*ARGSUSED*/
148
_citrus_EUCTW_encoding_module_uninit(_EUCTWEncodingInfo *ei )
149
0
{
150
0
    (void) ei;
151
0
}
152
153
static int
154
_citrus_EUCTW_mbrtowc_priv(_EUCTWEncodingInfo * ei,
155
    _citrus_wc_t * pwc, char ** s,
156
    size_t n, _EUCTWState * psenc, size_t * nresult)
157
0
{
158
0
    char *s0;
159
0
    _citrus_wc_t wchar;
160
0
    int c, chlenbak, cs;
161
162
0
    s0 = *s;
163
164
0
    if (s0 == NULL) {
165
0
        _citrus_EUCTW_init_state(ei, psenc);
166
0
        *nresult = 0; /* state independent */
167
0
        return (0);
168
0
    }
169
170
0
    chlenbak = psenc->chlen;
171
172
    /* make sure we have the first byte in the buffer */
173
0
    switch (psenc->chlen) {
174
0
    case 0:
175
0
        if (n < 1)
176
0
            goto restart;
177
0
        psenc->ch[0] = *s0++;
178
0
        psenc->chlen = 1;
179
0
        n--;
180
0
        break;
181
0
    case 1:
182
0
    case 2:
183
0
        break;
184
0
    default:
185
        /* illgeal state */
186
0
        goto ilseq;
187
0
    }
188
189
0
    c = _citrus_EUCTW_count(cs = _citrus_EUCTW_cs(psenc->ch[0] & 0xff));
190
0
    if (c == 0)
191
0
        goto ilseq;
192
0
    while (psenc->chlen < c) {
193
0
        if (n < 1)
194
0
            goto ilseq;
195
0
        psenc->ch[psenc->chlen] = *s0++;
196
0
        psenc->chlen++;
197
0
        n--;
198
0
    }
199
200
0
    wchar = 0;
201
0
    switch (cs) {
202
0
    case 0:
203
0
        if (psenc->ch[0] & 0x80)
204
0
            goto ilseq;
205
0
        wchar = psenc->ch[0] & 0xff;
206
0
        break;
207
0
    case 1:
208
0
        if (!(psenc->ch[0] & 0x80) || !(psenc->ch[1] & 0x80))
209
0
            goto ilseq;
210
0
        wchar = ((psenc->ch[0] & 0xff) << 8) | (psenc->ch[1] & 0xff);
211
0
        wchar |= 'G' << 24;
212
0
        break;
213
0
    case 2:
214
0
        if ((unsigned char)psenc->ch[1] < 0xa1 ||
215
0
            0xa7 < (unsigned char)psenc->ch[1])
216
0
            goto ilseq;
217
0
        if (!(psenc->ch[2] & 0x80) || !(psenc->ch[3] & 0x80))
218
0
            goto ilseq;
219
0
        wchar = ((psenc->ch[2] & 0xff) << 8) | (psenc->ch[3] & 0xff);
220
0
        wchar |= ('G' + psenc->ch[1] - 0xa1) << 24;
221
0
        break;
222
0
    default:
223
0
        goto ilseq;
224
0
    }
225
226
0
    *s = s0;
227
0
    psenc->chlen = 0;
228
229
0
    if (pwc)
230
0
        *pwc = wchar;
231
0
    *nresult = wchar ? c - chlenbak : 0;
232
0
    return (0);
233
234
0
ilseq:
235
0
    psenc->chlen = 0;
236
0
    *nresult = (size_t)-1;
237
0
    return (EILSEQ);
238
239
0
restart:
240
0
    *s = s0;
241
0
    *nresult = (size_t)-1;
242
0
    return (0);
243
0
}
244
245
static int
246
_citrus_EUCTW_wcrtomb_priv(_EUCTWEncodingInfo * ei ,
247
    char * s, size_t n, _citrus_wc_t wc,
248
    _EUCTWState * psenc , size_t * nresult)
249
0
{
250
0
    _citrus_wc_t cs, v;
251
0
    int clen, i, ret;
252
0
    size_t len;
253
0
    (void) ei;
254
0
    (void) psenc;
255
256
0
    cs = wc & 0x7f000080;
257
0
    clen = 1;
258
0
    if (wc & 0x00007f00)
259
0
        clen = 2;
260
0
    if ((wc & 0x007f0000) && !(wc & 0x00800000))
261
0
        clen = 3;
262
263
0
    if (clen == 1 && cs == 0x00000000) {
264
        /* ASCII */
265
0
        len = 1;
266
0
        if (n < len) {
267
0
            ret = E2BIG;
268
0
            goto err;
269
0
        }
270
0
        v = wc & 0x0000007f;
271
0
    } else if (clen == 2 && cs == ('G' << 24)) {
272
        /* CNS-11643-1 */
273
0
        len = 2;
274
0
        if (n < len) {
275
0
            ret = E2BIG;
276
0
            goto err;
277
0
        }
278
0
        v = wc & 0x00007f7f;
279
0
        v |= 0x00008080;
280
0
    } else if (clen == 2 && 'H' <= (cs >> 24) && (cs >> 24) <= 'M') {
281
        /* CNS-11643-[2-7] */
282
0
        len = 4;
283
0
        if (n < len) {
284
0
            ret = E2BIG;
285
0
            goto err;
286
0
        }
287
0
        *s++ = _SS2;
288
0
        *s++ = (cs >> 24) - 'H' + 0xa2;
289
0
        v = wc & 0x00007f7f;
290
0
        v |= 0x00008080;
291
0
    } else {
292
0
        ret = EILSEQ;
293
0
        goto err;
294
0
    }
295
296
0
    i = clen;
297
0
    while (i-- > 0)
298
0
        *s++ = (v >> (i << 3)) & 0xff;
299
300
0
    *nresult = len;
301
0
    return (0);
302
303
0
err:
304
0
    *nresult = (size_t)-1;
305
0
    return (ret);
306
0
}
307
308
static __inline int
309
/*ARGSUSED*/
310
_citrus_EUCTW_stdenc_wctocs(_EUCTWEncodingInfo * ei ,
311
    _citrus_csid_t * csid, _citrus_index_t * idx, _citrus_wc_t wc)
312
0
{
313
0
    (void) ei;
314
315
0
    *csid = (_citrus_csid_t)(wc >> 24) & 0xFF;
316
0
    *idx  = (_citrus_index_t)(wc & 0x7F7F);
317
318
0
    return (0);
319
0
}
320
321
static __inline int
322
/*ARGSUSED*/
323
_citrus_EUCTW_stdenc_cstowc(_EUCTWEncodingInfo * ei ,
324
    _citrus_wc_t * wc, _citrus_csid_t csid, _citrus_index_t idx)
325
0
{
326
0
    (void) ei;
327
328
0
    if (csid == 0) {
329
0
        if ((idx & ~0x7F) != 0)
330
0
            return (EINVAL);
331
0
        *wc = (_citrus_wc_t)idx;
332
0
    } else {
333
0
        if (csid < 'G' || csid > 'M' || (idx & ~0x7F7F) != 0)
334
0
            return (EINVAL);
335
0
        *wc = (_citrus_wc_t)idx | ((_citrus_wc_t)csid << 24);
336
0
    }
337
338
0
    return (0);
339
0
}
340
341
static __inline int
342
/*ARGSUSED*/
343
_citrus_EUCTW_stdenc_get_state_desc_generic(_EUCTWEncodingInfo * ei ,
344
    _EUCTWState * psenc, int * rstate)
345
0
{
346
0
    (void) ei;
347
348
0
    *rstate = (psenc->chlen == 0) ? _CITRUS_STDENC_SDGEN_INITIAL :
349
0
        _CITRUS_STDENC_SDGEN_INCOMPLETE_CHAR;
350
0
    return (0);
351
0
}
352
353
/* ----------------------------------------------------------------------
354
 * public interface for stdenc
355
 */
356
357
_CITRUS_STDENC_DECLS(EUCTW);
358
_CITRUS_STDENC_DEF_OPS(EUCTW);
359
360
#include "citrus_stdenc_template.h"