File 2129-Fix-compile-forms-1-2-crash-when-not-in-an-existing-.patch of Package erlang

From afff8b0fd74fda09ba8dc5f7bfe95b5cb345872e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org>
Date: Wed, 23 Mar 2016 07:00:34 +0100
Subject: [PATCH] Fix compile:forms/1,2 crash when not in an existing directory

compile:forms/1,2 will crash when the current working directory has
been deleted. Fix that problem, and while we are at it, also stop
including {source,""} in module_info() when no source code file is
given.

Reported-at: http://bugs.erlang.org/browse/ERL-113
Reported-by: Adam Lindberg
---
 lib/compiler/src/beam_asm.erl       |  6 +++++-
 lib/compiler/src/compile.erl        | 12 ++++++++++-
 lib/compiler/test/compile_SUITE.erl | 42 ++++++++++++++++++++++++++++++-------
 3 files changed, 51 insertions(+), 9 deletions(-)

diff --git a/lib/compiler/src/beam_asm.erl b/lib/compiler/src/beam_asm.erl
index 95be471..28fd061 100644
--- a/lib/compiler/src/beam_asm.erl
+++ b/lib/compiler/src/beam_asm.erl
@@ -225,10 +225,14 @@ flatten_imports(Imps) ->
     list_to_binary(map(fun({M,F,A}) -> <<M:32,F:32,A:32>> end, Imps)).
 
 build_attributes(Opts, SourceFile, Attr, MD5) ->
+    Misc0 = case SourceFile of
+		[] -> [];
+		[_|_] -> [{source,SourceFile}]
+	    end,
     Misc = case member(slim, Opts) of
 	       false ->
 		   {{Y,Mo,D},{H,Mi,S}} = erlang:universaltime(),
-		   [{time,{Y,Mo,D,H,Mi,S}},{source,SourceFile}];
+		   [{time,{Y,Mo,D,H,Mi,S}}|Misc0];
 	       true -> []
 	   end,
     Compile = [{options,Opts},{version,?COMPILER_VSN}|Misc],
diff --git a/lib/compiler/src/compile.erl b/lib/compiler/src/compile.erl
index 332bc0b..65566df 100644
--- a/lib/compiler/src/compile.erl
+++ b/lib/compiler/src/compile.erl
@@ -1328,7 +1328,7 @@ save_core_code(St) ->
 
 beam_asm(#compile{ifile=File,code=Code0,
 		  abstract_code=Abst,mod_options=Opts0}=St) ->
-    Source = filename:absname(File),
+    Source = paranoid_absname(File),
     Opts1 = lists:map(fun({debug_info_key,_}) -> {debug_info_key,'********'};
 			 (Other) -> Other
 		      end, Opts0),
@@ -1337,6 +1337,16 @@ beam_asm(#compile{ifile=File,code=Code0,
 	{ok,Code} -> {ok,St#compile{code=Code,abstract_code=[]}}
     end.
 
+paranoid_absname(""=File) ->
+    File;
+paranoid_absname(File) ->
+    case file:get_cwd() of
+	{ok,Cwd} ->
+	    filename:absname(File, Cwd);
+	_ ->
+	    File
+    end.
+
 test_native(#compile{options=Opts}) ->
     %% This test is done late, in case some other option has turned off native.
     %% 'native' given on the command line can be overridden by
diff --git a/lib/compiler/test/compile_SUITE.erl b/lib/compiler/test/compile_SUITE.erl
index fc04c9a..f1e7577 100644
--- a/lib/compiler/test/compile_SUITE.erl
+++ b/lib/compiler/test/compile_SUITE.erl
@@ -127,13 +127,39 @@ forms_2(Config) when is_list(Config) ->
     Src = "/foo/bar",
     AbsSrc = filename:absname(Src),
     Anno = erl_anno:new(1),
-    {ok,simple,Binary} = compile:forms([{attribute,Anno,module,simple}],
-				       [binary,{source,Src}]),
-    code:load_binary(simple, Src, Binary),
-    Info = simple:module_info(compile),
+    SimpleCode = [{attribute,Anno,module,simple}],
+    {ok,simple,Bin1} = compile:forms(SimpleCode, [binary,{source,Src}]),
 
-    %% Test that the proper source is returned.
-    AbsSrc = proplists:get_value(source, Info),
+    %% Load and test that the proper source is returned.
+    AbsSrc = forms_load_code(simple, Src, Bin1),
+
+    %% Work in a deleted directory.
+    PrivDir = proplists:get_value(priv_dir, Config),
+    WorkDir = filename:join(PrivDir, ?FUNCTION_NAME),
+    ok = file:make_dir(WorkDir),
+    ok = file:set_cwd(WorkDir),
+    case os:type() of
+	{unix,_} -> os:cmd("rm -rf " ++ WorkDir);
+	_ -> ok
+    end,
+    {ok,simple,Bin2} = compile:forms(SimpleCode),
+    undefined = forms_load_code(simple, "ignore", Bin2),
+
+    {ok,simple,Bin3} = compile:forms(SimpleCode, [{source,Src},report]),
+    case forms_load_code(simple, "ignore", Bin3) of
+	Src ->					%Unix.
+	    ok;
+	AbsSrc ->				%Windows.
+	    ok
+    end,
+
+    ok.
+
+
+forms_load_code(Mod, Src, Bin) ->
+    {module,Mod} = code:load_binary(Mod, Src, Bin),
+    Info = Mod:module_info(compile),
+    SourceOption = proplists:get_value(source, Info),
 
     %% Ensure that the options are not polluted with 'source'.
     [] = proplists:get_value(options, Info),
@@ -141,7 +167,9 @@ forms_2(Config) when is_list(Config) ->
     %% Cleanup.
     true = code:delete(simple),
     false = code:purge(simple),
-    ok.
+
+    SourceOption.
+
 
 module_mismatch(Config) when is_list(Config) ->
     DataDir = proplists:get_value(data_dir, Config),
-- 
2.1.4

openSUSE Build Service is sponsored by