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

Commitb62c870

Browse files
committed
Fix plperl to handle non-ASCII error message texts correctly.
We were passing error message texts to croak() verbatim, which turns outnot to work if the text contains non-ASCII characters; Perl mangles theirencoding, as reported in bug #13638 from Michal Leinweber. To fix, convertthe text into a UTF8-encoded SV first.It's hard to test this without risking failures in different databaseencodings; but we can follow the lead of plpython, which is alreadyassuming that no-break space (U+00A0) has an equivalent in all encodingswe care about running the regression tests in (cf commit2dfa15d).Back-patch to 9.1. The code is quite different in 9.0, and anyway it seemstoo risky to put something like this into 9.0's final minor release.Alex Hunsaker, with suggestions from Tim Bunce and Tom Lane
1 parent8400829 commitb62c870

File tree

7 files changed

+87
-8
lines changed

7 files changed

+87
-8
lines changed

‎src/pl/plperl/SPI.xs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ do_plperl_return_next(SV *sv)
4141
FlushErrorState();
4242

4343
/* Punt the error to Perl */
44-
croak("%s",edata->message);
44+
croak_cstr(edata->message);
4545
}
4646
PG_END_TRY();
4747
}

‎src/pl/plperl/Util.xs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ do_util_elog(int level, SV *msg)
5858
pfree(cmsg);
5959

6060
/* Punt the error to Perl */
61-
croak("%s",edata->message);
61+
croak_cstr(edata->message);
6262
}
6363
PG_END_TRY();
6464
}

‎src/pl/plperl/expected/plperl_elog.out

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,3 +104,16 @@ PL/Perl function "indirect_die_caller"
104104
2
105105
(1 row)
106106

107+
-- Test non-ASCII error messages
108+
--
109+
-- Note: this test case is known to fail if the database encoding is
110+
-- EUC_CN, EUC_JP, EUC_KR, or EUC_TW, for lack of any equivalent to
111+
-- U+00A0 (no-break space) in those encodings. However, testing with
112+
-- plain ASCII data would be rather useless, so we must live with that.
113+
SET client_encoding TO UTF8;
114+
create or replace function error_with_nbsp() returns void language plperl as $$
115+
elog(ERROR, "this message contains a no-break space");
116+
$$;
117+
select error_with_nbsp();
118+
ERROR: this message contains a no-break space at line 2.
119+
CONTEXT: PL/Perl function "error_with_nbsp"

‎src/pl/plperl/expected/plperl_elog_1.out

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,3 +104,16 @@ PL/Perl function "indirect_die_caller"
104104
2
105105
(1 row)
106106

107+
-- Test non-ASCII error messages
108+
--
109+
-- Note: this test case is known to fail if the database encoding is
110+
-- EUC_CN, EUC_JP, EUC_KR, or EUC_TW, for lack of any equivalent to
111+
-- U+00A0 (no-break space) in those encodings. However, testing with
112+
-- plain ASCII data would be rather useless, so we must live with that.
113+
SET client_encoding TO UTF8;
114+
create or replace function error_with_nbsp() returns void language plperl as $$
115+
elog(ERROR, "this message contains a no-break space");
116+
$$;
117+
select error_with_nbsp();
118+
ERROR: this message contains a no-break space at line 2.
119+
CONTEXT: PL/Perl function "error_with_nbsp"

‎src/pl/plperl/plperl.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3005,7 +3005,7 @@ plperl_spi_exec(char *query, int limit)
30053005
SPI_restore_connection();
30063006

30073007
/* Punt the error to Perl */
3008-
croak("%s",edata->message);
3008+
croak_cstr(edata->message);
30093009

30103010
/* Can't get here, but keep compiler quiet */
30113011
returnNULL;
@@ -3238,7 +3238,7 @@ plperl_spi_query(char *query)
32383238
SPI_restore_connection();
32393239

32403240
/* Punt the error to Perl */
3241-
croak("%s",edata->message);
3241+
croak_cstr(edata->message);
32423242

