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

Commitfd9e2ac

Browse files
committed
When we are in error recursion trouble, arrange to suppress translation and
encoding conversion of any elog/ereport message being sent to the frontend.This generalizes a patch that I put in last October, which suppressedtranslation of only specific messages known to be associated with recursivecan't-translate-the-message behavior. As shown in bug #4680, we need a moregeneral answer in order to have some hope of coping with broken encodingconversion setups. This approach seems a good deal less klugy anyway.Patch in all supported branches.
1 parent32032d4 commitfd9e2ac

File tree

4 files changed

+102
-56
lines changed

4 files changed

+102
-56
lines changed

‎src/backend/libpq/pqformat.c

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
2525
* Portions Copyright (c) 1994, Regents of the University of California
2626
*
27-
*$PostgreSQL: pgsql/src/backend/libpq/pqformat.c,v 1.48 2009/01/01 17:23:42 momjian Exp $
27+
*$PostgreSQL: pgsql/src/backend/libpq/pqformat.c,v 1.49 2009/03/02 21:18:43 tgl Exp $
2828
*
2929
*-------------------------------------------------------------------------
3030
*/
@@ -41,6 +41,7 @@
4141
*pq_sendcountedtext - append a counted text string (with character set conversion)
4242
*pq_sendtext- append a text string (with conversion)
4343
*pq_sendstring- append a null-terminated text string (with conversion)
44+
*pq_send_ascii_string - append a null-terminated text string (without conversion)
4445
*pq_endmessage- send the completed message to the frontend
4546
* Note: it is also possible to append data to the StringInfo buffer using
4647
* the regular StringInfo routines, but this is discouraged since required
@@ -184,7 +185,6 @@ void
184185
pq_sendstring(StringInfobuf,constchar*str)
185186
{
186187
intslen=strlen(str);
187-
188188
char*p;
189189

190190
p=pg_server_to_client(str,slen);
@@ -198,6 +198,35 @@ pq_sendstring(StringInfo buf, const char *str)
198198
appendBinaryStringInfo(buf,str,slen+1);
199199
}
200200

201+
/* --------------------------------
202+
*pq_send_ascii_string- append a null-terminated text string (without conversion)
203+
*
204+
* This function intentionally bypasses encoding conversion, instead just
205+
* silently replacing any non-7-bit-ASCII characters with question marks.
206+
* It is used only when we are having trouble sending an error message to
207+
* the client with normal localization and encoding conversion. The caller
208+
* should already have taken measures to ensure the string is just ASCII;
209+
* the extra work here is just to make certain we don't send a badly encoded
210+
* string to the client (which might or might not be robust about that).
211+
*
212+
* NB: passed text string must be null-terminated, and so is the data
213+
* sent to the frontend.
214+
* --------------------------------
215+
*/
216+
void
217+
pq_send_ascii_string(StringInfobuf,constchar*str)
218+
{
219+
while (*str)
220+
{
221+
charch=*str++;
222+
223+
if (IS_HIGHBIT_SET(ch))
224+
ch='?';
225+
appendStringInfoCharMacro(buf,ch);
226+
}
227+
appendStringInfoChar(buf,'\0');
228+
}
229+
201230
/* --------------------------------
202231
*pq_sendint- append a binary integer to a StringInfo buffer
203232
* --------------------------------

‎src/backend/utils/error/elog.c

Lines changed: 62 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
*
4343
*
4444
* IDENTIFICATION
45-
* $PostgreSQL: pgsql/src/backend/utils/error/elog.c,v 1.212 2009/01/19 15:34:23 mha Exp $
45+
* $PostgreSQL: pgsql/src/backend/utils/error/elog.c,v 1.213 2009/03/02 21:18:43 tgl Exp $
4646
*
4747
*-------------------------------------------------------------------------
4848
*/
@@ -72,6 +72,9 @@
7272
#include"utils/ps_status.h"
7373

7474

75+
#undef _
76+
#define_(x) err_gettext(x)
77+
7578
/* Global variables */
7679
ErrorContextCallback*error_context_stack=NULL;
7780

@@ -164,6 +167,25 @@ in_error_recursion_trouble(void)
164167
return (recursion_depth>2);
165168
}
166169

170+
/*
171+
* One of those fallback steps is to stop trying to localize the error
172+
* message, since there's a significant probability that that's exactly
173+
* what's causing the recursion.
174+
*/
175+
staticinlineconstchar*
176+
err_gettext(constchar*str)
177+
{
178+
#ifdefENABLE_NLS
179+
if (in_error_recursion_trouble())
180+
returnstr;
181+
else
182+
returngettext(str);
183+
#else
184+
returnstr;
185+
#endif
186+
}
187+
188+
167189
/*
168190
* errstart --- begin an error-reporting cycle
169191
*
@@ -631,7 +653,7 @@ errcode_for_socket_access(void)
631653
char *fmtbuf; \
632654
StringInfoDatabuf; \
633655
/* Internationalize the error format string */ \
634-
if (translateit) \
656+
if (translateit&& !in_error_recursion_trouble()) \
635657
fmt=dgettext(edata->domain,fmt); \
636658
/* Expand %m in format string */ \
637659
fmtbuf=expand_fmt_string(fmt,edata); \
@@ -2137,7 +2159,7 @@ send_message_to_server_log(ErrorData *edata)
21372159
}
21382160
else
21392161
{
2140-
char*msg=_("Not safe to send CSV data\n");
2162+
constchar*msg=_("Not safe to send CSV data\n");
21412163

21422164
write(fileno(stderr),msg,strlen(msg));
21432165
if (!(Log_destination&LOG_DESTINATION_STDERR)&&
@@ -2189,6 +2211,26 @@ write_pipe_chunks(char *data, int len, int dest)
21892211
}
21902212

21912213

2214+
/*
2215+
* Append a text string to the error report being built for the client.
2216+
*
2217+
* This is ordinarily identical to pq_sendstring(), but if we are in
2218+
* error recursion trouble we skip encoding conversion, because of the
2219+
* possibility that the problem is a failure in the encoding conversion
2220+
* subsystem itself. Code elsewhere should ensure that the passed-in
2221+
* strings will be plain 7-bit ASCII, and thus not in need of conversion,
2222+
* in such cases. (In particular, we disable localization of error messages
2223+
* to help ensure that's true.)
2224+
*/
2225+
staticvoid
2226+
err_sendstring(StringInfobuf,constchar*str)
2227+
{
2228+
if (in_error_recursion_trouble())
2229+
pq_send_ascii_string(buf,str);
2230+
else
2231+
pq_sendstring(buf,str);
2232+
}
2233+
21922234
/*
21932235
* Write error report to client
21942236
*/
@@ -2208,7 +2250,7 @@ send_message_to_frontend(ErrorData *edata)
22082250
inti;
22092251

22102252
pq_sendbyte(&msgbuf,PG_DIAG_SEVERITY);
2211-
pq_sendstring(&msgbuf,error_severity(edata->elevel));
2253+
err_sendstring(&msgbuf,error_severity(edata->elevel));
22122254

22132255
/* unpack MAKE_SQLSTATE code */
22142256
ssval=edata->sqlerrcode;
@@ -2220,72 +2262,72 @@ send_message_to_frontend(ErrorData *edata)
22202262
tbuf[i]='\0';
22212263

22222264
pq_sendbyte(&msgbuf,PG_DIAG_SQLSTATE);
2223-
pq_sendstring(&msgbuf,tbuf);
2265+
err_sendstring(&msgbuf,tbuf);
22242266

22252267
/* M field is required per protocol, so always send something */
22262268
pq_sendbyte(&msgbuf,PG_DIAG_MESSAGE_PRIMARY);
22272269
if (edata->message)
2228-
pq_sendstring(&msgbuf,edata->message);
2270+
err_sendstring(&msgbuf,edata->message);
22292271
else
2230-
pq_sendstring(&msgbuf,_("missing error text"));
2272+
err_sendstring(&msgbuf,_("missing error text"));
22312273

22322274
if (edata->detail)
22332275
{
22342276
pq_sendbyte(&msgbuf,PG_DIAG_MESSAGE_DETAIL);
2235-
pq_sendstring(&msgbuf,edata->detail);
2277+
err_sendstring(&msgbuf,edata->detail);
22362278
}
22372279

22382280
/* detail_log is intentionally not used here */
22392281

22402282
if (edata->hint)
22412283
{
22422284
pq_sendbyte(&msgbuf,PG_DIAG_MESSAGE_HINT);
2243-
pq_sendstring(&msgbuf,edata->hint);
2285+
err_sendstring(&msgbuf,edata->hint);
22442286
}
22452287

22462288
if (edata->context)
22472289
{
22482290
pq_sendbyte(&msgbuf,PG_DIAG_CONTEXT);
2249-
pq_sendstring(&msgbuf,edata->context);
2291+
err_sendstring(&msgbuf,edata->context);
22502292
}
22512293

22522294
if (edata->cursorpos>0)
22532295
{
22542296
snprintf(tbuf,sizeof(tbuf),"%d",edata->cursorpos);
22552297
pq_sendbyte(&msgbuf,PG_DIAG_STATEMENT_POSITION);
2256-
pq_sendstring(&msgbuf,tbuf);
2298+
err_sendstring(&msgbuf,tbuf);
22572299
}
22582300

22592301
if (edata->internalpos>0)
22602302
{
22612303
snprintf(tbuf,sizeof(tbuf),"%d",edata->internalpos);
22622304
pq_sendbyte(&msgbuf,PG_DIAG_INTERNAL_POSITION);
2263-
pq_sendstring(&msgbuf,tbuf);
2305+
err_sendstring(&msgbuf,tbuf);
22642306
}
22652307

22662308
if (edata->internalquery)
22672309
{
22682310
pq_sendbyte(&msgbuf,PG_DIAG_INTERNAL_QUERY);
2269-
pq_sendstring(&msgbuf,edata->internalquery);
2311+
err_sendstring(&msgbuf,edata->internalquery);
22702312
}
22712313

22722314
if (edata->filename)
22732315
{
22742316
pq_sendbyte(&msgbuf,PG_DIAG_SOURCE_FILE);
2275-
pq_sendstring(&msgbuf,edata->filename);
2317+
err_sendstring(&msgbuf,edata->filename);
22762318
}
22772319

22782320
if (edata->lineno>0)
22792321
{
22802322
snprintf(tbuf,sizeof(tbuf),"%d",edata->lineno);
22812323
pq_sendbyte(&msgbuf,PG_DIAG_SOURCE_LINE);
2282-
pq_sendstring(&msgbuf,tbuf);
2324+
err_sendstring(&msgbuf,tbuf);
22832325
}
22842326

22852327
if (edata->funcname)
22862328
{
22872329
pq_sendbyte(&msgbuf,PG_DIAG_SOURCE_FUNCTION);
2288-
pq_sendstring(&msgbuf,edata->funcname);
2330+
err_sendstring(&msgbuf,edata->funcname);
22892331
}
22902332

22912333
pq_sendbyte(&msgbuf,'\0');/* terminator */
@@ -2316,7 +2358,7 @@ send_message_to_frontend(ErrorData *edata)
23162358

23172359
appendStringInfoChar(&buf,'\n');
23182360

2319-
pq_sendstring(&msgbuf,buf.data);
2361+
err_sendstring(&msgbuf,buf.data);
23202362

23212363
pfree(buf.data);
23222364
}
@@ -2430,10 +2472,6 @@ useful_strerror(int errnum)
24302472

24312473
/*
24322474
* error_severity --- get localized string representing elevel
2433-
*
2434-
* Note: in an error recursion situation, we stop localizing the tags
2435-
* for ERROR and above. This is necessary because the problem might be
2436-
* failure to convert one of these strings to the client encoding.
24372475
*/
24382476
staticconstchar*
24392477
error_severity(intelevel)
@@ -2463,22 +2501,13 @@ error_severity(int elevel)
24632501
prefix=_("WARNING");
24642502
break;
24652503
caseERROR:
2466-
if (in_error_recursion_trouble())
2467-
prefix="ERROR";
2468-
else
2469-
prefix=_("ERROR");
2504+
prefix=_("ERROR");
24702505
break;
24712506
caseFATAL:
2472-
if (in_error_recursion_trouble())
2473-
prefix="FATAL";
2474-
else
2475-
prefix=_("FATAL");
2507+
prefix=_("FATAL");
24762508
break;
24772509
casePANIC:
2478-
if (in_error_recursion_trouble())
2479-
prefix="PANIC";
2480-
else
2481-
prefix=_("PANIC");
2510+
prefix=_("PANIC");
24822511
break;
24832512
default:
24842513
prefix="???";

‎src/backend/utils/mb/wchar.c

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* conversion functions between pg_wchar and multibyte streams.
33
* Tatsuo Ishii
4-
* $PostgreSQL: pgsql/src/backend/utils/mb/wchar.c,v 1.71 2009/02/10 19:29:39 petere Exp $
4+
* $PostgreSQL: pgsql/src/backend/utils/mb/wchar.c,v 1.72 2009/03/02 21:18:43 tgl Exp $
55
*
66
*/
77
/* can be used in either frontend or backend */
@@ -1636,25 +1636,12 @@ report_untranslatable_char(int src_encoding, int dest_encoding,
16361636
for (j=0;j<jlimit;j++)
16371637
p+=sprintf(p,"%02x", (unsignedchar)mbstr[j]);
16381638

1639-
/*
1640-
* In an error recursion situation, don't try to translate the message.
1641-
* This gets us out of trouble if the problem is failure to convert
1642-
* this very message (after translation) to the client encoding.
1643-
*/
1644-
if (in_error_recursion_trouble())
1645-
ereport(ERROR,
1646-
(errcode(ERRCODE_UNTRANSLATABLE_CHARACTER),
1647-
errmsg_internal("character 0x%s of encoding \"%s\" has no equivalent in \"%s\"",
1648-
buf,
1649-
pg_enc2name_tbl[src_encoding].name,
1650-
pg_enc2name_tbl[dest_encoding].name)));
1651-
else
1652-
ereport(ERROR,
1653-
(errcode(ERRCODE_UNTRANSLATABLE_CHARACTER),
1654-
errmsg("character 0x%s of encoding \"%s\" has no equivalent in \"%s\"",
1655-
buf,
1656-
pg_enc2name_tbl[src_encoding].name,
1657-
pg_enc2name_tbl[dest_encoding].name)));
1639+
ereport(ERROR,
1640+
(errcode(ERRCODE_UNTRANSLATABLE_CHARACTER),
1641+
errmsg("character 0x%s of encoding \"%s\" has no equivalent in \"%s\"",
1642+
buf,
1643+
pg_enc2name_tbl[src_encoding].name,
1644+
pg_enc2name_tbl[dest_encoding].name)));
16581645
}
16591646

16601647
#endif

‎src/include/libpq/pqformat.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
9-
* $PostgreSQL: pgsql/src/include/libpq/pqformat.h,v 1.27 2009/01/01 17:23:59 momjian Exp $
9+
* $PostgreSQL: pgsql/src/include/libpq/pqformat.h,v 1.28 2009/03/02 21:18:43 tgl Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -22,6 +22,7 @@ extern void pq_sendcountedtext(StringInfo buf, const char *str, int slen,
2222
boolcountincludesself);
2323
externvoidpq_sendtext(StringInfobuf,constchar*str,intslen);
2424
externvoidpq_sendstring(StringInfobuf,constchar*str);
25+
externvoidpq_send_ascii_string(StringInfobuf,constchar*str);
2526
externvoidpq_sendint(StringInfobuf,inti,intb);
2627
externvoidpq_sendint64(StringInfobuf,int64i);
2728
externvoidpq_sendfloat4(StringInfobuf,float4f);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp