diff options
Diffstat (limited to 'lib/stdlib/test')
| -rw-r--r-- | lib/stdlib/test/escript_SUITE.erl | 126 | ||||
| -rw-r--r-- | lib/stdlib/test/escript_SUITE_data/archive_script_file_access/archive_script_file_access.erl | 86 | 
2 files changed, 210 insertions, 2 deletions
| diff --git a/lib/stdlib/test/escript_SUITE.erl b/lib/stdlib/test/escript_SUITE.erl index 7ed1ee742a..253b18ecb0 100644 --- a/lib/stdlib/test/escript_SUITE.erl +++ b/lib/stdlib/test/escript_SUITE.erl @@ -1,7 +1,7 @@  %%  %% %CopyrightBegin%  %% -%% Copyright Ericsson AB 2007-2011. All Rights Reserved. +%% Copyright Ericsson AB 2007-2012. All Rights Reserved.  %%  %% The contents of this file are subject to the Erlang Public License,  %% Version 1.1, (the "License"); you may not use this file except in @@ -29,6 +29,7 @@  	 module_script/1,  	 beam_script/1,  	 archive_script/1, +	 archive_script_file_access/1,  	 epp/1,  	 create_and_extract/1,  	 foldl/1, @@ -44,7 +45,8 @@ suite() -> [{ct_hooks,[ts_install_cth]}].  all() ->       [basic, errors, strange_name, emulator_flags,       module_script, beam_script, archive_script, epp, -     create_and_extract, foldl, overflow]. +     create_and_extract, foldl, overflow, +     archive_script_file_access].  groups() ->       []. @@ -464,6 +466,126 @@ archive_script(Config) when is_list(Config) ->      ok. +%% Test the correction of OTP-10071 +%% The errors identified are +%% +%% * If primary archive was named "xxx", then a file in the same +%%   directory named "xxxyyy" would be interpreted as a file named yyy +%%   inside the archive. +%% +%% * erl_prim_loader did not correctly create and normalize absolute +%%   paths for primary archive and files inside it, so unless given +%%   with exact same path files inside the archive would not be +%%   found. E.g. if escript was started as ./xxx then "xxx/file" would +%%   not be found since erl_prim_loader would try to match +%%   /full/path/to/xxx with /full/path/to/./xxx. Same problem with +%%   ../ +%% +%% * Depending on how the primary archive was built, +%%   erl_prim_loader:list_dir/1 would sometimes return an empty string +%%   inside the file list. This was a virtual element representing the +%%   top directory of the archive. This shall not occur. +%% +archive_script_file_access(Config) when is_list(Config) -> +    %% Copy the orig files to priv_dir +    DataDir = ?config(data_dir, Config), +    PrivDir = ?config(priv_dir, Config), + +    MainMod = "archive_script_file_access", +    MainSrc = MainMod ++ ".erl", +    MainBeam = MainMod ++ ".beam", + +    Archive = filename:join([PrivDir, "archive_script_file_access.zip"]), +    ?line {ok, _} = zip:create(Archive, ["archive_script_file_access"], +			       [{compress, []}, {cwd, DataDir}]), +    ?line {ok, _} = zip:extract(Archive, [{cwd, PrivDir}]), +    TopDir = filename:join([PrivDir, "archive_script_file_access"]), + +    %% Compile the code +    ?line ok = compile_files([MainSrc], TopDir, TopDir), + +    %% First, create a file structure which will be included in the archive: +    %% +    %% dir1/ +    %% dir1/subdir1/ +    %% dir1/subdir1/file1 +    %% +    {ok, OldDir} = file:get_cwd(), +    ok = file:set_cwd(TopDir), +    DummyDir = "dir1", +    DummySubDir = filename:join(DummyDir, "subdir1"), +    RelDummyFile = filename:join(DummySubDir, "file1"), +    DummyFile = filename:join(TopDir,RelDummyFile), +    ok = filelib:ensure_dir(DummyFile), +    ok = file:write_file(DummyFile, ["foo\nbar\nbaz"]), + +    %% 1. Create zip archive by adding the dummy file and the beam +    %%    file as binaries to zip. +    %% +    %% This used to provoke the following issues when the script was run as +    %% "./<script_name>": +    %% a. erl_prim_loader:read_file_info/1 returning 'error' +    %% b. erl_prim_loader:list_dir/1 returning {ok, ["dir1", [], "file1"]} +    %%    leading to an infinite loop in reltool_target:spec_dir/1 +    Files1 = +	lists:map(fun(Filename) -> +			  {ok, Bin} = file:read_file(Filename), +			  {Filename,Bin} +		  end, +		  [RelDummyFile,MainBeam]), +    {ok, {"mem", Bin1}} = zip:create("mem", Files1, [memory]), + +    %% Create the escript +    ScriptName1 = "archive_script_file_access1", +    Script1 = filename:join([PrivDir, ScriptName1]), +    Flags = "-escript main " ++ MainMod, +    ok = escript:create(Script1,[shebang,{emu_args,Flags},{archive,Bin1}]), +    ok = file:change_mode(Script1,8#00744), + +    %% Also add a dummy file in the same directory with the same name +    %% as the script except is also has an extension. This used to +    %% cause erl_prim_loader to believe it was a file inside the +    %% script. +    ok = file:write_file(Script1 ++ ".extension", +			 <<"same name as script, but with extension">>), + +    %% Change to script's directory and run it as "./<script_name>" +    ok = file:set_cwd(PrivDir), +    do_run(PrivDir, "./" ++ ScriptName1, +	   [<<"file_access:[]\n", +	      "ExitCode:0">>]), +    ok = file:set_cwd(TopDir), + + +    %% 2. Create zip archive by letting zip read the files from the file system +    %% +    %% The difference compared to the archive_script_file_access1 is +    %% that this will have a file element for each directory in the +    %% archive - while archive_script_file_access1 will only have a +    %% file element per regular file. +    Files2 = [DummyDir,MainBeam], +    {ok, {"mem", Bin2}} = zip:create("mem", Files2, [memory]), + +    %% Create the escript +    ScriptName2 = "archive_script_file_access2", +    Script2 = filename:join([PrivDir, ScriptName2]), +    ok = escript:create(Script2,[shebang,{emu_args,Flags},{archive,Bin2}]), +    ok = file:change_mode(Script2,8#00744), + +    %% Also add a dummy file in the same directory with the same name +    %% as the script except is also has an extension. This used to +    %% cause erl_prim_loader to believe it was a file inside the +    %% script. +    ok = file:write_file(Script2 ++ ".extension", +			 <<"same name as script, but with extension">>), + +    %% Change to script's directory and run it as "./<script_name>" +    ok = file:set_cwd(PrivDir), +    do_run(PrivDir, "./" ++ ScriptName2, +	   [<<"file_access:[]\n", +	      "ExitCode:0">>]), +    ok = file:set_cwd(OldDir). +  compile_app(TopDir, AppName) ->      AppDir = filename:join([TopDir, AppName]),      SrcDir = filename:join([AppDir, "src"]), diff --git a/lib/stdlib/test/escript_SUITE_data/archive_script_file_access/archive_script_file_access.erl b/lib/stdlib/test/escript_SUITE_data/archive_script_file_access/archive_script_file_access.erl new file mode 100644 index 0000000000..226a8675db --- /dev/null +++ b/lib/stdlib/test/escript_SUITE_data/archive_script_file_access/archive_script_file_access.erl @@ -0,0 +1,86 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2012. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +-module(archive_script_file_access). +-behaviour(escript). + +-export([main/1]). + +-include_lib("kernel/include/file.hrl"). + +main(MainArgs) -> +    io:format("file_access:~p\n", [MainArgs]), +    ArchiveFile = escript:script_name(), + +    AbsArchiveFile = filename:absname(ArchiveFile), +    RelArchiveFile = filename:basename(ArchiveFile), +    DotSlashArchiveFile = "./" ++ RelArchiveFile, + +    Beam = atom_to_list(?MODULE) ++ ".beam", +    AbsBeam = filename:join(AbsArchiveFile,Beam), +    RelBeam = filename:join(RelArchiveFile,Beam), +    DotSlashBeam = filename:join(DotSlashArchiveFile,Beam), +    Dir = "dir1", +    AbsDir = filename:join(AbsArchiveFile,Dir), +    RelDir = filename:join(RelArchiveFile,Dir), +    DotSlashDir = filename:join(DotSlashArchiveFile,Dir), + +    {ok,List1} = erl_prim_loader:list_dir(AbsArchiveFile), +    {ok,List1} = erl_prim_loader:list_dir(RelArchiveFile), +    {ok,List1} = erl_prim_loader:list_dir(DotSlashArchiveFile), +    {ok,List1} = erl_prim_loader:list_dir(AbsArchiveFile ++ "/"), +    {ok,List1} = erl_prim_loader:list_dir(AbsArchiveFile ++ "/."), +    {ok,List1} = erl_prim_loader:list_dir(filename:join([AbsDir,".."])), +    {ok,List1} = erl_prim_loader:list_dir(filename:join([RelDir,".."])), +    {ok,List1} = erl_prim_loader:list_dir(filename:join([DotSlashDir,".."])), +    false = lists:member([],List1), + +    {ok,List2} = erl_prim_loader:list_dir(AbsDir), +    {ok,List2} = erl_prim_loader:list_dir(RelDir), +    {ok,List2} = erl_prim_loader:list_dir(DotSlashDir), +    false = lists:member([],List2), + +    error = erl_prim_loader:list_dir(AbsBeam), +    error = erl_prim_loader:list_dir(RelBeam), +    error = erl_prim_loader:list_dir(DotSlashBeam), + +    error = erl_prim_loader:get_file(AbsArchiveFile), +    error = erl_prim_loader:get_file(RelArchiveFile), +    error = erl_prim_loader:get_file(DotSlashArchiveFile), +    error = erl_prim_loader:get_file(AbsArchiveFile ++ "/"), +    error = erl_prim_loader:get_file(AbsArchiveFile ++ "/."), +    {ok,Bin,AbsBeam} = erl_prim_loader:get_file(AbsBeam), +    {ok,Bin,RelBeam} = erl_prim_loader:get_file(RelBeam), +    {ok,Bin,DotSlashBeam} = erl_prim_loader:get_file(DotSlashBeam), + +    {ok,#file_info{type=directory}=DFI} = +	erl_prim_loader:read_file_info(AbsArchiveFile), +    {ok,DFI} = erl_prim_loader:read_file_info(RelArchiveFile), +    {ok,DFI} = erl_prim_loader:read_file_info(DotSlashArchiveFile), +    {ok,DFI} = erl_prim_loader:read_file_info(AbsArchiveFile ++ "/"), +    {ok,DFI} = erl_prim_loader:read_file_info(AbsArchiveFile ++ "/."), +    {ok,#file_info{type=regular}=RFI} = erl_prim_loader:read_file_info(AbsBeam), +    {ok,RFI} = erl_prim_loader:read_file_info(RelBeam), +    {ok,RFI} = erl_prim_loader:read_file_info(DotSlashBeam), + +    F = AbsArchiveFile ++ ".extension", +    error = erl_prim_loader:list_dir(F), +    {ok,_,_} = erl_prim_loader:get_file(F), +    {ok,#file_info{type=regular}} = erl_prim_loader:read_file_info(F), + +    ok. | 
