~ubuntu-branches/ubuntu/wily/libxml2/wily-proposed

« back to all changes in this revision

Viewing changes to os400/iconv/iconv.c

  • Committer: Package Import Robot
  • Author(s): Aron Xu
  • Date: 2014-10-26 07:04:50 UTC
  • mfrom: (43.2.7 sid)
  • Revision ID: package-import@ubuntu.com-20141026070450-rmcqvcqn8peeuebs
Tags: 2.9.2+dfsg1-1
* New upstream release (Closes: #765722, CVE-2014-3660)
* Remove no-longer-needed upstream patches
* Update distro patch
* Std-ver: 3.9.5 -> 3.9.6, no change.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
***     iconv_open(), iconv(), iconv_close() wrappers for the OS/400.
 
3
***
 
4
***     See Copyright for the status of this software.
 
5
***
 
6
***     Author: Patrick Monnerat <pm@datasphere.ch>, DATASPHERE S.A.
 
7
**/
 
8
 
 
9
#include <errno.h>
 
10
#include <stdio.h>
 
11
#include <stdlib.h>
 
12
 
 
13
#include "/QIBM/include/iconv.h"        /* Force system definition. */
 
14
 
 
15
#define USE_SYSTEM_ICONV
 
16
#include "iconv.h"                      /* Use local definitions. */
 
17
 
 
18
 
 
19
 
 
20
/**
 
21
***     Bring-in the name-->CCSID mapping DFA tables.
 
22
**/
 
23
 
 
24
#include "ianatables.c"
 
25
 
 
26
 
 
27
 
 
28
static int
 
29
findEncoding(const unsigned char * * namep)
 
30
 
 
31
{
 
32
        t_staterange curstate;
 
33
        t_ccsid ccsid;
 
34
        t_ccsid final;
 
35
        t_transrange l;
 
36
        t_transrange h;
 
37
        const unsigned char * name;
 
38
 
 
39
        /**
 
40
        ***     Get the CCSID correspong to the name at *`namep'.
 
41
        ***     If success, update pointer at `namep' to 1st byte after matched
 
42
        ***             name and return the CCSID.
 
43
        ***     If failure, set errno and return -1.
 
44
        **/
 
45
 
 
46
        if (!namep || !(name = *namep)) {
 
47
                errno = EINVAL;
 
48
                return -1;
 
49
                }
 
50
 
 
51
        curstate = 0;
 
52
        final = 0;
 
53
 
 
54
        for (;;) {
 
55
                if (curstate < sizeof final_array / sizeof final_array[0])
 
56
                        if (final_array[curstate]) {
 
57
                                final = final_array[curstate];
 
58
                                *namep = name;
 
59
                                }
 
60
 
 
61
                l = trans_array[curstate] - 1;
 
62
                h = trans_array[curstate + 1];
 
63
 
 
64
                do {
 
65
                        if (++l >= h) {
 
66
                                if (!final) {
 
67
                                        errno = EINVAL;
 
68
                                        return -1;
 
69
                                        }
 
70
 
 
71
                                return final - 1;
 
72
                                }
 
73
                } while (label_array[l] != *name);
 
74
 
 
75
                curstate = goto_array[l];
 
76
                name++;
 
77
                }
 
78
 
 
79
        /* NOTREACHED. */
 
80
}
 
81
 
 
82
 
 
83
static void
 
84
makeos400codename(char * buf, unsigned int ccsid)
 
85
 
 
86
{
 
87
        ccsid &= 0xFFFF;
 
88
        memset(buf, 0, 32);
 
89
        sprintf(buf, "IBMCCSID%05u0000000", ccsid);
 
90
}
 
91
 
 
92
 
 
93
Iconv_t
 
94
IconvOpen(const char * tocode, const char * fromcode)
 
95
 
 
96
{
 
97
        int toccsid = findEncoding(&tocode);
 
98
        int fromccsid = findEncoding(&fromcode);
 
99
        char fromibmccsid[33];
 
100
        char toibmccsid[33];
 
101
        iconv_t * cd;
 
102
 
 
103
        if (toccsid < 0 || fromccsid < 0)
 
104
                return (Iconv_t) -1;
 
105
 
 
106
        makeos400codename(fromibmccsid, fromccsid);
 
107
        makeos400codename(toibmccsid, toccsid);
 
108
        memset(toibmccsid + 13, 0, sizeof toibmccsid - 13);
 
109
 
 
110
        cd = (iconv_t *) malloc(sizeof *cd);
 
111
 
 
112
        if (!cd)
 
113
                return (Iconv_t) -1;
 
114
 
 
115
        *cd = iconv_open(toibmccsid, fromibmccsid);
 
116
 
 
117
        if (cd->return_value) {
 
118
                free((char *) cd);
 
119
                return (Iconv_t) -1;
 
120
                }
 
121
 
 
122
        return (Iconv_t) cd;
 
123
}
 
124
 
 
125
 
 
126
size_t
 
127
Iconv(Iconv_t cd, char * * inbuf, size_t * inbytesleft,
 
128
                                        char * * outbuf, size_t * outbytesleft)
 
129
 
 
130
{
 
131
        if (!cd || cd == (Iconv_t) -1) {
 
132
                errno = EINVAL;
 
133
                return (size_t) -1;
 
134
                }
 
135
 
 
136
        return iconv(*(iconv_t *) cd, inbuf, inbytesleft, outbuf, outbytesleft);
 
137
}
 
138
 
 
139
 
 
140
int
 
141
IconvClose(Iconv_t cd)
 
142
 
 
143
{
 
144
        if (!cd || cd == (Iconv_t) -1) {
 
145
                errno = EINVAL;
 
146
                return -1;
 
147
                }
 
148
 
 
149
        if (iconv_close(*(iconv_t *) cd))
 
150
                return -1;
 
151
 
 
152
        free((char *) cd);
 
153
        return 0;
 
154
}