From fd223c7407c7067ac3ec7e586f9e3d7b5afd2b2e Mon Sep 17 00:00:00 2001
From: Itagaki Takahiro <itagaki.takahiro@gmail.com>
Date: Fri, 3 Dec 2010 12:00:27 +0900
Subject: [PATCH] Remove unnecessary string null-termination in pg_convert. We
 can directly verify the unterminated input with pg_verify_mbstr_len.

---
 src/backend/utils/mb/mbutils.c | 35 +++++++++++++++++-----------------
 1 file changed, 17 insertions(+), 18 deletions(-)

diff --git a/src/backend/utils/mb/mbutils.c b/src/backend/utils/mb/mbutils.c
index a9dc2dee45c..a04181286af 100644
--- a/src/backend/utils/mb/mbutils.c
+++ b/src/backend/utils/mb/mbutils.c
@@ -406,14 +406,14 @@ pg_convert_from(PG_FUNCTION_ARGS)
 Datum
 pg_convert(PG_FUNCTION_ARGS)
 {
-	bytea	   *string = PG_GETARG_BYTEA_P(0);
+	bytea	   *string = PG_GETARG_BYTEA_PP(0);
 	char	   *src_encoding_name = NameStr(*PG_GETARG_NAME(1));
 	int			src_encoding = pg_char_to_encoding(src_encoding_name);
 	char	   *dest_encoding_name = NameStr(*PG_GETARG_NAME(2));
 	int			dest_encoding = pg_char_to_encoding(dest_encoding_name);
-	unsigned char *result;
+	const char *src_str;
+	char	   *dest_str;
 	bytea	   *retval;
-	unsigned char *str;
 	int			len;
 
 	if (src_encoding < 0)
@@ -427,26 +427,25 @@ pg_convert(PG_FUNCTION_ARGS)
 				 errmsg("invalid destination encoding name \"%s\"",
 						dest_encoding_name)));
 
-	/* make sure that source string is valid and null terminated */
-	len = VARSIZE(string) - VARHDRSZ;
-	pg_verify_mbstr(src_encoding, VARDATA(string), len, false);
-	str = palloc(len + 1);
-	memcpy(str, VARDATA(string), len);
-	*(str + len) = '\0';
+	/* make sure that source string is valid */
+	len = VARSIZE_ANY_EXHDR(string);
+	src_str = VARDATA_ANY(string);
+	pg_verify_mbstr_len(src_encoding, src_str, len, false);
 
-	result = pg_do_encoding_conversion(str, len, src_encoding, dest_encoding);
+	dest_str = (char *) pg_do_encoding_conversion(
+				(unsigned char *) src_str, len, src_encoding, dest_encoding);
+	if (dest_str != src_str)
+		len = strlen(dest_str);
 
 	/*
 	 * build bytea data type structure.
 	 */
-	len = strlen((char *) result) + VARHDRSZ;
-	retval = palloc(len);
-	SET_VARSIZE(retval, len);
-	memcpy(VARDATA(retval), result, len - VARHDRSZ);
-
-	if (result != str)
-		pfree(result);
-	pfree(str);
+	retval = (bytea *) palloc(len + VARHDRSZ);
+	SET_VARSIZE(retval, len + VARHDRSZ);
+	memcpy(VARDATA(retval), dest_str, len);
+
+	if (dest_str != src_str)
+		pfree(dest_str);
 
 	/* free memory if allocated by the toaster */
 	PG_FREE_IF_COPY(string, 0);
-- 
GitLab