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