~ubuntu-branches/ubuntu/feisty/apache2/feisty

« back to all changes in this revision

Viewing changes to srclib/apr-util/encoding/apr_base64.c

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Barth
  • Date: 2006-12-09 21:05:45 UTC
  • mfrom: (0.6.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20061209210545-h70s0xaqc2v8vqr2
Tags: 2.2.3-3.2
* Non-maintainer upload.
* 043_ajp_connection_reuse: Patch from upstream Bugzilla, fixing a critical
  issue with regard to connection reuse in mod_proxy_ajp.
  Closes: #396265

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as
 
2
 * applicable.
 
3
 *
 
4
 * Licensed under the Apache License, Version 2.0 (the "License");
 
5
 * you may not use this file except in compliance with the License.
 
6
 * You may obtain a copy of the License at
 
7
 *
 
8
 *     http://www.apache.org/licenses/LICENSE-2.0
 
9
 *
 
10
 * Unless required by applicable law or agreed to in writing, software
 
11
 * distributed under the License is distributed on an "AS IS" BASIS,
 
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
13
 * See the License for the specific language governing permissions and
 
14
 * limitations under the License.
 
15
 */
 
16
 
 
17
/* base64 encoder/decoder. Originally part of main/util.c
 
18
 * but moved here so that support/ab and apr_sha1.c could
 
19
 * use it. This meant removing the apr_palloc()s and adding
 
20
 * ugly 'len' functions, which is quite a nasty cost.
 
21
 */
 
22
 
 
23
#include "apr_base64.h"
 
24
#if APR_CHARSET_EBCDIC
 
25
#include "apr_xlate.h"
 
26
#endif                          /* APR_CHARSET_EBCDIC */
 
27
 
 
28
/* aaaack but it's fast and const should make it shared text page. */
 
29
static const unsigned char pr2six[256] =
 
30
{
 
31
#if !APR_CHARSET_EBCDIC
 
32
    /* ASCII table */
 
33
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
 
34
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
 
35
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63,
 
36
    52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64,
 
37
    64,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
 
38
    15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64,
 
39
    64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
 
40
    41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64,
 
41
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
 
42
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
 
43
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
 
44
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
 
45
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
 
46
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
 
47
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
 
48
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
 
49
#else /*APR_CHARSET_EBCDIC*/
 
50
    /* EBCDIC table */
 
51
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
 
52
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
 
53
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
 
54
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
 
55
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64,
 
56
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
 
57
    64, 63, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
 
58
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
 
59
    64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 64, 64, 64, 64, 64, 64,
 
60
    64, 35, 36, 37, 38, 39, 40, 41, 42, 43, 64, 64, 64, 64, 64, 64,
 
61
    64, 64, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64, 64,
 
62
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
 
63
    64,  0,  1,  2,  3,  4,  5,  6,  7,  8, 64, 64, 64, 64, 64, 64,
 
64
    64,  9, 10, 11, 12, 13, 14, 15, 16, 17, 64, 64, 64, 64, 64, 64,
 
65
    64, 64, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64, 64,
 
66
    52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64
 
67
#endif /*APR_CHARSET_EBCDIC*/
 
68
};
 
69
 
 
70
#if APR_CHARSET_EBCDIC
 
71
static apr_xlate_t *xlate_to_ebcdic;
 
72
static unsigned char os_toascii[256];
 
73
 
 
74
APU_DECLARE(apr_status_t) apr_base64init_ebcdic(apr_xlate_t *to_ascii,
 
75
                                             apr_xlate_t *to_ebcdic)
 
76
{
 
77
    int i;
 
78
    apr_size_t inbytes_left, outbytes_left;
 
79
    apr_status_t rv;
 
80
    int onoff;
 
81
    
 
82
    /* Only single-byte conversion is supported.
 
83
     */
 
84
    rv = apr_xlate_sb_get(to_ascii, &onoff);
 
85
    if (rv) {
 
86
        return rv;
 
87
    }
 
88
    if (!onoff) { /* If conversion is not single-byte-only */
 
89
        return APR_EINVAL;
 
90
    }
 
91
    rv = apr_xlate_sb_get(to_ebcdic, &onoff);
 
92
    if (rv) {
 
93
        return rv;
 
94
    }
 
95
    if (!onoff) { /* If conversion is not single-byte-only */
 
96
        return APR_EINVAL;
 
97
    }
 
98
    xlate_to_ebcdic = to_ebcdic;
 
99
    for (i = 0; i < sizeof(os_toascii); i++) {
 
100
        os_toascii[i] = i;
 
101
    }
 
102
    inbytes_left = outbytes_left = sizeof(os_toascii);
 
103
    apr_xlate_conv_buffer(to_ascii, os_toascii, &inbytes_left,
 
104
                          os_toascii, &outbytes_left);
 
105
 
 
106
    return APR_SUCCESS;
 
107
}
 
108
#endif /*APR_CHARSET_EBCDIC*/
 
109
 
 
110
APU_DECLARE(int) apr_base64_decode_len(const char *bufcoded)
 
111
{
 
112
    int nbytesdecoded;
 
113
    register const unsigned char *bufin;
 
114
    register int nprbytes;
 
115
 
 
116
    bufin = (const unsigned char *) bufcoded;
 
117
    while (pr2six[*(bufin++)] <= 63);
 
118
 
 
119
    nprbytes = (bufin - (const unsigned char *) bufcoded) - 1;
 
120
    nbytesdecoded = ((nprbytes + 3) / 4) * 3;
 
121
 
 
122
    return nbytesdecoded + 1;
 
123
}
 
124
 
 
125
APU_DECLARE(int) apr_base64_decode(char *bufplain, const char *bufcoded)
 
126
{
 
127
#if APR_CHARSET_EBCDIC
 
128
    apr_size_t inbytes_left, outbytes_left;
 
129
#endif                          /* APR_CHARSET_EBCDIC */
 
130
    int len;
 
131
    
 
132
    len = apr_base64_decode_binary((unsigned char *) bufplain, bufcoded);
 
133
#if APR_CHARSET_EBCDIC
 
134
    inbytes_left = outbytes_left = len;
 
135
    apr_xlate_conv_buffer(xlate_to_ebcdic, bufplain, &inbytes_left,
 
136
                          bufplain, &outbytes_left);
 
137
#endif                          /* APR_CHARSET_EBCDIC */
 
138
    bufplain[len] = '\0';
 
139
    return len;
 
140
}
 
141
 
 
142
/* This is the same as apr_base64_decode() except on EBCDIC machines, where
 
143
 * the conversion of the output to ebcdic is left out.
 
144
 */
 
145
APU_DECLARE(int) apr_base64_decode_binary(unsigned char *bufplain,
 
146
                                   const char *bufcoded)
 
147
{
 
148
    int nbytesdecoded;
 
149
    register const unsigned char *bufin;
 
150
    register unsigned char *bufout;
 
151
    register int nprbytes;
 
152
 
 
153
    bufin = (const unsigned char *) bufcoded;
 
154
    while (pr2six[*(bufin++)] <= 63);
 
155
    nprbytes = (bufin - (const unsigned char *) bufcoded) - 1;
 
156
    nbytesdecoded = ((nprbytes + 3) / 4) * 3;
 
157
 
 
158
    bufout = (unsigned char *) bufplain;
 
159
    bufin = (const unsigned char *) bufcoded;
 
160
 
 
161
    while (nprbytes > 4) {
 
162
        *(bufout++) =
 
163
            (unsigned char) (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4);
 
164
        *(bufout++) =
 
165
            (unsigned char) (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2);
 
166
        *(bufout++) =
 
167
            (unsigned char) (pr2six[bufin[2]] << 6 | pr2six[bufin[3]]);
 
168
        bufin += 4;
 
169
        nprbytes -= 4;
 
170
    }
 
171
 
 
172
    /* Note: (nprbytes == 1) would be an error, so just ingore that case */
 
173
    if (nprbytes > 1) {
 
174
        *(bufout++) =
 
175
            (unsigned char) (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4);
 
176
    }
 
177
    if (nprbytes > 2) {
 
178
        *(bufout++) =
 
179
            (unsigned char) (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2);
 
180
    }
 
181
    if (nprbytes > 3) {
 
182
        *(bufout++) =
 
183
            (unsigned char) (pr2six[bufin[2]] << 6 | pr2six[bufin[3]]);
 
184
    }
 
185
 
 
186
    nbytesdecoded -= (4 - nprbytes) & 3;
 
187
    return nbytesdecoded;
 
188
}
 
189
 
 
190
static const char basis_64[] =
 
191
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 
192
 
 
193
APU_DECLARE(int) apr_base64_encode_len(int len)
 
194
{
 
195
    return ((len + 2) / 3 * 4) + 1;
 
196
}
 
197
 
 
198
APU_DECLARE(int) apr_base64_encode(char *encoded, const char *string, int len)
 
199
{
 
200
#if !APR_CHARSET_EBCDIC
 
201
    return apr_base64_encode_binary(encoded, (const unsigned char *) string, len);
 
202
#else /* APR_CHARSET_EBCDIC */
 
203
    int i;
 
204
    char *p;
 
205
 
 
206
    p = encoded;
 
207
    for (i = 0; i < len - 2; i += 3) {
 
208
        *p++ = basis_64[(os_toascii[string[i]] >> 2) & 0x3F];
 
209
        *p++ = basis_64[((os_toascii[string[i]] & 0x3) << 4) |
 
210
                        ((int) (os_toascii[string[i + 1]] & 0xF0) >> 4)];
 
211
        *p++ = basis_64[((os_toascii[string[i + 1]] & 0xF) << 2) |
 
212
                        ((int) (os_toascii[string[i + 2]] & 0xC0) >> 6)];
 
213
        *p++ = basis_64[os_toascii[string[i + 2]] & 0x3F];
 
214
    }
 
215
    if (i < len) {
 
216
        *p++ = basis_64[(os_toascii[string[i]] >> 2) & 0x3F];
 
217
        if (i == (len - 1)) {
 
218
            *p++ = basis_64[((os_toascii[string[i]] & 0x3) << 4)];
 
219
            *p++ = '=';
 
220
        }
 
221
        else {
 
222
            *p++ = basis_64[((os_toascii[string[i]] & 0x3) << 4) |
 
223
                            ((int) (os_toascii[string[i + 1]] & 0xF0) >> 4)];
 
224
            *p++ = basis_64[((os_toascii[string[i + 1]] & 0xF) << 2)];
 
225
        }
 
226
        *p++ = '=';
 
227
    }
 
228
 
 
229
    *p++ = '\0';
 
230
    return p - encoded;
 
231
#endif                          /* APR_CHARSET_EBCDIC */
 
232
}
 
233
 
 
234
/* This is the same as apr_base64_encode() except on EBCDIC machines, where
 
235
 * the conversion of the input to ascii is left out.
 
236
 */
 
237
APU_DECLARE(int) apr_base64_encode_binary(char *encoded,
 
238
                                      const unsigned char *string, int len)
 
239
{
 
240
    int i;
 
241
    char *p;
 
242
 
 
243
    p = encoded;
 
244
    for (i = 0; i < len - 2; i += 3) {
 
245
        *p++ = basis_64[(string[i] >> 2) & 0x3F];
 
246
        *p++ = basis_64[((string[i] & 0x3) << 4) |
 
247
                        ((int) (string[i + 1] & 0xF0) >> 4)];
 
248
        *p++ = basis_64[((string[i + 1] & 0xF) << 2) |
 
249
                        ((int) (string[i + 2] & 0xC0) >> 6)];
 
250
        *p++ = basis_64[string[i + 2] & 0x3F];
 
251
    }
 
252
    if (i < len) {
 
253
        *p++ = basis_64[(string[i] >> 2) & 0x3F];
 
254
        if (i == (len - 1)) {
 
255
            *p++ = basis_64[((string[i] & 0x3) << 4)];
 
256
            *p++ = '=';
 
257
        }
 
258
        else {
 
259
            *p++ = basis_64[((string[i] & 0x3) << 4) |
 
260
                            ((int) (string[i + 1] & 0xF0) >> 4)];
 
261
            *p++ = basis_64[((string[i + 1] & 0xF) << 2)];
 
262
        }
 
263
        *p++ = '=';
 
264
    }
 
265
 
 
266
    *p++ = '\0';
 
267
    return p - encoded;
 
268
}