diff options
Diffstat (limited to 'contrib/pgcrypto/encode.c')
-rw-r--r-- | contrib/pgcrypto/encode.c | 212 |
1 files changed, 123 insertions, 89 deletions
diff --git a/contrib/pgcrypto/encode.c b/contrib/pgcrypto/encode.c index 0ad0a8f56ce..b6db217c836 100644 --- a/contrib/pgcrypto/encode.c +++ b/contrib/pgcrypto/encode.c @@ -1,7 +1,7 @@ /* * encode.c * Various data encoding/decoding things. - * + * * Copyright (c) 2001 Marko Kreen * All rights reserved. * @@ -9,15 +9,15 @@ * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: encode.c,v 1.3 2001/02/10 02:31:25 tgl Exp $ + * $Id: encode.c,v 1.4 2001/03/22 03:59:10 momjian Exp $ */ #include "postgres.h" @@ -43,9 +43,9 @@ #endif static pg_coding * -find_coding(pg_coding *hbuf, text *name, int silent); + find_coding(pg_coding * hbuf, text *name, int silent); static pg_coding * -pg_find_coding(pg_coding *res, char *name); + pg_find_coding(pg_coding * res, char *name); /* SQL function: encode(bytea, text) returns text */ @@ -54,34 +54,37 @@ PG_FUNCTION_INFO_V1(encode); Datum encode(PG_FUNCTION_ARGS) { - text *arg; - text *name; - uint len, rlen, rlen0; - pg_coding *c, cbuf; - text *res; - + text *arg; + text *name; + uint len, + rlen, + rlen0; + pg_coding *c, + cbuf; + text *res; + if (PG_ARGISNULL(0) || PG_ARGISNULL(1)) PG_RETURN_NULL(); - - name = PG_GETARG_TEXT_P(1); - c = find_coding(&cbuf, name, 0); /* will give error if fails */ + + name = PG_GETARG_TEXT_P(1); + c = find_coding(&cbuf, name, 0); /* will give error if fails */ arg = PG_GETARG_TEXT_P(0); len = VARSIZE(arg) - VARHDRSZ; - + rlen0 = c->encode_len(len); - - res = (text *)palloc(rlen0 + VARHDRSZ); - + + res = (text *) palloc(rlen0 + VARHDRSZ); + rlen = c->encode(VARDATA(arg), len, VARDATA(res)); VARATT_SIZEP(res) = rlen + VARHDRSZ; if (rlen > rlen0) elog(FATAL, "pg_encode: overflow, encode estimate too small"); - + PG_FREE_IF_COPY(arg, 0); PG_FREE_IF_COPY(name, 1); - + PG_RETURN_TEXT_P(res); } @@ -91,54 +94,58 @@ PG_FUNCTION_INFO_V1(decode); Datum decode(PG_FUNCTION_ARGS) { - text *arg; - text *name; - uint len, rlen, rlen0; - pg_coding *c, cbuf; - text *res; - + text *arg; + text *name; + uint len, + rlen, + rlen0; + pg_coding *c, + cbuf; + text *res; + if (PG_ARGISNULL(0) || PG_ARGISNULL(1)) PG_RETURN_NULL(); - - name = PG_GETARG_TEXT_P(1); - c = find_coding(&cbuf, name, 0); /* will give error if fails */ + + name = PG_GETARG_TEXT_P(1); + c = find_coding(&cbuf, name, 0); /* will give error if fails */ arg = PG_GETARG_TEXT_P(0); len = VARSIZE(arg) - VARHDRSZ; - + rlen0 = c->decode_len(len); - - res = (text *)palloc(rlen0 + VARHDRSZ); - + + res = (text *) palloc(rlen0 + VARHDRSZ); + rlen = c->decode(VARDATA(arg), len, VARDATA(res)); VARATT_SIZEP(res) = rlen + VARHDRSZ; if (rlen > rlen0) elog(FATAL, "pg_decode: overflow, decode estimate too small"); - + PG_FREE_IF_COPY(arg, 0); PG_FREE_IF_COPY(name, 1); - + PG_RETURN_TEXT_P(res); } static pg_coding * -find_coding(pg_coding *dst, text *name, int silent) +find_coding(pg_coding * dst, text *name, int silent) { - pg_coding *p; - char buf[NAMEDATALEN]; - uint len; - + pg_coding *p; + char buf[NAMEDATALEN]; + uint len; + len = VARSIZE(name) - VARHDRSZ; - if (len >= NAMEDATALEN) { + if (len >= NAMEDATALEN) + { if (silent) return NULL; elog(ERROR, "Encoding type does not exist (name too long)"); } - + memcpy(buf, VARDATA(name), len); buf[len] = 0; - + p = pg_find_coding(dst, buf); if (p == NULL && !silent) @@ -151,21 +158,23 @@ static char *hextbl = "0123456789abcdef"; uint hex_encode(uint8 *src, uint len, uint8 *dst) { - uint8 *end = src + len; - while (src < end) { + uint8 *end = src + len; + + while (src < end) + { *dst++ = hextbl[(*src >> 4) & 0xF]; *dst++ = hextbl[*src & 0xF]; src++; } - return len*2; + return len * 2; } /* probably should use lookup table */ static uint8 get_hex(char c) { - uint8 res = 0; - + uint8 res = 0; + if (c >= '0' && c <= '9') res = c - '0'; else if (c >= 'a' && c <= 'f') @@ -174,19 +183,26 @@ get_hex(char c) res = c - 'A' + 10; else elog(ERROR, "Bad hex code: '%c'", c); - + return res; } uint hex_decode(uint8 *src, uint len, uint8 *dst) { - uint8 *s, *srcend, v1, v2, *p = dst; - + uint8 *s, + *srcend, + v1, + v2, + *p = dst; + srcend = src + len; - s = src; p = dst; - while (s < srcend) { - if (*s == ' ' || *s == '\n' || *s == '\t' || *s == '\r') { + s = src; + p = dst; + while (s < srcend) + { + if (*s == ' ' || *s == '\n' || *s == '\t' || *s == '\r') + { s++; continue; } @@ -196,30 +212,36 @@ hex_decode(uint8 *src, uint len, uint8 *dst) v2 = get_hex(*s++); *p++ = v1 | v2; } - + return p - dst; } static unsigned char _base64[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; uint b64_encode(uint8 *src, uint len, uint8 *dst) { - uint8 *s, *p, *end = src + len, *lend = dst + 76; - int pos = 2; + uint8 *s, + *p, + *end = src + len, + *lend = dst + 76; + int pos = 2; unsigned long buf = 0; - s = src; p = dst; - - while (s < end) { + s = src; + p = dst; + + while (s < end) + { buf |= *s << (pos << 3); pos--; s++; - + /* write it out */ - if (pos < 0) { + if (pos < 0) + { *p++ = _base64[(buf >> 18) & 0x3f]; *p++ = _base64[(buf >> 12) & 0x3f]; *p++ = _base64[(buf >> 6) & 0x3f]; @@ -228,12 +250,14 @@ b64_encode(uint8 *src, uint len, uint8 *dst) pos = 2; buf = 0; } - if (p >= lend) { + if (p >= lend) + { *p++ = '\n'; lend = p + 76; } } - if (pos != 2) { + if (pos != 2) + { *p++ = _base64[(buf >> 18) & 0x3f]; *p++ = _base64[(buf >> 12) & 0x3f]; *p++ = (pos == 0) ? _base64[(buf >> 6) & 0x3f] : '='; @@ -247,14 +271,17 @@ b64_encode(uint8 *src, uint len, uint8 *dst) uint b64_decode(uint8 *src, uint len, uint8 *dst) { - char *srcend = src + len, *s = src; - uint8 *p = dst; - char c; - uint b = 0; + char *srcend = src + len, + *s = src; + uint8 *p = dst; + char c; + uint b = 0; unsigned long buf = 0; - int pos = 0, end = 0; - - while (s < srcend) { + int pos = 0, + end = 0; + + while (s < srcend) + { c = *s++; if (c >= 'A' && c <= 'Z') b = c - 'A'; @@ -266,16 +293,21 @@ b64_decode(uint8 *src, uint len, uint8 *dst) b = 62; else if (c == '/') b = 63; - else if (c == '=') { + else if (c == '=') + { /* end sequence */ - if (!end) { - if (pos == 2) end = 1; - else if (pos == 3) end = 2; + if (!end) + { + if (pos == 2) + end = 1; + else if (pos == 3) + end = 2; else elog(ERROR, "base64: unexpected '='"); } b = 0; - } else if (c == ' ' || c == '\t' || c == '\n' || c == '\r') + } + else if (c == ' ' || c == '\t' || c == '\n' || c == '\r') continue; else elog(ERROR, "base64: Invalid symbol"); @@ -283,7 +315,8 @@ b64_decode(uint8 *src, uint len, uint8 *dst) /* add it to buffer */ buf = (buf << 6) + b; pos++; - if (pos == 4) { + if (pos == 4) + { *p++ = (buf >> 16) & 255; if (end == 0 || end > 1) *p++ = (buf >> 8) & 255; @@ -326,21 +359,22 @@ b64_dec_len(uint srclen) } static pg_coding -encoding_list [] = { - { "hex", hex_enc_len, hex_dec_len, hex_encode, hex_decode}, - { "base64", b64_enc_len, b64_dec_len, b64_encode, b64_decode}, - { NULL, NULL, NULL, NULL, NULL} + encoding_list[] = { + {"hex", hex_enc_len, hex_dec_len, hex_encode, hex_decode}, + {"base64", b64_enc_len, b64_dec_len, b64_encode, b64_decode}, + {NULL, NULL, NULL, NULL, NULL} }; static pg_coding * -pg_find_coding(pg_coding *res, char *name) +pg_find_coding(pg_coding * res, char *name) { - pg_coding *p; - for (p = encoding_list; p->name; p++) { + pg_coding *p; + + for (p = encoding_list; p->name; p++) + { if (!strcasecmp(p->name, name)) return p; } return NULL; } - |