Annotation of libaitwww/src/base64.c, revision 1.4

1.2       misho       1: /*************************************************************************
                      2: * (C) 2012 AITNET ltd - Sofia/Bulgaria - <misho@aitnet.org>
                      3: *  by Michael Pounov <misho@elwix.org>
                      4: *
                      5: * $Author: misho $
1.4     ! misho       6: * $Id: base64.c,v 1.3.6.1 2016/09/14 15:08:24 misho Exp $
1.2       misho       7: *
                      8: **************************************************************************
                      9: The ELWIX and AITNET software is distributed under the following
                     10: terms:
                     11: 
                     12: All of the documentation and software included in the ELWIX and AITNET
                     13: Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>
                     14: 
1.4     ! misho      15: Copyright 2004 - 2016
1.2       misho      16:        by Michael Pounov <misho@elwix.org>.  All rights reserved.
                     17: 
                     18: Redistribution and use in source and binary forms, with or without
                     19: modification, are permitted provided that the following conditions
                     20: are met:
                     21: 1. Redistributions of source code must retain the above copyright
                     22:    notice, this list of conditions and the following disclaimer.
                     23: 2. Redistributions in binary form must reproduce the above copyright
                     24:    notice, this list of conditions and the following disclaimer in the
                     25:    documentation and/or other materials provided with the distribution.
                     26: 3. All advertising materials mentioning features or use of this software
                     27:    must display the following acknowledgement:
                     28: This product includes software developed by Michael Pounov <misho@elwix.org>
                     29: ELWIX - Embedded LightWeight unIX and its contributors.
                     30: 4. Neither the name of AITNET nor the names of its contributors
                     31:    may be used to endorse or promote products derived from this software
                     32:    without specific prior written permission.
                     33: 
                     34: THIS SOFTWARE IS PROVIDED BY AITNET AND CONTRIBUTORS ``AS IS'' AND
                     35: ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     36: IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     37: ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     38: FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     39: DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     40: OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     41: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     42: LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     43: OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     44: SUCH DAMAGE.
                     45: */
                     46: #include "global.h"
                     47: 
                     48: 
                     49: static const unsigned char base64_table[65] = 
                     50:        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
                     51: 
                     52: 
                     53: /*
                     54:  * www_b64encode() - Base64 encode function
                     55:  *
                     56:  * @src = source data
1.3       misho      57:  * return: NULL error or !=NULL encoded variable, after use call ait_freeVar()
1.2       misho      58:  */
                     59: ait_val_t *
                     60: www_b64encode(ait_val_t * __restrict src)
                     61: {
1.4     ! misho      62:        ait_val_t v = AIT_VAL_INIT, *ret = NULL;
1.2       misho      63:        size_t olen;
                     64:        const u_char *in, *end;
                     65:        u_char *pos, *out;
                     66:        int len = 0;
                     67: 
                     68:        if (!src || AIT_ISEMPTY(src))
                     69:                return NULL;
                     70:        olen = AIT_LEN(src) * 4 / 3 + 4;        /* 3-byte blocks to 4-byte */
                     71:        olen += olen / 72;                      /* LF */
                     72:        olen++;                                 /* \0 */
                     73:        if (olen < AIT_LEN(src)) {
                     74:                www_SetErr(EINVAL, "Integer overflow");
                     75:                return NULL;
                     76:        }
                     77: 
                     78:        AIT_SET_STRSIZ(&v, olen);
                     79:        pos = out = (u_char*) AIT_GET_STR(&v);
                     80:        in = (u_char*) AIT_GET_STR(src);
                     81:        end = in + AIT_LEN(src);
                     82: 
                     83:        while (end - in >= 3) {
                     84:                *pos++ = base64_table[in[0] >> 2];
                     85:                *pos++ = base64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)];
                     86:                *pos++ = base64_table[((in[1] & 0x0f) << 2) | (in[2] >> 6)];
                     87:                *pos++ = base64_table[in[2] & 0x3f];
                     88:                in += 3;
                     89:                len += 4;
                     90:                if (len >= 72) {
                     91:                        *pos++ = '\n';
                     92:                        len = 0;
                     93:                }
                     94:        }
                     95: 
                     96:        if (end - in) {
                     97:                *pos++ = base64_table[in[0] >> 2];
                     98:                if (end - in == 1) {
                     99:                        *pos++ = base64_table[(in[0] & 0x03) << 4];
                    100:                        *pos++ = '=';
                    101:                } else {
                    102:                        *pos++ = base64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)];
                    103:                        *pos++ = base64_table[(in[1] & 0x0f) << 2];
                    104:                }
                    105:                *pos++ = '=';
                    106:                len += 4;
                    107:        }
                    108: 
                    109:        if (len)
                    110:                *pos++ = '\n';
                    111: 
                    112:        *pos = 0;
                    113: 
