summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTatsuo Ishii <ishii@postgresql.org>2001-11-19 06:48:39 +0000
committerTatsuo Ishii <ishii@postgresql.org>2001-11-19 06:48:39 +0000
commit5590d5fe99d88c1a9d47852e6be36aa590401f01 (patch)
tree7cbdd3785e263c12f750f220a93e43088aa309fa /src
parent09a2b4f4234f66c2dc89c269743ba04bf78ae8ba (diff)
downloadpostgresql-5590d5fe99d88c1a9d47852e6be36aa590401f01.tar.gz
Fix nasty bugs in pg_convert() and pg_convert2().
o they sometimes returns a result garbage string appended. o they do not work if client encoding is different from server encoding
Diffstat (limited to 'src')
-rw-r--r--src/backend/utils/mb/mbutils.c49
1 files changed, 40 insertions, 9 deletions
diff --git a/src/backend/utils/mb/mbutils.c b/src/backend/utils/mb/mbutils.c
index 645b9f3260..f7bc6fdac3 100644
--- a/src/backend/utils/mb/mbutils.c
+++ b/src/backend/utils/mb/mbutils.c
@@ -3,7 +3,7 @@
* client encoding and server internal encoding.
* (currently mule internal code (mic) is used)
* Tatsuo Ishii
- * $Id: mbutils.c,v 1.25 2001/10/25 05:49:51 momjian Exp $
+ * $Id: mbutils.c,v 1.26 2001/11/19 06:48:39 ishii Exp $
*/
#include "postgres.h"
@@ -220,6 +220,8 @@ pg_convert(PG_FUNCTION_ARGS)
from_mic_converter dest;
unsigned char *result;
text *retval;
+ unsigned char *str;
+ int len;
if (encoding < 0)
elog(ERROR, "Invalid encoding name %s", NameStr(*s));
@@ -231,14 +233,28 @@ pg_convert(PG_FUNCTION_ARGS)
elog(ERROR, "Conversion from %s to %s is not possible", NameStr(*s), encoding_name);
}
- result = pg_do_encoding_conversion(VARDATA(string), VARSIZE(string) - VARHDRSZ,
- src, dest);
+ /* make sure that source string is null terminated */
+ len = VARSIZE(string) - VARHDRSZ;
+ str = palloc(len + 1);
+ memcpy(str, VARDATA(string), len);
+ *(str + len) = '\0';
+
+ result = pg_do_encoding_conversion(str, len, src, dest);
if (result == NULL)
elog(ERROR, "Encoding conversion failed");
- retval = DatumGetTextP(DirectFunctionCall1(textin, CStringGetDatum(result)));
- if (result != (unsigned char *) VARDATA(string))
+ /* build text data type structre. we cannot use textin() here,
+ since textin assumes that input string encoding is same as
+ database encoding. */
+ len = strlen(result) + VARHDRSZ;
+ retval = palloc(len);
+ VARATT_SIZEP(retval) = len;
+ memcpy(VARDATA(retval), result, len - VARHDRSZ);
+
+ /* free memory allocated by pg_do_encoding_conversion */
+ if (result != str)
pfree(result);
+ pfree(str);
/* free memory if allocated by the toaster */
PG_FREE_IF_COPY(string, 0);
@@ -263,6 +279,8 @@ pg_convert2(PG_FUNCTION_ARGS)
from_mic_converter dest;
unsigned char *result;
text *retval;
+ unsigned char *str;
+ int len;
if (src_encoding < 0)
elog(ERROR, "Invalid source encoding name %s", src_encoding_name);
@@ -275,14 +293,27 @@ pg_convert2(PG_FUNCTION_ARGS)
src_encoding_name, dest_encoding_name);
}
- result = pg_do_encoding_conversion(VARDATA(string), VARSIZE(string) - VARHDRSZ,
- src, dest);
+ /* make sure that source string is null terminated */
+ len = VARSIZE(string) - VARHDRSZ;
+ str = palloc(len + 1);
+ memcpy(str, VARDATA(string), len);
+ *(str + len) = '\0';
+
+ result = pg_do_encoding_conversion(str, len, src, dest);
if (result == NULL)
elog(ERROR, "Encoding conversion failed");
- retval = DatumGetTextP(DirectFunctionCall1(textin, CStringGetDatum(result)));
- if (result != (unsigned char *) VARDATA(string))
+ /* build text data type structre. we cannot use textin() here,
+ since textin assumes that input string encoding is same as
+ database encoding. */
+ len = strlen(result) + VARHDRSZ;
+ retval = palloc(len);
+ VARATT_SIZEP(retval) = len;
+ memcpy(VARDATA(retval), result, len - VARHDRSZ);
+
+ if (result != str)
pfree(result);
+ pfree(str);
/* free memory if allocated by the toaster */
PG_FREE_IF_COPY(string, 0);