diff options
author | Tom Lane | 2022-01-31 17:05:37 +0000 |
---|---|---|
committer | Tom Lane | 2022-01-31 17:05:37 +0000 |
commit | c10f830c511f0ba3e6f4c9d99f444d39e30440c8 (patch) | |
tree | b32f2568f2a3d243acbf29113ac1c87a8bae8520 /src/test | |
parent | c89f409749c35bf18fab8e025a34645dd925390c (diff) |
Make canonicalize_path() more canonical.
Teach canonicalize_path() how to strip all unnecessary uses of "."
and "..", replacing the previous ad-hoc code that got rid of only
some such cases. In particular, we can always remove all such
uses from absolute paths.
The proximate reason to do this is that Windows rejects paths
involving ".." in some cases (in particular, you can't put one in a
symlink), so we ought to be sure we don't use ".." unnecessarily.
Moreover, it seems like good cleanup on general principles.
There is other path-munging code that could be simplified now, but
we'll leave that for followup work.
It is tempting to call this a bug fix and back-patch it. On the other
hand, the misbehavior can only be reached if a highly privileged user
does something dubious, so it's not unreasonable to say "so don't do
that". And this patch could result in unexpected behavioral changes,
in case anybody was expecting uses of ".." to stay put. So at least
for now, just put it in HEAD.
Shenhao Wang, editorialized a bit by me
Discussion: https://postgr.es/m/OSBPR01MB4214FA221FFE046F11F2AD74F2D49@OSBPR01MB4214.jpnprd01.prod.outlook.com
Diffstat (limited to 'src/test')
-rw-r--r-- | src/test/regress/expected/create_function_1.out | 4 | ||||
-rw-r--r-- | src/test/regress/expected/misc_functions.out | 135 | ||||
-rw-r--r-- | src/test/regress/regress.c | 10 | ||||
-rw-r--r-- | src/test/regress/sql/create_function_1.sql | 5 | ||||
-rw-r--r-- | src/test/regress/sql/misc_functions.sql | 27 |
5 files changed, 181 insertions, 0 deletions
diff --git a/src/test/regress/expected/create_function_1.out b/src/test/regress/expected/create_function_1.out index 5345ed08400..6141b7060b1 100644 --- a/src/test/regress/expected/create_function_1.out +++ b/src/test/regress/expected/create_function_1.out @@ -28,3 +28,7 @@ CREATE FUNCTION int44out(city_budget) AS :'regresslib' LANGUAGE C STRICT IMMUTABLE; NOTICE: argument type city_budget is only a shell +CREATE FUNCTION test_canonicalize_path(text) + RETURNS text + AS :'regresslib' + LANGUAGE C STRICT IMMUTABLE; diff --git a/src/test/regress/expected/misc_functions.out b/src/test/regress/expected/misc_functions.out index e2c77d0ac84..6cf39c6bd2d 100644 --- a/src/test/regress/expected/misc_functions.out +++ b/src/test/regress/expected/misc_functions.out @@ -134,6 +134,141 @@ LINE 1: SELECT num_nulls(); ^ HINT: No function matches the given name and argument types. You might need to add explicit type casts. -- +-- canonicalize_path() +-- +SELECT test_canonicalize_path('/'); + test_canonicalize_path +------------------------ + / +(1 row) + +SELECT test_canonicalize_path('/./abc/def/'); + test_canonicalize_path +------------------------ + /abc/def +(1 row) + +SELECT test_canonicalize_path('/./../abc/def'); + test_canonicalize_path +------------------------ + /abc/def +(1 row) + +SELECT test_canonicalize_path('/./../../abc/def/'); + test_canonicalize_path +------------------------ + /abc/def +(1 row) + +SELECT test_canonicalize_path('/abc/.././def/ghi'); + test_canonicalize_path +------------------------ + /def/ghi +(1 row) + +SELECT test_canonicalize_path('/abc/./../def/ghi//'); + test_canonicalize_path +------------------------ + /def/ghi +(1 row) + +SELECT test_canonicalize_path('/abc/def/../..'); + test_canonicalize_path +------------------------ + / +(1 row) + +SELECT test_canonicalize_path('/abc/def/../../..'); + test_canonicalize_path +------------------------ + / +(1 row) + +SELECT test_canonicalize_path('/abc/def/../../../../ghi/jkl'); + test_canonicalize_path +------------------------ + /ghi/jkl +(1 row) + +SELECT test_canonicalize_path('.'); + test_canonicalize_path +------------------------ + . +(1 row) + +SELECT test_canonicalize_path('./'); + test_canonicalize_path +------------------------ + . +(1 row) + +SELECT test_canonicalize_path('./abc/..'); + test_canonicalize_path +------------------------ + . +(1 row) + +SELECT test_canonicalize_path('abc/../'); + test_canonicalize_path +------------------------ + . +(1 row) + +SELECT test_canonicalize_path('abc/../def'); + test_canonicalize_path +------------------------ + def +(1 row) + +SELECT test_canonicalize_path('..'); + test_canonicalize_path +------------------------ + .. +(1 row) + +SELECT test_canonicalize_path('../abc/def'); + test_canonicalize_path +------------------------ + ../abc/def +(1 row) + +SELECT test_canonicalize_path('../abc/..'); + test_canonicalize_path +------------------------ + .. +(1 row) + +SELECT test_canonicalize_path('../abc/../def'); + test_canonicalize_path +------------------------ + ../def +(1 row) + +SELECT test_canonicalize_path('../abc/../../def/ghi'); + test_canonicalize_path +------------------------ + ../../def/ghi +(1 row) + +SELECT test_canonicalize_path('./abc/./def/.'); + test_canonicalize_path +------------------------ + abc/def +(1 row) + +SELECT test_canonicalize_path('./abc/././def/.'); + test_canonicalize_path +------------------------ + abc/def +(1 row) + +SELECT test_canonicalize_path('./abc/./def/.././ghi/../../../jkl/mno'); + test_canonicalize_path +------------------------ + ../jkl/mno +(1 row) + +-- -- pg_log_backend_memory_contexts() -- -- Memory contexts are logged and they are not returned to the function. diff --git a/src/test/regress/regress.c b/src/test/regress/regress.c index eefbd0f0dfd..0802fb9136a 100644 --- a/src/test/regress/regress.c +++ b/src/test/regress/regress.c @@ -531,6 +531,16 @@ int44out(PG_FUNCTION_ARGS) PG_RETURN_CSTRING(result); } +PG_FUNCTION_INFO_V1(test_canonicalize_path); +Datum +test_canonicalize_path(PG_FUNCTION_ARGS) +{ + char *path = text_to_cstring(PG_GETARG_TEXT_PP(0)); + + canonicalize_path(path); + PG_RETURN_TEXT_P(cstring_to_text(path)); +} + PG_FUNCTION_INFO_V1(make_tuple_indirect); Datum make_tuple_indirect(PG_FUNCTION_ARGS) diff --git a/src/test/regress/sql/create_function_1.sql b/src/test/regress/sql/create_function_1.sql index 4170b16fe6b..34cc7c6efc4 100644 --- a/src/test/regress/sql/create_function_1.sql +++ b/src/test/regress/sql/create_function_1.sql @@ -29,3 +29,8 @@ CREATE FUNCTION int44out(city_budget) RETURNS cstring AS :'regresslib' LANGUAGE C STRICT IMMUTABLE; + +CREATE FUNCTION test_canonicalize_path(text) + RETURNS text + AS :'regresslib' + LANGUAGE C STRICT IMMUTABLE; diff --git a/src/test/regress/sql/misc_functions.sql b/src/test/regress/sql/misc_functions.sql index 1159f6b5855..cfaba456e15 100644 --- a/src/test/regress/sql/misc_functions.sql +++ b/src/test/regress/sql/misc_functions.sql @@ -31,6 +31,33 @@ SELECT num_nonnulls(); SELECT num_nulls(); -- +-- canonicalize_path() +-- + +SELECT test_canonicalize_path('/'); +SELECT test_canonicalize_path('/./abc/def/'); +SELECT test_canonicalize_path('/./../abc/def'); +SELECT test_canonicalize_path('/./../../abc/def/'); +SELECT test_canonicalize_path('/abc/.././def/ghi'); +SELECT test_canonicalize_path('/abc/./../def/ghi//'); +SELECT test_canonicalize_path('/abc/def/../..'); +SELECT test_canonicalize_path('/abc/def/../../..'); +SELECT test_canonicalize_path('/abc/def/../../../../ghi/jkl'); +SELECT test_canonicalize_path('.'); +SELECT test_canonicalize_path('./'); +SELECT test_canonicalize_path('./abc/..'); +SELECT test_canonicalize_path('abc/../'); +SELECT test_canonicalize_path('abc/../def'); +SELECT test_canonicalize_path('..'); +SELECT test_canonicalize_path('../abc/def'); +SELECT test_canonicalize_path('../abc/..'); +SELECT test_canonicalize_path('../abc/../def'); +SELECT test_canonicalize_path('../abc/../../def/ghi'); +SELECT test_canonicalize_path('./abc/./def/.'); +SELECT test_canonicalize_path('./abc/././def/.'); +SELECT test_canonicalize_path('./abc/./def/.././ghi/../../../jkl/mno'); + +-- -- pg_log_backend_memory_contexts() -- -- Memory contexts are logged and they are not returned to the function. |