Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit a626045

Browse files
committed
Fix up plperl 'use_strict' so that it can be enabled or disabled on the
fly. Fix problem with incompletely duplicated setup code. Andrew Dunstan, from an idea of Michael Fuhr's.
1 parent a06d98b commit a626045

File tree

3 files changed

+139
-83
lines changed

3 files changed

+139
-83
lines changed

src/pl/plperl/expected/plperl_elog.out

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,38 @@ create or replace function perl_warn(text) returns void language plperl as $$
1919

2020
$$;
2121
select perl_warn('implicit elog via warn');
22-
NOTICE: implicit elog via warn at (eval 7) line 4.
22+
NOTICE: implicit elog via warn at line 4.
2323

2424
perl_warn
2525
-----------
2626

2727
(1 row)
2828

29+
-- test strict mode on/off
30+
SET plperl.use_strict = true;
31+
create or replace function uses_global() returns text language plperl as $$
32+
33+
$global = 1;
34+
$other_global = 2;
35+
return 'uses_global worked';
36+
37+
$$;
38+
ERROR: creation of Perl function failed: Global symbol "$global" requires explicit package name at line 3.
39+
Global symbol "$other_global" requires explicit package name at line 4.
40+
select uses_global();
41+
ERROR: function uses_global() does not exist
42+
HINT: No function matches the given name and argument types. You may need to add explicit type casts.
43+
SET plperl.use_strict = false;
44+
create or replace function uses_global() returns text language plperl as $$
45+
46+
$global = 1;
47+
$other_global=2;
48+
return 'uses_global worked';
49+
50+
$$;
51+
select uses_global();
52+
uses_global
53+
--------------------
54+
uses_global worked
55+
(1 row)
56+

src/pl/plperl/plperl.c

Lines changed: 88 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
* ENHANCEMENTS, OR MODIFICATIONS.
3434
*
3535
* IDENTIFICATION
36-
* $PostgreSQL: pgsql/src/pl/plperl/plperl.c,v 1.90 2005/08/20 19:19:21 tgl Exp $
36+
* $PostgreSQL: pgsql/src/pl/plperl/plperl.c,v 1.91 2005/08/24 18:16:56 tgl Exp $
3737
*
3838
**********************************************************************/
3939

@@ -185,57 +185,88 @@ plperl_init_all(void)
185185
/* We don't need to do anything yet when a new backend starts. */
186186
}
187187

188+
/* Each of these macros must represent a single string literal */
189+
190+
#define PERLBOOT \
191+
"SPI::bootstrap(); use vars qw(%_SHARED);" \
192+
"sub ::plperl_warn { my $msg = shift; " \
193+
" $msg =~ s/\\(eval \\d+\\) //g; &elog(&NOTICE, $msg); } " \
194+
"$SIG{__WARN__} = \\&::plperl_warn; " \
195+
"sub ::plperl_die { my $msg = shift; " \
196+
" $msg =~ s/\\(eval \\d+\\) //g; die $msg; } " \
197+
"$SIG{__DIE__} = \\&::plperl_die; " \
198+
"sub ::mkunsafefunc {" \
199+
" my $ret = eval(qq[ sub { $_[0] $_[1] } ]); " \
200+
" $@ =~ s/\\(eval \\d+\\) //g if $@; return $ret; }" \
201+
"use strict; " \
202+
"sub ::mk_strict_unsafefunc {" \
203+
" my $ret = eval(qq[ sub { use strict; $_[0] $_[1] } ]); " \
204+
" $@ =~ s/\\(eval \\d+\\) //g if $@; return $ret; } " \
205+
"sub ::_plperl_to_pg_array {" \
206+
" my $arg = shift; ref $arg eq 'ARRAY' || return $arg; " \
207+
" my $res = ''; my $first = 1; " \
208+
" foreach my $elem (@$arg) " \
209+
" { " \
210+
" $res .= ', ' unless $first; $first = undef; " \
211+
" if (ref $elem) " \
212+
" { " \
213+
" $res .= _plperl_to_pg_array($elem); " \
214+
" } " \
215+
" else " \
216+
" { " \
217+
" my $str = qq($elem); " \
218+
" $str =~ s/([\"\\\\])/\\\\$1/g; " \
219+
" $res .= qq(\"$str\"); " \
220+
" } " \
221+
" } " \
222+
" return qq({$res}); " \
223+
"} "
224+
225+
#define SAFE_MODULE \
226+
"require Safe; $Safe::VERSION"
227+
228+
#define SAFE_OK \
229+
"use vars qw($PLContainer); $PLContainer = new Safe('PLPerl');" \
230+
"$PLContainer->permit_only(':default');" \
231+
"$PLContainer->permit(qw[:base_math !:base_io sort time]);" \
232+
"$PLContainer->share(qw[&elog &spi_exec_query &return_next " \
233+
"&spi_query &spi_fetchrow " \
234+
"&_plperl_to_pg_array " \
235+
"&DEBUG &LOG &INFO &NOTICE &WARNING &ERROR %_SHARED ]);" \
236+
"sub ::mksafefunc {" \
237+
" my $ret = $PLContainer->reval(qq[sub { $_[0] $_[1] }]); " \
238+
" $@ =~ s/\\(eval \\d+\\) //g if $@; return $ret; }" \
239+
"$PLContainer->permit('require'); $PLContainer->reval('use strict;');" \
240+
"$PLContainer->deny('require');" \
241+
"sub ::mk_strict_safefunc {" \
242+
" my $ret = $PLContainer->reval(qq[sub { BEGIN { strict->import(); } $_[0] $_[1] }]); " \
243+
" $@ =~ s/\\(eval \\d+\\) //g if $@; return $ret; }"
244+
245+
#define SAFE_BAD \
246+
"use vars qw($PLContainer); $PLContainer = new Safe('PLPerl');" \
247+
"$PLContainer->permit_only(':default');" \
248+
"$PLContainer->share(qw[&elog &ERROR ]);" \
249+
"sub ::mksafefunc { return $PLContainer->reval(qq[sub { " \
250+
" elog(ERROR,'trusted Perl functions disabled - " \
251+
" please upgrade Perl Safe module to version 2.09 or later');}]); }" \
252+
"sub ::mk_strict_safefunc { return $PLContainer->reval(qq[sub { " \
253+
" elog(ERROR,'trusted Perl functions disabled - " \
254+
" please upgrade Perl Safe module to version 2.09 or later');}]); }"
255+
188256

