I am attaching a patch to eliminate duplicate b64_encode and decode functions from pgcrypto, and to expose those functions for use by add-ins (I want to use them in Veil).
The patch was made against CVS head today. It compiles and tests successfully. Though I was unable to run pgrypto regression tests, I did give the b64 encoding a sanity check. I also added a b64_char() function that is now used from pgcrypto. This allowed me to remove the duplicate _base64 character array. I hope this is the correct place to submit the patch. The wiki (http://wiki.postgresql.org/wiki/Submitting_a_Patch) refers to pgsql-patches but I believe that is now deprecated. __ Marc
Index: contrib/pgcrypto/pgp-armor.c =================================================================== RCS file: /projects/cvsroot/pgsql/contrib/pgcrypto/pgp-armor.c,v retrieving revision 1.3 diff -c -r1.3 pgp-armor.c *** contrib/pgcrypto/pgp-armor.c 15 Oct 2005 02:49:06 -0000 1.3 --- contrib/pgcrypto/pgp-armor.c 17 Jul 2008 22:37:27 -0000 *************** *** 30,181 **** */ #include "postgres.h" #include "px.h" #include "mbuf.h" #include "pgp.h" /* - * BASE64 - duplicated :( - */ - - static const unsigned char _base64[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - - static int - b64_encode(const uint8 *src, unsigned len, uint8 *dst) - { - uint8 *p, - *lend = dst + 76; - const uint8 *s, - *end = src + len; - int pos = 2; - unsigned long buf = 0; - - s = src; - p = dst; - - while (s < end) - { - buf |= *s << (pos << 3); - pos--; - s++; - - /* - * write it out - */ - if (pos < 0) - { - *p++ = _base64[(buf >> 18) & 0x3f]; - *p++ = _base64[(buf >> 12) & 0x3f]; - *p++ = _base64[(buf >> 6) & 0x3f]; - *p++ = _base64[buf & 0x3f]; - - pos = 2; - buf = 0; - } - if (p >= lend) - { - *p++ = '\n'; - lend = p + 76; - } - } - if (pos != 2) - { - *p++ = _base64[(buf >> 18) & 0x3f]; - *p++ = _base64[(buf >> 12) & 0x3f]; - *p++ = (pos == 0) ? _base64[(buf >> 6) & 0x3f] : '='; - *p++ = '='; - } - - return p - dst; - } - - /* probably should use lookup table */ - static int - b64_decode(const uint8 *src, unsigned len, uint8 *dst) - { - const uint8 *srcend = src + len, - *s = src; - uint8 *p = dst; - char c; - unsigned b = 0; - unsigned long buf = 0; - int pos = 0, - end = 0; - - while (s < srcend) - { - c = *s++; - if (c >= 'A' && c <= 'Z') - b = c - 'A'; - else if (c >= 'a' && c <= 'z') - b = c - 'a' + 26; - else if (c >= '0' && c <= '9') - b = c - '0' + 52; - else if (c == '+') - b = 62; - else if (c == '/') - b = 63; - else if (c == '=') - { - /* - * end sequence - */ - if (!end) - { - if (pos == 2) - end = 1; - else if (pos == 3) - end = 2; - else - return PXE_PGP_CORRUPT_ARMOR; - } - b = 0; - } - else if (c == ' ' || c == '\t' || c == '\n' || c == '\r') - continue; - else - return PXE_PGP_CORRUPT_ARMOR; - - /* - * add it to buffer - */ - buf = (buf << 6) + b; - pos++; - if (pos == 4) - { - *p++ = (buf >> 16) & 255; - if (end == 0 || end > 1) - *p++ = (buf >> 8) & 255; - if (end == 0 || end > 2) - *p++ = buf & 255; - buf = 0; - pos = 0; - } - } - - if (pos != 0) - return PXE_PGP_CORRUPT_ARMOR; - return p - dst; - } - - static unsigned - b64_enc_len(unsigned srclen) - { - /* - * 3 bytes will be converted to 4, linefeed after 76 chars - */ - return (srclen + 2) * 4 / 3 + srclen / (76 * 3 / 4); - } - - static unsigned - b64_dec_len(unsigned srclen) - { - return (srclen * 3) >> 2; - } - - /* * PGP armor */ --- 30,42 ---- */ #include "postgres.h" + #include "utils/builtins.h" #include "px.h" #include "mbuf.h" #include "pgp.h" /* * PGP armor */ *************** *** 215,234 **** memcpy(pos, armor_header, n); pos += n; ! n = b64_encode(src, len, pos); pos += n; if (*(pos - 1) != '\n') *pos++ = '\n'; *pos++ = '='; ! pos[3] = _base64[crc & 0x3f]; crc >>= 6; ! pos[2] = _base64[crc & 0x3f]; crc >>= 6; ! pos[1] = _base64[crc & 0x3f]; crc >>= 6; ! pos[0] = _base64[crc & 0x3f]; pos += 4; n = strlen(armor_footer); --- 76,95 ---- memcpy(pos, armor_header, n); pos += n; ! n = b64_encode((char *) src, len, (char *) pos); pos += n; if (*(pos - 1) != '\n') *pos++ = '\n'; *pos++ = '='; ! pos[3] = b64_char(crc); crc >>= 6; ! pos[2] = b64_char(crc); crc >>= 6; ! pos[1] = b64_char(crc); crc >>= 6; ! pos[0] = b64_char(crc); pos += 4; n = strlen(armor_footer); *************** *** 356,367 **** goto out; /* decode crc */ ! if (b64_decode(p + 1, 4, buf) != 3) goto out; crc = (((long) buf[0]) << 16) + (((long) buf[1]) << 8) + (long) buf[2]; /* decode data */ ! res = b64_decode(base64_start, base64_end - base64_start, dst); /* check crc */ if (res >= 0 && crc24(dst, res) != crc) --- 217,229 ---- goto out; /* decode crc */ ! if (b64_decode((char *) (p + 1), 4, (char *) buf) != 3) goto out; crc = (((long) buf[0]) << 16) + (((long) buf[1]) << 8) + (long) buf[2]; /* decode data */ ! res = b64_decode((char *) base64_start, base64_end - base64_start, ! (char *) dst); /* check crc */ if (res >= 0 && crc24(dst, res) != crc) *************** *** 373,383 **** unsigned pgp_armor_enc_len(unsigned len) { ! return b64_enc_len(len) + strlen(armor_header) + strlen(armor_footer) + 16; } unsigned pgp_armor_dec_len(unsigned len) { ! return b64_dec_len(len); } --- 235,246 ---- unsigned pgp_armor_enc_len(unsigned len) { ! return b64_enc_len(NULL, len) + strlen(armor_header) + ! strlen(armor_footer) + 16; } unsigned pgp_armor_dec_len(unsigned len) { ! return b64_dec_len(NULL, len); } Index: src/backend/utils/adt/encode.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/utils/adt/encode.c,v retrieving revision 1.22 diff -c -r1.22 encode.c *** src/backend/utils/adt/encode.c 25 Mar 2008 22:42:44 -0000 1.22 --- src/backend/utils/adt/encode.c 17 Jul 2008 22:37:28 -0000 *************** *** 214,220 **** 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, }; ! static unsigned b64_encode(const char *src, unsigned len, char *dst) { char *p, --- 214,226 ---- 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, }; ! char ! b64_char(unsigned src) ! { ! return _base64[src & 0x3f]; ! } ! ! unsigned b64_encode(const char *src, unsigned len, char *dst) { char *p, *************** *** 261,267 **** return p - dst; } ! static unsigned b64_decode(const char *src, unsigned len, char *dst) { const char *srcend = src + len, --- 267,273 ---- return p - dst; } ! unsigned b64_decode(const char *src, unsigned len, char *dst) { const char *srcend = src + len, *************** *** 330,343 **** } ! static unsigned b64_enc_len(const char *src, unsigned srclen) { /* 3 bytes will be converted to 4, linefeed after 76 chars */ return (srclen + 2) * 4 / 3 + srclen / (76 * 3 / 4); } ! static unsigned b64_dec_len(const char *src, unsigned srclen) { return (srclen * 3) >> 2; --- 336,349 ---- } ! unsigned b64_enc_len(const char *src, unsigned srclen) { /* 3 bytes will be converted to 4, linefeed after 76 chars */ return (srclen + 2) * 4 / 3 + srclen / (76 * 3 / 4); } ! unsigned b64_dec_len(const char *src, unsigned srclen) { return (srclen * 3) >> 2; Index: src/include/utils/builtins.h =================================================================== RCS file: /projects/cvsroot/pgsql/src/include/utils/builtins.h,v retrieving revision 1.318 diff -c -r1.318 builtins.h *** src/include/utils/builtins.h 3 Jul 2008 20:58:47 -0000 1.318 --- src/include/utils/builtins.h 17 Jul 2008 22:37:28 -0000 *************** *** 677,684 **** extern Datum byteaGetBit(PG_FUNCTION_ARGS); extern Datum byteaSetByte(PG_FUNCTION_ARGS); extern Datum byteaSetBit(PG_FUNCTION_ARGS); - extern Datum binary_encode(PG_FUNCTION_ARGS); - extern Datum binary_decode(PG_FUNCTION_ARGS); extern Datum byteaeq(PG_FUNCTION_ARGS); extern Datum byteane(PG_FUNCTION_ARGS); extern Datum bytealt(PG_FUNCTION_ARGS); --- 677,682 ---- *************** *** 692,697 **** --- 690,704 ---- extern Datum bytea_substr_no_len(PG_FUNCTION_ARGS); extern Datum pg_column_size(PG_FUNCTION_ARGS); + /* encode.c */ + extern Datum binary_encode(PG_FUNCTION_ARGS); + extern Datum binary_decode(PG_FUNCTION_ARGS); + extern char b64_char(unsigned src); + extern unsigned b64_encode(const char *src, unsigned len, char *dst); + extern unsigned b64_decode(const char *src, unsigned len, char *dst); + extern unsigned b64_enc_len(const char *src, unsigned srclen); + extern unsigned b64_dec_len(const char *src, unsigned srclen); + /* version.c */ extern Datum pgsql_version(PG_FUNCTION_ARGS);
signature.asc
Description: This is a digitally signed message part