Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitbe4b8a8

Browse files
committed
Don't use %s-with-precision format spec to truncate data being displayed
in a COPY error message. It seems that glibc gets indigestion if it isasked to truncate strings that contain invalid UTF-8 encoding sequences.vsnprintf will return -1 in such cases, leading to looping and eventualmemory overflow in elog.c. Instead use our own, more robust pg_mbcliplenroutine. I believe this problem accounts for several recent reports ofunexpected 'out of memory' errors during COPY IN.
1 parent6bdfde9 commitbe4b8a8

File tree

1 file changed

+48
-12
lines changed

1 file changed

+48
-12
lines changed

‎src/backend/commands/copy.c

Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/commands/copy.c,v 1.214 2003/11/29 19:51:47 pgsql Exp $
11+
* $PostgreSQL: pgsql/src/backend/commands/copy.c,v 1.215 2004/01/18 02:15:29 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -139,6 +139,7 @@ static Datum CopyReadBinaryAttribute(int column_no, FmgrInfo *flinfo,
139139
Oidtypelem,bool*isnull);
140140
staticvoidCopyAttributeOut(char*string,char*delim);
141141
staticList*CopyGetAttnums(Relationrel,List*attnamelist);
142+
staticvoidlimit_printout_length(StringInfobuf);
142143

143144
/* Internal communications functions */
144145
staticvoidSendCopyBegin(boolbinary,intnatts);
@@ -1140,8 +1141,6 @@ CopyTo(Relation rel, List *attnumlist, bool binary, bool oids,
11401141
staticvoid
11411142
copy_in_error_callback(void*arg)
11421143
{
1143-
#defineMAX_COPY_DATA_DISPLAY 100
1144-
11451144
if (copy_binary)
11461145
{
11471146
/* can't usefully display the data */
@@ -1156,17 +1155,18 @@ copy_in_error_callback(void *arg)
11561155
if (copy_attname)
11571156
{
11581157
/* error is relevant to a particular column */
1159-
errcontext("COPY %s, line %d, column %s: \"%.*s%s\"",
1158+
limit_printout_length(&attribute_buf);
1159+
errcontext("COPY %s, line %d, column %s: \"%s\"",
11601160
copy_relname,copy_lineno,copy_attname,
1161-
MAX_COPY_DATA_DISPLAY,attribute_buf.data,
1162-
(attribute_buf.len>MAX_COPY_DATA_DISPLAY) ?"..." :"");
1161+
attribute_buf.data);
11631162
}
11641163
else
11651164
{
11661165
/* error is relevant to a particular line */
11671166
if (!line_buf_converted)
11681167
{
11691168
/* didn't convert the encoding yet... */
1169+
line_buf_converted= true;
11701170
if (client_encoding!=server_encoding)
11711171
{
11721172
char*cvt;
@@ -1181,16 +1181,46 @@ copy_in_error_callback(void *arg)
11811181
appendBinaryStringInfo(&line_buf,cvt,strlen(cvt));
11821182
}
11831183
}
1184-
line_buf_converted= true;
11851184
}
1186-
errcontext("COPY %s, line %d: \"%.*s%s\"",
1185+
limit_printout_length(&line_buf);
1186+
errcontext("COPY %s, line %d: \"%s\"",
11871187
copy_relname,copy_lineno,
1188-
MAX_COPY_DATA_DISPLAY,line_buf.data,
1189-
(line_buf.len>MAX_COPY_DATA_DISPLAY) ?"..." :"");
1188+
line_buf.data);
11901189
}
11911190
}
11921191
}
11931192

1193+
/*
1194+
* Make sure we don't print an unreasonable amount of COPY data in a message.
1195+
*
1196+
* It would seem a lot easier to just use the sprintf "precision" limit to
1197+
* truncate the string. However, some versions of glibc have a bug/misfeature
1198+
* that vsnprintf will always fail (return -1) if it is asked to truncate
1199+
* a string that contains invalid byte sequences for the current encoding.
1200+
* So, do our own truncation. We assume we can alter the StringInfo buffer
1201+
* holding the input data.
1202+
*/
1203+
staticvoid
1204+
limit_printout_length(StringInfobuf)
1205+
{
1206+
#defineMAX_COPY_DATA_DISPLAY 100
1207+
1208+
intlen;
1209+
1210+
/* Fast path if definitely okay */
1211+
if (buf->len <=MAX_COPY_DATA_DISPLAY)
1212+
return;
1213+
1214+
/* Apply encoding-dependent truncation */
1215+
len=pg_mbcliplen(buf->data,buf->len,MAX_COPY_DATA_DISPLAY);
1216+
if (buf->len <=len)
1217+
return;/* no need to truncate */
1218+
buf->len=len;
1219+
buf->data[len]='\0';
1220+
1221+
/* Add "..." to show we truncated the input */
1222+
appendStringInfoString(buf,"...");
1223+
}
11941224

11951225
/*
11961226
* Copy FROM file to relation.
@@ -1875,7 +1905,15 @@ CopyReadLine(void)
18751905

18761906
/*
18771907
* Done reading the line. Convert it to server encoding.
1908+
*
1909+
* Note: set line_buf_converted to true *before* attempting conversion;
1910+
* this prevents infinite recursion during error reporting should
1911+
* pg_client_to_server() issue an error, due to copy_in_error_callback
1912+
* again attempting the same conversion. We'll end up issuing the message
1913+
* without conversion, which is bad but better than nothing ...
18781914
*/
1915+
line_buf_converted= true;
1916+
18791917
if (change_encoding)
18801918
{
18811919
cvt= (char*)pg_client_to_server((unsignedchar*)line_buf.data,
@@ -1889,8 +1927,6 @@ CopyReadLine(void)
18891927
}
18901928
}
18911929

1892-
line_buf_converted= true;
1893-
18941930
returnresult;
18951931
}
18961932

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp