From 7eff804b490afbc7815cbaf6d2b4bcec311d12bb Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Sun, 30 Sep 2001 22:03:41 +0000
Subject: [PATCH] Clean up encode/decode functions a little bit.

---
 src/backend/utils/adt/encode.c | 48 ++++++++++++++++------------------
 1 file changed, 22 insertions(+), 26 deletions(-)

diff --git a/src/backend/utils/adt/encode.c b/src/backend/utils/adt/encode.c
index 53825851847..ce197bd19f4 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 <ctype.h>
+
 #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;
-- 
GitLab