32433243
/* Can't get here, but keep compiler quiet */
32443244
returnNULL;
@@ -3324,7 +3324,7 @@ plperl_spi_fetchrow(char *cursor)
33243324
SPI_restore_connection();
33253325

33263326
/* Punt the error to Perl */
3327-
croak("%s",edata->message);
3327+
croak_cstr(edata->message);
33283328

33293329
/* Can't get here, but keep compiler quiet */
33303330
returnNULL;
@@ -3499,7 +3499,7 @@ plperl_spi_prepare(char *query, int argc, SV **argv)
34993499
SPI_restore_connection();
35003500

35013501
/* Punt the error to Perl */
3502-
croak("%s",edata->message);
3502+
croak_cstr(edata->message);
35033503

35043504
/* Can't get here, but keep compiler quiet */
35053505
returnNULL;
@@ -3640,7 +3640,7 @@ plperl_spi_exec_prepared(char *query, HV *attr, int argc, SV **argv)
36403640
SPI_restore_connection();
36413641

36423642
/* Punt the error to Perl */
3643-
croak("%s",edata->message);
3643+
croak_cstr(edata->message);
36443644

36453645
/* Can't get here, but keep compiler quiet */
36463646
returnNULL;
@@ -3769,7 +3769,7 @@ plperl_spi_query_prepared(char *query, int argc, SV **argv)
37693769
SPI_restore_connection();
37703770

37713771
/* Punt the error to Perl */
3772-
croak("%s",edata->message);
3772+
croak_cstr(edata->message);
37733773

37743774
/* Can't get here, but keep compiler quiet */
37753775
returnNULL;

‎src/pl/plperl/plperl_helpers.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,4 +121,42 @@ cstr2sv(const char *str)
121121
returnsv;
122122
}
123123

124+
/*
125+
* croak() with specified message, which is given in the database encoding.
126+
*
127+
* Ideally we'd just write croak("%s", str), but plain croak() does not play
128+
* nice with non-ASCII data. In modern Perl versions we can call cstr2sv()
129+
* and pass the result to croak_sv(); in versions that don't have croak_sv(),
130+
* we have to work harder.
131+
*/
132+
staticinlinevoid
133+
croak_cstr(constchar*str)
134+
{
135+
#ifdefcroak_sv
136+
/* Use sv_2mortal() to be sure the transient SV gets freed */
137+
croak_sv(sv_2mortal(cstr2sv(str)));
138+
#else
139+
140+
/*
141+
* The older way to do this is to assign a UTF8-marked value to ERRSV and
142+
* then call croak(NULL). But if we leave it to croak() to append the
143+
* error location, it does so too late (only after popping the stack) in
144+
* some Perl versions. Hence, use mess() to create an SV with the error
145+
* location info already appended.
146+
*/
147+
SV*errsv=get_sv("@",GV_ADD);
148+
char*utf8_str=utf_e2u(str);
149+
SV*ssv;
150+
151+
ssv=mess("%s",utf8_str);
152+
SvUTF8_on(ssv);
153+
154+
pfree(utf8_str);
155+
156+
sv_setsv(errsv,ssv);
157+
158+
croak(NULL);
159+
#endif/* croak_sv */
160+
}
161+
124162
#endif/* PL_PERL_HELPERS_H */

‎src/pl/plperl/sql/plperl_elog.sql

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,3 +76,18 @@ return $a + $b;
7676
$$;
7777

7878
select indirect_die_caller();
79+
80+
-- Test non-ASCII error messages
81+
--
82+
-- Note: this test case is known to fail if the database encoding is
83+
-- EUC_CN, EUC_JP, EUC_KR, or EUC_TW, for lack of any equivalent to
84+
-- U+00A0 (no-break space) in those encodings. However, testing with
85+
-- plain ASCII data would be rather useless, so we must live with that.
86+
87+
SET client_encoding TO UTF8;
88+
89+
create or replacefunctionerror_with_nbsp() returns void language plperlas $$
90+
elog(ERROR,"this message contains a no-break space");
91+
$$;
92+
93+
select error_with_nbsp();

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp