@@ -3851,6 +3851,29 @@ select * from plpgsql_check_function('dyn_sql_3');
3851
3851
Context: SQL statement "SELECT r.c"
3852
3852
(2 rows)
3853
3853
3854
+ drop function dyn_sql_3();
3855
+ create or replace function dyn_sql_3()
3856
+ returns void as $$
3857
+ declare
3858
+ r record;
3859
+ v text = 'select 10 a, 20 b't;
3860
+ begin
3861
+ select 10 a, 20 b into r;
3862
+ for r in execute v
3863
+ loop
3864
+ raise notice '%', r.a;
3865
+ end loop;
3866
+ end
3867
+ $$ language plpgsql;
3868
+ -- should be warning
3869
+ select * from plpgsql_check_function('dyn_sql_3');
3870
+ plpgsql_check_function
3871
+ ---------------------------------------------------------------------------------------
3872
+ warning:00000:7:FOR over EXECUTE statement:cannot determinate a result of dynamic SQL
3873
+ Detail: There is a risk of related false alarms.
3874
+ Hint: Don't use dynamic SQL and record type together, when you would check function.
3875
+ (3 rows)
3876
+
3854
3877
drop function dyn_sql_3();
3855
3878
create or replace function dyn_sql_4()
3856
3879
returns table(ax int, bx int) as $$
@@ -3885,3 +3908,100 @@ select * from plpgsql_check_function('dyn_sql_4()');
3885
3908
(2 rows)
3886
3909
3887
3910
drop function dyn_sql_4();
3911
+ create or replace function test_bug(text)
3912
+ returns regproc as $$
3913
+ begin
3914
+ return $1::regproc;
3915
+ exception when undefined_function or invalid_name then
3916
+ raise;
3917
+ end;
3918
+ $$ language plpgsql;
3919
+ -- should not raise a exception
3920
+ select * from plpgsql_check_function('test_bug');
3921
+ plpgsql_check_function
3922
+ ------------------------
3923
+ (0 rows)
3924
+
3925
+ create or replace function test_bug(text)
3926
+ returns regproc as $$
3927
+ begin
3928
+ return $1::regproc;
3929
+ exception when undefined_function or invalid_name then
3930
+ raise notice '%', $1; -- bug
3931
+ end;
3932
+ $$ language plpgsql;
3933
+ select test_bug('kuku'); -- should to fail
3934
+ NOTICE: kuku
3935
+ ERROR: control reached end of function without RETURN
3936
+ CONTEXT: PL/pgSQL function test_bug(text)
3937
+ select * from plpgsql_check_function('test_bug');
3938
+ plpgsql_check_function
3939
+ --------------------------------------------------------------------
3940
+ warning extra:2F005:control reached end of function without RETURN
3941
+ (1 row)
3942
+
3943
+ drop function test_bug(text);
3944
+ create or replace function test_bug(text)
3945
+ returns regproc as $$
3946
+ begin
3947
+ return $1::regproc;
3948
+ exception when undefined_function or invalid_name then
3949
+ raise notice '%', $1;
3950
+ return NULL;
3951
+ end;
3952
+ $$ language plpgsql;
3953
+ select test_bug('kuku'); -- should be ok
3954
+ NOTICE: kuku
3955
+ test_bug
3956
+ ----------
3957
+
3958
+ (1 row)
3959
+
3960
+ select * from plpgsql_check_function('test_bug');
3961
+ plpgsql_check_function
3962
+ ------------------------
3963
+ (0 rows)
3964
+
3965
+ drop function test_bug(text);
3966
+ create or replace function foo(a text, b text)
3967
+ returns void as $$
3968
+ begin
3969
+ -- unsecure
3970
+ execute 'select ' || a;
3971
+ a := quote_literal(a); -- is safe now
3972
+ execute 'select ' || a;
3973
+ a := a || b; -- it is unsecure again
3974
+ execute 'select ' || a;
3975
+ end;
3976
+ $$ language plpgsql;
3977
+ \sf+ foo(text, text)
3978
+ CREATE OR REPLACE FUNCTION public.foo(a text, b text)
3979
+ RETURNS void
3980
+ LANGUAGE plpgsql
3981
+ 1 AS $function$
3982
+ 2 begin
3983
+ 3 -- unsecure
3984
+ 4 execute 'select ' || a;
3985
+ 5 a := quote_literal(a); -- is safe now
3986
+ 6 execute 'select ' || a;
3987
+ 7 a := a || b; -- it is unsecure again
3988
+ 8 execute 'select ' || a;
3989
+ 9 end;
3990
+ 10 $function$
3991
+ -- should to raise two warnings
3992
+ select * from plpgsql_check_function('foo', security_warnings := true);
3993
+ plpgsql_check_function
3994
+ -----------------------------------------------------------------------------
3995
+ security:00000:4:EXECUTE:text type variable is not sanitized
3996
+ Query: SELECT 'select ' || a
3997
+ -- ^
3998
+ Detail: The EXECUTE expression is SQL injection vulnerable.
3999
+ Hint: Use quote_ident, quote_literal or format function to secure variable.
4000
+ security:00000:8:EXECUTE:text type variable is not sanitized
4001
+ Query: SELECT 'select ' || a
4002
+ -- ^
4003
+ Detail: The EXECUTE expression is SQL injection vulnerable.
4004
+ Hint: Use quote_ident, quote_literal or format function to secure variable.
4005
+ (10 rows)
4006
+
4007
+ drop function foo(text, text);
0 commit comments