189257
static void
190258
plperl_init_interp(void)
191259
{
192-
static char *loose_embedding[3] = {
193-
"", "-e",
194-
/* all one string follows (no commas please) */
195-
"SPI::bootstrap(); use vars qw(%_SHARED);"
196-
"sub ::plperl_warn { my $msg = shift; &elog(&NOTICE, $msg); } "
197-
"$SIG{__WARN__} = \\&::plperl_warn; "
198-
"sub ::mkunsafefunc {return eval(qq[ sub { $_[0] $_[1] } ]); }"
199-
"sub ::_plperl_to_pg_array"
200-
"{"
201-
" my $arg = shift; ref $arg eq 'ARRAY' || return $arg; "
202-
" my $res = ''; my $first = 1; "
203-
" foreach my $elem (@$arg) "
204-
" { "
205-
" $res .= ', ' unless $first; $first = undef; "
206-
" if (ref $elem) "
207-
" { "
208-
" $res .= _plperl_to_pg_array($elem); "
209-
" } "
210-
" else "
211-
" { "
212-
" my $str = qq($elem); "
213-
" $str =~ s/([\"\\\\])/\\\\$1/g; "
214-
" $res .= qq(\"$str\"); "
215-
" } "
216-
" } "
217-
" return qq({$res}); "
218-
"} "
219-
};
220-
221-
222-
static char *strict_embedding[3] = {
223-
"", "-e",
224-
/* all one string follows (no commas please) */
225-
"SPI::bootstrap(); use vars qw(%_SHARED);"
226-
"sub ::plperl_warn { my $msg = shift; &elog(&NOTICE, $msg); } "
227-
"$SIG{__WARN__} = \\&::plperl_warn; "
228-
"sub ::mkunsafefunc {return eval("
229-
"qq[ sub { use strict; $_[0] $_[1] } ]); }"
260+
static char *embedding[3] = {
261+
"", "-e", PERLBOOT
230262
};
231263

232264
plperl_interp = perl_alloc();
233265
if (!plperl_interp)
234266
elog(ERROR, "could not allocate Perl interpreter");
235267

236268
perl_construct(plperl_interp);
237-
perl_parse(plperl_interp, plperl_init_shared_libs, 3 ,
238-
(plperl_use_strict ? strict_embedding : loose_embedding), NULL);
269+
perl_parse(plperl_interp, plperl_init_shared_libs, 3, embedding, NULL);
239270
perl_run(plperl_interp);
240271

241272
plperl_proc_hash = newHV();
@@ -245,44 +276,10 @@ plperl_init_interp(void)
245276
static void
246277
plperl_safe_init(void)
247278
{
248-
static char *safe_module =
249-
"require Safe; $Safe::VERSION";
250-
251-
static char *common_safe_ok =
252-
"use vars qw($PLContainer); $PLContainer = new Safe('PLPerl');"
253-
"$PLContainer->permit_only(':default');"
254-
"$PLContainer->permit(qw[:base_math !:base_io sort time]);"
255-
"$PLContainer->share(qw[&elog &spi_exec_query &return_next "
256-
"&spi_query &spi_fetchrow "
257-
"&_plperl_to_pg_array "
258-
"&DEBUG &LOG &INFO &NOTICE &WARNING &ERROR %_SHARED ]);"
259-
;
260-
261-
static char * strict_safe_ok =
262-
"$PLContainer->permit('require');$PLContainer->reval('use strict;');"
263-
"$PLContainer->deny('require');"
264-
"sub ::mksafefunc { return $PLContainer->reval(qq[ "
265-
" sub { BEGIN { strict->import(); } $_[0] $_[1]}]); }"
266-
;
267-
268-
static char * loose_safe_ok =
269-
"sub ::mksafefunc { return $PLContainer->reval(qq[ "
270-
" sub { $_[0] $_[1]}]); }"
271-
;
272-
273-
static char *safe_bad =
274-
"use vars qw($PLContainer); $PLContainer = new Safe('PLPerl');"
275-
"$PLContainer->permit_only(':default');"
276-
"$PLContainer->share(qw[&elog &ERROR ]);"
277-
"sub ::mksafefunc { return $PLContainer->reval(qq[sub { "
278-
"elog(ERROR,'trusted Perl functions disabled - "
279-
"please upgrade Perl Safe module to version 2.09 or later');}]); }"
280-
;
281-
282279
SV *res;
283280
double safe_version;
284281

285-
res = eval_pv(safe_module, FALSE); /* TRUE = croak if failure */
282+
res = eval_pv(SAFE_MODULE, FALSE); /* TRUE = croak if failure */
286283

287284
safe_version = SvNV(res);
288285

@@ -294,12 +291,11 @@ plperl_safe_init(void)
294291
if (safe_version < 2.0899 )
295292
{
296293
/* not safe, so disallow all trusted funcs */
297-
eval_pv(safe_bad, FALSE);
294+
eval_pv(SAFE_BAD, FALSE);
298295
}
299296
else
300297
{
301-
eval_pv(common_safe_ok, FALSE);
302-
eval_pv((plperl_use_strict ? strict_safe_ok : loose_safe_ok), FALSE);
298+
eval_pv(SAFE_OK, FALSE);
303299
}
304300

305301
plperl_safe_init_done = true;
@@ -369,7 +365,7 @@ plperl_convert_to_pg_array(SV *src)
369365
XPUSHs(src);
370366
PUTBACK ;
371367

372-
count = call_pv("_plperl_to_pg_array", G_SCALAR);
368+
count = call_pv("::_plperl_to_pg_array", G_SCALAR);
373369

374370
SPAGAIN ;
375371

@@ -661,6 +657,7 @@ plperl_create_sub(char *s, bool trusted)
661657
dSP;
662658
SV *subref;
663659
int count;
660+
char *compile_sub;
664661

665662
if (trusted && !plperl_safe_init_done)
666663
{
@@ -680,8 +677,17 @@ plperl_create_sub(char *s, bool trusted)
680677
* errors properly. Perhaps it's because there's another level of
681678
* eval inside mksafefunc?
682679
*/
683-
count = perl_call_pv((trusted ? "::mksafefunc" : "::mkunsafefunc"),
684-
G_SCALAR | G_EVAL | G_KEEPERR);
680+
681+
if (trusted && plperl_use_strict)
682+
compile_sub = "::mk_strict_safefunc";
683+
else if (plperl_use_strict)
684+
compile_sub = "::mk_strict_unsafefunc";
685+
else if (trusted)
686+
compile_sub = "::mksafefunc";
687+
else
688+
compile_sub = "::mkunsafefunc";
689+
690+
count = perl_call_pv(compile_sub, G_SCALAR | G_EVAL | G_KEEPERR);
685691
SPAGAIN;
686692

687693
if (count != 1)

src/pl/plperl/sql/plperl_elog.sql

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,28 @@ $$;
1818

1919
select perl_warn('implicit elog via warn');
2020

21+
-- test strict mode on/off
2122

23+
SET plperl.use_strict = true;
2224

25+
create or replace function uses_global() returns text language plperl as $$
2326

27+
$global = 1;
28+
$other_global = 2;
29+
return 'uses_global worked';
30+
31+
$$;
32+
33+
select uses_global();
34+
35+
SET plperl.use_strict = false;
36+
37+
create or replace function uses_global() returns text language plperl as $$
38+
39+
$global = 1;
40+
$other_global=2;
41+
return 'uses_global worked';
42+
43+
$$;
44+
45+
select uses_global();

0 commit comments

Comments
 (0)