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_johab.c
Line
Count
Source
1
/*-
2
 * Copyright (c)2006 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
#include "dcmtk/config/osconfig.h"
28
#include "citrus_johab.h"
29
30
#include <sys/types.h>
31
#include <errno.h>
32
#include <limits.h>
33
#include <stdbool.h>
34
#include <stddef.h>
35
#include <stdint.h>
36
#include <stdio.h>
37
#include <stdlib.h>
38
#include <string.h>
39
#include <wchar.h>
40
41
#include "citrus_bcs.h"
42
#include "citrus_types.h"
43
#include "citrus_module.h"
44
#include "citrus_stdenc.h"
45
46
/* ----------------------------------------------------------------------
47
 * private stuffs used by templates
48
 */
49
50
typedef struct {
51
    int  chlen;
52
    char     ch[2];
53
} _JOHABState;
54
55
typedef struct {
56
    int  dummy;
57
} _JOHABEncodingInfo;
58
59
#define _CEI_TO_EI(_cei_)       (&(_cei_)->ei)
60
#define _CEI_TO_STATE(_cei_, _func_)    (_cei_)->states.s_##_func_
61
62
0
#define _FUNCNAME(m)            _citrus_JOHAB_##m
63
0
#define _ENCODING_INFO          _JOHABEncodingInfo
64
#define _ENCODING_STATE         _JOHABState
65
0
#define _ENCODING_MB_CUR_MAX(_ei_)      2
66
0
#define _ENCODING_IS_STATE_DEPENDENT        0
67
#define _STATE_NEEDS_EXPLICIT_INIT(_ps_)    0
68
69
70
static __inline void
71
/*ARGSUSED*/
72
_citrus_JOHAB_init_state(_JOHABEncodingInfo * ei ,
73
    _JOHABState * psenc)
74
0
{
75
0
    (void) ei;
76
77
0
    psenc->chlen = 0;
78
0
}
79
80
#if 0
81
static __inline void
82
/*ARGSUSED*/
83
_citrus_JOHAB_pack_state(_JOHABEncodingInfo * ei ,
84
    void * pspriv, const _JOHABState * psenc)
85
{
86
    (void) ei;
87
88
    memcpy(pspriv, (const void *)psenc, sizeof(*psenc));
89
}
90
91
static __inline void
92
/*ARGSUSED*/
93
_citrus_JOHAB_unpack_state(_JOHABEncodingInfo * ei ,
94
    _JOHABState * psenc, const void * pspriv)
95
{
96
    (void) ei;
97
98
    memcpy((void *)psenc, pspriv, sizeof(*psenc));
99
}
100
#endif
101
102
static void
103
/*ARGSUSED*/
104
_citrus_JOHAB_encoding_module_uninit(_JOHABEncodingInfo *ei )
105
0
{
106
0
    (void) ei;
107
108
    /* ei may be null */
109
0
}
110
111
static int
112
/*ARGSUSED*/
113
_citrus_JOHAB_encoding_module_init(_JOHABEncodingInfo * ei ,
114
    const void * var , size_t lenvar )
115
0
{
116
0
    (void) ei;
117
0
    (void) var;
118
0
    (void) lenvar;
119
120
    /* ei may be null */
121
0
    return (0);
122
0
}
123
124
static __inline bool
125
ishangul(int l, int t)
126
0
{
127
128
0
    return ((l >= 0x84 && l <= 0xD3) &&
129
0
        ((t >= 0x41 && t <= 0x7E) || (t >= 0x81 && t <= 0xFE)));
130
0
}
131
132
static __inline bool
133
isuda(int l, int t)
134
0
{
135
136
0
    return ((l == 0xD8) &&
137
0
        ((t >= 0x31 && t <= 0x7E) || (t >= 0x91 && t <= 0xFE)));
138
0
}
139
140
static __inline bool
141
ishanja(int l, int t)
142
0
{
143
144
0
    return (((l >= 0xD9 && l <= 0xDE) || (l >= 0xE0 && l <= 0xF9)) &&
145
0
        ((t >= 0x31 && t <= 0x7E) || (t >= 0x91 && t <= 0xFE)));
146
0
}
147
148
static int
149
/*ARGSUSED*/
150
_citrus_JOHAB_mbrtowc_priv(_JOHABEncodingInfo * ei,
151
    _citrus_wc_t * pwc, char ** s, size_t n,
152
    _JOHABState * psenc, size_t * nresult)
153
0
{
154
0
    char *s0;
155
0
    int l, t;
156
157
0
    if (*s == NULL) {
158
0
        _citrus_JOHAB_init_state(ei, psenc);
159
0
        *nresult = _ENCODING_IS_STATE_DEPENDENT;
160
0
        return (0);
161
0
    }
162
0
    s0 = *s;
163
164
0
    switch (psenc->chlen) {
165
0
    case 0:
166
0
        if (n-- < 1)
167
0
            goto restart;
168
0
        l = *s0++ & 0xFF;
169
0
        if (l <= 0x7F) {
170
0
            if (pwc != NULL)
171
0
                *pwc = (_citrus_wc_t)l;
172
0
            *nresult = (l == 0) ? 0 : 1;
173
0
            *s = s0;
174
0
            return (0);
175
0
        }
176
0
        psenc->ch[psenc->chlen++] = (char) l;
177
0
        break;
178
0
    case 1:
179
0
        l = psenc->ch[0] & 0xFF;
180
0
        break;
181
0
    default:
182
0
        return (EINVAL);
183
0
    }
184
0
    if (n-- < 1) {
185
0
restart:
186
0
        *nresult = (size_t)-2;
187
0
        *s = s0;
188
0
        return (0);
189
0
    }
190
0
    t = *s0++ & 0xFF;
191
0
    if (!ishangul(l, t) && !isuda(l, t) && !ishanja(l, t)) {
192
0
        *nresult = (size_t)-1;
193
0
        return (EILSEQ);
194
0
    }
195
0
    if (pwc != NULL)
196
0
        *pwc = (_citrus_wc_t)(l << 8 | t);
197
0
    *nresult = s0 - *s;
198
0
    *s = s0;
199
0
    psenc->chlen = 0;
200
201
0
    return (0);
202
0
}
203
204
static int
205
/*ARGSUSED*/
206
_citrus_JOHAB_wcrtomb_priv(_JOHABEncodingInfo * ei ,
207
    char * s, size_t n, _citrus_wc_t wc,
208
    _JOHABState * psenc, size_t * nresult)
209
0
{
210
0
    int l, t;
211
0
    (void) ei;
212
213
0
    if (psenc->chlen != 0)
214
0
        return (EINVAL);
215
216
    /* XXX assume _citrus_wc_t as int */
217
0
    if ((uint32_t)wc <= 0x7F) {
218
0
        if (n < 1)
219
0
            goto e2big;
220
0
        *s = wc & 0xFF;
221
0
        *nresult = 1;
222
0
    } else if ((uint32_t)wc <= 0xFFFF) {
223
0
        if (n < 2) {
224
0
e2big:
225
0
            *nresult = (size_t)-1;
226
0
            return (E2BIG);
227
0
        }
228
0
        l = (wc >> 8) & 0xFF;
229
0
        t = wc & 0xFF;
230
0
        if (!ishangul(l, t) && !isuda(l, t) && !ishanja(l, t))
231
0
            goto ilseq;
232
0
        *s++ = (char) l;
233
0
        *s = (char) t;
234
0
        *nresult = 2;
235
0
    } else {
236
0
ilseq:
237
0
        *nresult = (size_t)-1;
238
0
        return (EILSEQ);
239
0
    }
240
0
    return (0);
241
242
0
}
243
244
static __inline int
245
/*ARGSUSED*/
246
_citrus_JOHAB_stdenc_wctocs(_JOHABEncodingInfo * ei ,
247
    _citrus_csid_t * csid, _citrus_index_t * idx, _citrus_wc_t wc)
248
0
{
249
0
    int m, l, linear, t;
250
0
    (void) ei;
251
252
    /* XXX assume _citrus_wc_t as int */
253
0
    if ((uint32_t)wc <= 0x7F) {
254
0
        *idx = (_citrus_index_t)wc;
255
0
        *csid = 0;
256
0
    } else if ((uint32_t)wc <= 0xFFFF) {
257
0
        l = (wc >> 8) & 0xFF;
258
0
        t = wc & 0xFF;
259
0
        if (ishangul(l, t) || isuda(l, t)) {
260
0
            *idx = (_citrus_index_t)wc;
261
0
            *csid = 1;
262
0
        } else {
263
0
            if (l >= 0xD9 && l <= 0xDE) {
264
0
                linear = l - 0xD9;
265
0
                m = 0x21;
266
0
            } else if (l >= 0xE0 && l <= 0xF9) {
267
0
                linear = l - 0xE0;
268
0
                m = 0x4A;
269
0
            } else
270
0
                return (EILSEQ);
271
0
            linear *= 188;
272
0
            if (t >= 0x31 && t <= 0x7E)
273
0
                linear += t - 0x31;
274
0
            else if (t >= 0x91 && t <= 0xFE)
275
0
                linear += t - 0x43;
276
0
            else
277
0
                return (EILSEQ);
278
0
            l = (linear / 94) + m;
279
0
            t = (linear % 94) + 0x21;
280
0
            *idx = (_citrus_index_t)((l << 8) | t);
281
0
            *csid = 2;
282
0
        }
283
0
    } else
284
0
        return (EILSEQ);
285
0
    return (0);
286
0
}
287
288
static __inline int
289
/*ARGSUSED*/
290
_citrus_JOHAB_stdenc_cstowc(_JOHABEncodingInfo * ei ,
291
    _citrus_wc_t * wc, _citrus_csid_t csid, _citrus_index_t idx)
292
0
{
293
0
    int m, n, l, linear, t;
294
0
    (void) ei;
295
296
0
    switch (csid) {
297
0
    case 0:
298
0
    case 1:
299
0
        *wc = (_citrus_wc_t)idx;
300
0
        break;
301
0
    case 2:
302
0
        if (idx >= 0x2121 && idx <= 0x2C71) {
303
0
            m = 0xD9;
304
0
            n = 0x21;
305
0
        } else if (idx >= 0x4A21 && idx <= 0x7D7E) {
306
0
            m = 0xE0;
307
0
            n = 0x4A;
308
0
        } else
309
0
            return (EILSEQ);
310
0
        l = ((idx >> 8) & 0xFF) - n;
311
0
        t = (idx & 0xFF) - 0x21;
312
0
        linear = (l * 94) + t;
313
0
        l = (linear / 188) + m;
314
0
        t = linear % 188;
315
0
        t += (t <= 0x4D) ? 0x31 : 0x43;
316
0
        break;
317
0
    default:
318
0
        return (EILSEQ);
319
0
    }
320
0
    return (0);
321
0
}
322
323
static __inline int
324
/*ARGSUSED*/
325
_citrus_JOHAB_stdenc_get_state_desc_generic(_JOHABEncodingInfo * ei ,
326
    _JOHABState * psenc, int * rstate)
327
0
{
328
0
    (void) ei;
329
330
0
    *rstate = (psenc->chlen == 0) ? _CITRUS_STDENC_SDGEN_INITIAL :
331
0
        _CITRUS_STDENC_SDGEN_INCOMPLETE_CHAR;
332
0
    return (0);
333
0
}
334
335
/* ----------------------------------------------------------------------
336
 * public interface for stdenc
337
 */
338
339
_CITRUS_STDENC_DECLS(JOHAB);
340
_CITRUS_STDENC_DEF_OPS(JOHAB);
341
342
#include "citrus_stdenc_template.h"