@@ -3820,6 +3820,29 @@ select * from plpgsql_check_function('dyn_sql_3');
3820
3820
Context: SQL statement "SELECT r.c"
3821
3821
(2 rows)
3822
3822
3823
+ drop function dyn_sql_3();
3824
+ create or replace function dyn_sql_3()
3825
+ returns void as $$
3826
+ declare
3827
+ r record;
3828
+ v text = 'select 10 a, 20 b't;
3829
+ begin
3830
+ select 10 a, 20 b into r;
3831
+ for r in execute v
3832
+ loop
3833
+ raise notice '%', r.a;
3834
+ end loop;
3835
+ end
3836
+ $$ language plpgsql;
3837
+ -- should be warning
3838
+ select * from plpgsql_check_function('dyn_sql_3');
3839
+ plpgsql_check_function
3840
+ ---------------------------------------------------------------------------------------
3841
+ warning:00000:7:FOR over EXECUTE statement:cannot determinate a result of dynamic SQL
3842
+ Detail: There is a risk of related false alarms.
3843
+ Hint: Don't use dynamic SQL and record type together, when you would check function.
3844
+ (3 rows)
3845
+
3823
3846
drop function dyn_sql_3();
3824
3847
create or replace function dyn_sql_4()
3825
3848
returns table(ax int, bx int) as $$
@@ -3854,3 +3877,100 @@ select * from plpgsql_check_function('dyn_sql_4()');
3854
3877
(2 rows)
3855
3878
3856
3879
drop function dyn_sql_4();
3880
+ create or replace function test_bug(text)
3881
+ returns regproc as $$
3882
+ begin
3883
+ return $1::regproc;
3884
+ exception when undefined_function or invalid_name then
3885
+ raise;
3886
+ end;
3887
+ $$ language plpgsql;
3888
+ -- should not raise a exception
3889
+ select * from plpgsql_check_function('test_bug');
3890
+ plpgsql_check_function
3891
+ ------------------------
3892
+ (0 rows)
3893
+
3894
+ create or replace function test_bug(text)
3895
+ returns regproc as $$
3896
+ begin
3897
+ return $1::regproc;
3898
+ exception when undefined_function or invalid_name then
3899
+ raise notice '%', $1; -- bug
3900
+ end;
3901
+ $$ language plpgsql;
3902
+ select test_bug('kuku'); -- should to fail
3903
+ NOTICE: kuku
3904
+ ERROR: control reached end of function without RETURN
3905
+ CONTEXT: PL/pgSQL function test_bug(text)
3906
+ select * from plpgsql_check_function('test_bug');
3907
+ plpgsql_check_function
3908
+ --------------------------------------------------------------------
3909
+ warning extra:2F005:control reached end of function without RETURN
3910
+ (1 row)
3911
+
3912
+ drop function test_bug(text);
3913
+ create or replace function test_bug(text)
3914
+ returns regproc as $$
3915
+ begin
3916
+ return $1::regproc;
3917
+ exception when undefined_function or invalid_name then
3918
+ raise notice '%', $1;
3919
+ return NULL;
3920
+ end;
3921
+ $$ language plpgsql;
3922
+ select test_bug('kuku'); -- should be ok
3923
+ NOTICE: kuku
3924
+ test_bug
3925
+ ----------
3926
+
3927
+ (1 row)
3928
+
3929
+ select * from plpgsql_check_function('test_bug');
3930
+ plpgsql_check_function
3931
+ ------------------------
3932
+ (0 rows)
3933
+
3934
+ drop function test_bug(text);
3935
+ create or replace function foo(a text, b text)
3936
+ returns void as $$
3937
+ begin
3938
+ -- unsecure
3939
+ execute 'select ' || a;
3940
+ a := quote_literal(a); -- is safe now
3941
+ execute 'select ' || a;
3942
+ a := a || b; -- it is unsecure again
3943
+ execute 'select ' || a;
3944
+ end;
3945
+ $$ language plpgsql;
3946
+ \sf+ foo(text, text)
3947
+ CREATE OR REPLACE FUNCTION public.foo(a text, b text)
3948
+ RETURNS void
3949
+ LANGUAGE plpgsql
3950
+ 1 AS $function$
3951
+ 2 begin
3952
+ 3 -- unsecure
3953
+ 4 execute 'select ' || a;
3954
+ 5 a := quote_literal(a); -- is safe now
3955
+ 6 execute 'select ' || a;
3956
+ 7 a := a || b; -- it is unsecure again
3957
+ 8 execute 'select ' || a;
3958
+ 9 end;
3959
+ 10 $function$
3960
+ -- should to raise two warnings
3961
+ select * from plpgsql_check_function('foo', security_warnings := true);
3962
+ plpgsql_check_function
3963
+ -----------------------------------------------------------------------------
3964
+ security:00000:4:EXECUTE statement:text type variable is not sanitized
3965
+ Query: SELECT 'select ' || a
3966
+ -- ^
3967
+ Detail: The EXECUTE expression is SQL injection vulnerable.
3968
+ Hint: Use quote_ident, quote_literal or format function to secure variable.
3969
+ security:00000:8:EXECUTE statement:text type variable is not sanitized
3970
+ Query: SELECT 'select ' || a
3971
+ -- ^
3972
+ Detail: The EXECUTE expression is SQL injection vulnerable.
3973
+ Hint: Use quote_ident, quote_literal or format function to secure variable.
3974
+ (10 rows)
3975
+
3976
+ drop function foo(text, text);
0 commit comments