diff --git a/src/backend/utils/adt/encode.c b/src/backend/utils/adt/encode.c index 5382585184..ce197bd19f 100644 --- a/src/backend/utils/adt/encode.c +++ b/src/backend/utils/adt/encode.c @@ -7,13 +7,14 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/adt/encode.c,v 1.2 2001/09/14 17:46:40 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/encode.c,v 1.3 2001/09/30 22:03:41 tgl Exp $ * *------------------------------------------------------------------------- */ #include "postgres.h" #include + #include "utils/builtins.h" @@ -38,24 +39,25 @@ binary_encode(PG_FUNCTION_ARGS) Datum name = PG_GETARG_DATUM(1); text *result; char *namebuf; - int namelen, datalen, resultlen, res; + int datalen, resultlen, res; struct pg_encoding *enc; datalen = VARSIZE(data) - VARHDRSZ; - namelen = VARSIZE(name) - VARHDRSZ; - namebuf = (char *)DirectFunctionCall1(textout, name); + namebuf = DatumGetCString(DirectFunctionCall1(textout, name)); enc = pg_find_encoding(namebuf); if (enc == NULL) - elog(ERROR, "No such encoding"); + elog(ERROR, "No such encoding as '%s'", namebuf); resultlen = enc->encode_len(VARDATA(data), datalen); result = palloc(VARHDRSZ + resultlen); res = enc->encode(VARDATA(data), datalen, VARDATA(result)); + + /* Make this FATAL 'cause we've trodden on memory ... */ if (res > resultlen) - elog(ERROR, "Overflow - encode estimate too small"); + elog(FATAL, "Overflow - encode estimate too small"); VARATT_SIZEP(result) = VARHDRSZ + res; @@ -69,24 +71,25 @@ binary_decode(PG_FUNCTION_ARGS) Datum name = PG_GETARG_DATUM(1); bytea *result; char *namebuf; - int namelen, datalen, resultlen, res; + int datalen, resultlen, res; struct pg_encoding *enc; datalen = VARSIZE(data) - VARHDRSZ; - namelen = VARSIZE(name) - VARHDRSZ; - namebuf = (char *)DirectFunctionCall1(textout, name); + namebuf = DatumGetCString(DirectFunctionCall1(textout, name)); enc = pg_find_encoding(namebuf); if (enc == NULL) - elog(ERROR, "No such encoding"); + elog(ERROR, "No such encoding as '%s'", namebuf); resultlen = enc->decode_len(VARDATA(data), datalen); result = palloc(VARHDRSZ + resultlen); res = enc->decode(VARDATA(data), datalen, VARDATA(result)); + + /* Make this FATAL 'cause we've trodden on memory ... */ if (res > resultlen) - elog(ERROR, "Overflow - decode estimate too small"); + elog(FATAL, "Overflow - decode estimate too small"); VARATT_SIZEP(result) = VARHDRSZ + res; @@ -339,14 +342,12 @@ esc_encode(const uint8 *src, unsigned srclen, uint8 *dst) { const uint8 *end = src + srclen; uint8 *rp = dst; - int val; int len = 0; while (src < end) { if (*src == '\0') { - val = *src; rp[0] = '\\'; rp[1] = '0'; rp[2] = '0'; @@ -356,7 +357,6 @@ esc_encode(const uint8 *src, unsigned srclen, uint8 *dst) } else if (*src == '\\') { - val = *src; rp[0] = '\\'; rp[1] = '\\'; rp += 2; @@ -370,7 +370,6 @@ esc_encode(const uint8 *src, unsigned srclen, uint8 *dst) src++; } - *rp = '\0'; return len; } @@ -380,7 +379,6 @@ esc_decode(const uint8 *src, unsigned srclen, uint8 *dst) { const uint8 *end = src + srclen; uint8 *rp = dst; - int val; int len = 0; while (src < end) @@ -389,11 +387,13 @@ esc_decode(const uint8 *src, unsigned srclen, uint8 *dst) { *rp++ = *src++; } - else if ( (src[0] == '\\') && + else if ( src+3 < end && (src[1] >= '0' && src[1] <= '3') && (src[2] >= '0' && src[2] <= '7') && (src[3] >= '0' && src[3] <= '7') ) { + int val; + val = VAL(src[1]); val <<= 3; val += VAL(src[2]); @@ -401,7 +401,7 @@ esc_decode(const uint8 *src, unsigned srclen, uint8 *dst) *rp++ = val + VAL(src[3]); src += 4; } - else if ( (src[0] == '\\') && + else if ( src+1 < end && (src[1] == '\\') ) { *rp++ = '\\'; @@ -418,6 +418,7 @@ esc_decode(const uint8 *src, unsigned srclen, uint8 *dst) len++; } + return len; } @@ -439,11 +440,6 @@ esc_enc_len(const uint8 *src, unsigned srclen) src++; } - /* - * Allow for null terminator - */ - len++; - return len; } @@ -459,7 +455,7 @@ esc_dec_len(const uint8 *src, unsigned srclen) { src++; } - else if ( (src[0] == '\\') && + else if ( src+3 < end && (src[1] >= '0' && src[1] <= '3') && (src[2] >= '0' && src[2] <= '7') && (src[3] >= '0' && src[3] <= '7') ) @@ -469,7 +465,7 @@ esc_dec_len(const uint8 *src, unsigned srclen) */ src += 4; } - else if ( (src[0] == '\\') && + else if ( src+1 < end && (src[1] == '\\') ) { /* @@ -510,7 +506,7 @@ pg_find_encoding(const char *name) int i; for (i = 0; enclist[i].name; i++) - if (!strcasecmp(enclist[i].name, name)) + if (strcasecmp(enclist[i].name, name) == 0) return &enclist[i].enc; return NULL;