1.3       misho     114:        if (!(ret = ait_allocVar())) {
                    115:                www_SetErr(elwix_GetErrno(), "%s", elwix_GetError());
1.2       misho     116:                return NULL;
                    117:        } else {
                    118:                AIT_INIT_VAL2(ret, string);
                    119:                AIT_SET_STRLCPY(ret, AIT_GET_STR(&v), pos - out);
                    120:                AIT_FREE_VAL(&v);
                    121:        }
                    122:        return ret;
                    123: }
                    124: 
                    125: /*
                    126:  * www_b64decode() - Base64 decode function
                    127:  *
                    128:  * @src = source encoded data
1.3       misho     129:  * return: NULL error or !=NULL decoded variable, after use call ait_freeVar()
1.2       misho     130:  */
                    131: ait_val_t *
                    132: www_b64decode(ait_val_t * __restrict src)
                    133: {
1.4     ! misho     134:        ait_val_t v = AIT_VAL_INIT, *ret = NULL;
1.2       misho     135:        u_char dtable[256], *s, *pos, *out, in[4], blk[4];
                    136:        register size_t i, olen, cx = 0;
                    137: 
                    138:        if (!src || AIT_ISEMPTY(src))
                    139:                return NULL;
                    140:        else
                    141:                s = (u_char*) AIT_GET_STR(src);
                    142: 
                    143:        memset(dtable, 0x80, sizeof dtable);
                    144:        for (i = 0; i < sizeof base64_table - 1; i++)
                    145:                dtable[base64_table[i]] = (u_char) i;
                    146:        dtable['='] = 0;
                    147: 
                    148:        for (i = 0; i < AIT_LEN(src); i++)
                    149:                if (dtable[s[i]] != 0x80)
                    150:                        cx++;
                    151:        if (!cx || cx % 4) {
                    152:                www_SetErr(EINVAL, "Invalid argument");
                    153:                return NULL;
                    154:        }
                    155: 
                    156:        olen = cx / 4 * 3;
                    157:        AIT_SET_STRSIZ(&v, olen);
                    158:        pos = out = (u_char*) AIT_GET_STR(&v);
                    159: 
                    160:        for (cx = i = 0; i < AIT_LEN(src); i++) {
                    161:                if (dtable[s[i]] == 0x80)
                    162:                        continue;
                    163:                in[cx] = s[i];
                    164:                blk[cx++] = dtable[s[i]];
                    165:                if (cx == 4) {
                    166:                        *pos++ = (blk[0] << 2) | (blk[1] >> 4);
                    167:                        *pos++ = (blk[1] << 4) | (blk[2] >> 2);
                    168:                        *pos++ = (blk[2] << 6) | blk[3];
                    169:                        cx = 0;
                    170:                }
                    171:        }
                    172: 
                    173:        if (pos > out) {
                    174:                if (in[2] == '=')
                    175:                        pos -= 2;
                    176:                else if (in[3] == '=')
                    177:                        pos--;
                    178:        }
                    179: 
1.3       misho     180:        if (!(ret = ait_allocVar())) {
                    181:                www_SetErr(elwix_GetErrno(), "%s", elwix_GetError());
1.2       misho     182:                return NULL;
                    183:        } else {
                    184:                AIT_INIT_VAL2(ret, string);
                    185:                AIT_SET_STRLCPY(ret, AIT_GET_STR(&v), pos - out);
                    186:                AIT_FREE_VAL(&v);
                    187:        }
                    188:        return ret;
                    189: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>