From a6944611e262744bc4742e24d1a2bfed2f20fa31 Mon Sep 17 00:00:00 2001 From: Tatsuo Ishii Date: Sat, 6 Jan 2001 03:33:17 +0000 Subject: [PATCH] Fix copy to make it more robust against unexpected character sequences. This is done by disabling multi-byte awareness when it's not necessary. This is kind of a workaround, not a perfect solution. However, there is no ideal way to parse broken multi-byte character sequences. So I guess this is the best way what we could do right now... --- src/backend/commands/copy.c | 64 ++++++++++++++++++++++--------------- 1 file changed, 39 insertions(+), 25 deletions(-) diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c index a7424033af..f33c6e9eb4 100644 --- a/src/backend/commands/copy.c +++ b/src/backend/commands/copy.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.127 2001/01/03 20:04:10 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.128 2001/01/06 03:33:17 ishii Exp $ * *------------------------------------------------------------------------- */ @@ -74,8 +74,8 @@ static bool fe_eof; static StringInfoData attribute_buf; #ifdef MULTIBYTE -static int encoding; - +static int client_encoding; +static int server_encoding; #endif @@ -297,7 +297,8 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe, */ initStringInfo(&attribute_buf); #ifdef MULTIBYTE - encoding = pg_get_client_encoding(); + client_encoding = pg_get_client_encoding(); + server_encoding = GetDatabaseEncoding(); #endif if (from) @@ -1114,29 +1115,35 @@ CopyReadAttribute(FILE *fp, bool *isnull, char *delim, int *newline, char *null_ } appendStringInfoCharMacro(&attribute_buf, c); #ifdef MULTIBYTE - /* get additional bytes of the char, if any */ - s[0] = c; - mblen = pg_encoding_mblen(encoding, s); - for (j = 1; j < mblen; j++) + if (client_encoding != server_encoding) { - c = CopyGetChar(fp); - if (c == EOF) - goto endOfFile; - appendStringInfoCharMacro(&attribute_buf, c); + /* get additional bytes of the char, if any */ + s[0] = c; + mblen = pg_encoding_mblen(client_encoding, s); + for (j = 1; j < mblen; j++) + { + c = CopyGetChar(fp); + if (c == EOF) + goto endOfFile; + appendStringInfoCharMacro(&attribute_buf, c); + } } #endif } #ifdef MULTIBYTE - cvt = (char *) pg_client_to_server((unsigned char *) attribute_buf.data, - attribute_buf.len); - if (cvt != attribute_buf.data) + if (client_encoding != server_encoding) { - /* transfer converted data back to attribute_buf */ - attribute_buf.len = 0; - attribute_buf.data[0] = '\0'; - appendBinaryStringInfo(&attribute_buf, cvt, strlen(cvt)); - pfree(cvt); + cvt = (char *) pg_client_to_server((unsigned char *) attribute_buf.data, + attribute_buf.len); + if (cvt != attribute_buf.data) + { + /* transfer converted data back to attribute_buf */ + attribute_buf.len = 0; + attribute_buf.data[0] = '\0'; + appendBinaryStringInfo(&attribute_buf, cvt, strlen(cvt)); + pfree(cvt); + } } #endif @@ -1163,15 +1170,22 @@ CopyAttributeOut(FILE *fp, char *server_string, char *delim) #endif #ifdef MULTIBYTE - string = (char *) pg_server_to_client((unsigned char *) server_string, - strlen(server_string)); - string_start = string; + if (client_encoding != server_encoding) + { + string = (char *) pg_server_to_client((unsigned char *) server_string, + strlen(server_string)); + string_start = string; + } + else + { + string = server_string; + } #else string = server_string; #endif #ifdef MULTIBYTE - for (; (mblen = pg_encoding_mblen(encoding, string)) && + for (; (mblen = (server_encoding == client_encoding? 1 : pg_encoding_mblen(client_encoding, string))) && ((c = *string) != '\0'); string += mblen) #else for (; (c = *string) != '\0'; string++) @@ -1188,7 +1202,7 @@ CopyAttributeOut(FILE *fp, char *server_string, char *delim) } #ifdef MULTIBYTE - if (string_start != server_string) + if (client_encoding != server_encoding) pfree(string_start); /* pfree pg_server_to_client result */ #endif }