diff options
| author | Björn Gustavsson <[email protected]> | 2019-08-19 15:45:46 +0200 | 
|---|---|---|
| committer | Björn Gustavsson <[email protected]> | 2019-08-22 12:23:45 +0200 | 
| commit | 72f704c7b83643bec889eabe3f9fe378639bb06e (patch) | |
| tree | 6812843aaa76b489604466c687e15c90dc64a43b /lib/stdlib/test | |
| parent | d14919b70af5d08970f0e92aded2b375a79f4d94 (diff) | |
| download | otp-72f704c7b83643bec889eabe3f9fe378639bb06e.tar.gz otp-72f704c7b83643bec889eabe3f9fe378639bb06e.tar.bz2 otp-72f704c7b83643bec889eabe3f9fe378639bb06e.zip | |
Fix filelib:wildcard/1,2 for patterns containing ".." and/or "@"
`..` was broken and only worked when it was used in the beginning
of the pattern before any wildcard characters. For example:
    1> filelib:wildcard("erts/..").
    ["erts/.."]
Using `..` preceded by wildcard characters would not work:
    1> filelib:wildcard("*/..").
    []
`@` is not a wildcard character but is used internally in `filelib` as
an escape character and was not handled as other literal
characters. That could lead to performance degradation as it disabled
an optimization of the matching of the literal prefix of a pattern. It
would also cause the following example to fail:
    1> filelib:wildcard("@/..").
    []
This commit corrects the handling `..` and also makes sure that the
use of `@` in a pattern does not degrade performance.
https://bugs.erlang.org/browse/ERL-1029
Diffstat (limited to 'lib/stdlib/test')
| -rw-r--r-- | lib/stdlib/test/filelib_SUITE.erl | 34 | 
1 files changed, 34 insertions, 0 deletions
| diff --git a/lib/stdlib/test/filelib_SUITE.erl b/lib/stdlib/test/filelib_SUITE.erl index 7403d52881..527d083eaa 100644 --- a/lib/stdlib/test/filelib_SUITE.erl +++ b/lib/stdlib/test/filelib_SUITE.erl @@ -79,9 +79,11 @@ wildcard_one(Config) when is_list(Config) ->      do_wildcard_1(Dir,  		  fun(Wc) ->  			  L = filelib:wildcard(Wc), +			  L = filelib:wildcard(disable_prefix_opt(Wc)),  			  L = filelib:wildcard(Wc, erl_prim_loader),  			  L = filelib:wildcard(Wc, "."),  			  L = filelib:wildcard(Wc, Dir), +			  L = filelib:wildcard(disable_prefix_opt(Wc), Dir),  			  L = filelib:wildcard(Wc, Dir++"/.")  		  end),      file:set_cwd(OldCwd), @@ -119,6 +121,14 @@ wcc(Wc, Error) ->      {'EXIT',{{badpattern,Error},  	     [{filelib,wildcard,2,_}|_]}} = (catch filelib:wildcard(Wc, ".")). +disable_prefix_opt([C|Wc]) when $a =< C, C =< $z; C =:= $@ -> +    %% There is an optimization for patterns that have a literal prefix +    %% (such as "lib/compiler/ebin/*"). Test that we'll get the same result +    %% if we disable that optimization. +    [$[, C, $] | Wc]; +disable_prefix_opt(Wc) -> +    Wc. +  do_wildcard_1(Dir, Wcf0) ->      do_wildcard_2(Dir, Wcf0),      Wcf = fun(Wc0) -> @@ -300,6 +310,30 @@ do_wildcard_10(Dir, Wcf) ->      end,      del(Files), +    wildcard_11(Dir, Wcf). + +%% ERL-ERL-1029/OTP-15987: Fix problems with "@/.." and ".." in general. +wildcard_11(Dir, Wcf) -> +    Dirs0 = ["@","@dir","dir@"], +    Dirs = [filename:join(Dir, D) || D <- Dirs0], +    _ = [ok = file:make_dir(D) || D <- Dirs], +    Files0 = ["@a","b@","x","y","z"], +    Files = mkfiles(Files0, Dir), + +    ["@","@a","@dir","b@","dir@","x","y","z"] = Wcf("*"), +    ["@"] = Wcf("@"), +    ["@","@a","@dir"] = Wcf("@*"), +    ["@/..","@dir/.."] = Wcf("@*/.."), +    ["@/../@","@/../@a","@/../@dir", +     "@dir/../@","@dir/../@a","@dir/../@dir"] = Wcf("@*/../@*"), + +    %% Non-directories followed by "/.." should not match any files. +    [] = Wcf("@a/.."), +    [] = Wcf("x/.."), + +    %% Cleanup. +    del(Files), +    [ok = file:del_dir(D) || D <- Dirs],      ok.  fold_files(Config) when is_list(Config) -> | 
