File 2157-erts-Fix-error-cases-in-enif_get_list_length.patch of Package erlang

From 7a319cd96f7f4869300b32442ebe892ae557f41c Mon Sep 17 00:00:00 2001
From: Sverker Eriksson <sverker@erlang.org>
Date: Mon, 8 Feb 2016 15:47:49 +0100
Subject: [PATCH] erts: Fix error cases in enif_get_list_length

false if improper list
false if length > UINT_MAX
---
 erts/doc/src/erl_nif.xml                      | 2 +-
 erts/emulator/beam/erl_nif.c                  | 9 +++++++--
 erts/emulator/test/nif_SUITE.erl              | 4 ++--
 erts/emulator/test/nif_SUITE_data/nif_SUITE.c | 6 +++++-
 4 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/erts/doc/src/erl_nif.xml b/erts/doc/src/erl_nif.xml
index 420c9fe..be0e406 100644
--- a/erts/doc/src/erl_nif.xml
+++ b/erts/doc/src/erl_nif.xml
@@ -753,7 +753,7 @@ typedef enum {
     <func><name><ret>int</ret><nametext>enif_get_list_length(ErlNifEnv* env, ERL_NIF_TERM term, unsigned* len)</nametext></name>
       <fsummary>Get the length of list <c>term</c></fsummary>
       <desc><p>Set <c>*len</c> to the length of list <c>term</c> and return true,
-      or return false if <c>term</c> is not a list.</p></desc>
+      or return false if <c>term</c> is not a proper list.</p></desc>
     </func>
     <func><name><ret>int</ret><nametext>enif_get_long(ErlNifEnv* env, ERL_NIF_TERM term, long int* ip)</nametext></name>
       <fsummary>Read an long integer term</fsummary>
diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c
index b057ec7..12aaf4c 100644
--- a/erts/emulator/beam/erl_nif.c
+++ b/erts/emulator/beam/erl_nif.c
@@ -911,8 +911,13 @@ int enif_get_list_cell(ErlNifEnv* env, Eterm term, Eterm* head, Eterm* tail)
 
 int enif_get_list_length(ErlNifEnv* env, Eterm term, unsigned* len)
 {
-    if (is_not_list(term) && is_not_nil(term)) return 0;
-    *len = erts_list_length(term);
+    Sint i;
+    Uint u;
+
+    if ((i = erts_list_length(term)) < 0) return 0;
+    u = (Uint)i;
+    if ((unsigned)u != u) return 0;
+    *len = u;
     return 1;
 }
 
diff --git a/erts/emulator/test/nif_SUITE.erl b/erts/emulator/test/nif_SUITE.erl
index b02a090..bfec474 100644
--- a/erts/emulator/test/nif_SUITE.erl
+++ b/erts/emulator/test/nif_SUITE.erl
@@ -1398,7 +1398,7 @@ is_checks(Config) when is_list(Config) ->
 get_length(doc) -> ["Test all enif_get_length functions"];
 get_length(Config) when is_list(Config) ->
     ?line ensure_lib_loaded(Config, 1),
-    ?line ok = length_test(hejsan, "hejsan", [], [], not_a_list).
+    ?line ok = length_test(hejsan, "hejsan", [], [], not_a_list, [1,2|3]).
 
 ensure_lib_loaded(Config) ->
     ensure_lib_loaded(Config, 1).
@@ -1951,7 +1951,7 @@ last_resource_dtor_call() -> ?nif_stub.
 make_new_resource(_,_) -> ?nif_stub.
 check_is(_,_,_,_,_,_,_,_,_,_,_) -> ?nif_stub.
 check_is_exception() -> ?nif_stub.
-length_test(_,_,_,_,_) -> ?nif_stub.
+length_test(_,_,_,_,_,_) -> ?nif_stub.
 make_atoms() -> ?nif_stub.
 make_strings() -> ?nif_stub.
 make_new_resource_binary(_) -> ?nif_stub.
diff --git a/erts/emulator/test/nif_SUITE_data/nif_SUITE.c b/erts/emulator/test/nif_SUITE_data/nif_SUITE.c
index 8ebce4f..1acb270 100644
--- a/erts/emulator/test/nif_SUITE_data/nif_SUITE.c
+++ b/erts/emulator/test/nif_SUITE_data/nif_SUITE.c
@@ -914,6 +914,7 @@ static ERL_NIF_TERM check_is_exception(ErlNifEnv* env, int argc, const ERL_NIF_T
  * argv[2] empty list
  * argv[3] not an atom
  * argv[4] not a list
+ * argv[5] improper list
  */
 static ERL_NIF_TERM length_test(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
 {
@@ -934,6 +935,9 @@ static ERL_NIF_TERM length_test(ErlNifEnv* env, int argc, const ERL_NIF_TERM arg
     if (enif_get_list_length(env, argv[4], &len))
 	return enif_make_badarg(env);
 
+    if (enif_get_list_length(env, argv[5], &len))
+	return enif_make_badarg(env);
+
     return enif_make_atom(env, "ok");
 }
 
@@ -2002,7 +2006,7 @@ static ErlNifFunc nif_funcs[] =
     {"make_new_resource", 2, make_new_resource},
     {"check_is", 11, check_is},
     {"check_is_exception", 0, check_is_exception},
-    {"length_test", 5, length_test},
+    {"length_test", 6, length_test},
     {"make_atoms", 0, make_atoms},
     {"make_strings", 0, make_strings},
     {"make_new_resource", 2, make_new_resource},
-- 
2.1.4

openSUSE Build Service is sponsored by