diff options
author | Björn Gustavsson <bjorn@erlang.org> | 2021-08-31 06:20:35 +0200 |
---|---|---|
committer | Björn Gustavsson <bjorn@erlang.org> | 2021-08-31 06:59:55 +0200 |
commit | cb2b510e5000a8344c9a8a78a1054bf29e99c9ee (patch) | |
tree | 74ca7ab0262f7cc239e7318fc95531dfb178455a | |
parent | 1c63b200a677ec7ac12202ddbcf7710884b16ff2 (diff) | |
download | erlang-cb2b510e5000a8344c9a8a78a1054bf29e99c9ee.tar.gz |
Correct extended error for binary_to_term/2
When `binary_to_term/2` failed with a `badarg` exception, the extended error
information would always blame the second argument even if the error was
in the first argument:
1> binary_to_term(<<"">>, []).
** exception error: bad argument
in function binary_to_term/2
called as binary_to_term(<<>>,[])
*** argument 2: invalid option in list
2> binary_to_term(<<131,100,0,10,97,95,110,101,119,95,97,116,111,109>>, [safe]).
** exception error: bad argument
in function binary_to_term/2
called as binary_to_term(<<131,100,0,10,97,95,110,101,119,95,97,116,111,109>>,
[safe])
*** argument 2: invalid option in list
Correct the extended error information like this:
1> binary_to_term(<<"">>, []).
** exception error: bad argument
in function binary_to_term/2
called as binary_to_term(<<>>,[])
*** argument 1: invalid external representation of a term
2> binary_to_term(<<131,100,0,10,97,95,110,101,119,95,97,116,111,109>>, [safe]).
** exception error: bad argument
in function binary_to_term/2
called as binary_to_term(<<131,100,0,10,97,95,110,101,119,95,97,116,111,109>>,
[safe])
*** argument 1: invalid or unsafe external representation of a term
Closes #5171.
-rw-r--r-- | erts/emulator/beam/external.c | 3 | ||||
-rw-r--r-- | erts/emulator/test/exception_SUITE.erl | 13 | ||||
-rw-r--r-- | lib/kernel/src/erl_erts_errors.erl | 22 |
3 files changed, 32 insertions, 6 deletions
diff --git a/erts/emulator/beam/external.c b/erts/emulator/beam/external.c index 6bfd9fa825..efb315842a 100644 --- a/erts/emulator/beam/external.c +++ b/erts/emulator/beam/external.c @@ -2101,7 +2101,8 @@ BIF_RETTYPE binary_to_term_2(BIF_ALIST_2) return binary_to_term_int(BIF_P, BIF_ARG_1, &ctx); error: - BIF_ERROR(BIF_P, BADARG); + BIF_P->fvalue = am_badopt; + BIF_ERROR(BIF_P, BADARG | EXF_HAS_EXT_INFO); } Eterm diff --git a/erts/emulator/test/exception_SUITE.erl b/erts/emulator/test/exception_SUITE.erl index 18a5dda447..746993bf34 100644 --- a/erts/emulator/test/exception_SUITE.erl +++ b/erts/emulator/test/exception_SUITE.erl @@ -680,7 +680,7 @@ do_error_3(Reason, Args, Options) -> error_info(_Config) -> DeadProcess = dead_process(), - NewAtom = non_existing_atom(), + {NewAtom,NewAtomExt} = non_existing_atom(), Eons = 1 bsl 50, %% We'll need an incorrect memory type for erlang:memory/1. We want to test an @@ -767,9 +767,14 @@ error_info(_Config) -> {binary_to_list, [<<1,2,3>>, 4, 5]}, {binary_to_term, [abc]}, - {binary_to_term, [<<"abc">>]}, + {binary_to_term, [<<"bad">>]}, + {binary_to_term, [term_to_binary(a), abc]}, {binary_to_term, [<<"bad">>, abc]}, + {binary_to_term, [<<"bad">>, [bad]]}, + {binary_to_term, [<<"bad">>, []]}, + {binary_to_term, [<<"bad">>, [safe]]}, + {binary_to_term, [NewAtomExt, [safe]]}, {bit_size, [abc]}, {bitstring_to_list, [abc]}, @@ -1322,7 +1327,9 @@ non_existing_atom(Atom) -> non_existing_atom([Char|Atom]) catch error:badarg -> - Atom + AtomBin = list_to_binary(Atom), + AtomExt = <<131,100,(byte_size(AtomBin)):16,AtomBin/binary>>, + {Atom,AtomExt} end. do_error_info(L0) -> diff --git a/lib/kernel/src/erl_erts_errors.erl b/lib/kernel/src/erl_erts_errors.erl index 0b2b89ceac..8b0768ac80 100644 --- a/lib/kernel/src/erl_erts_errors.erl +++ b/lib/kernel/src/erl_erts_errors.erl @@ -264,9 +264,25 @@ format_erlang_error(binary_to_list, [Bin,Start,Stop], _) -> end; format_erlang_error(binary_to_term, [Bin], _) -> [must_be_binary(Bin, bad_ext_term)]; -format_erlang_error(binary_to_term, [Bin,Options], _) -> +format_erlang_error(binary_to_term, [Bin,Options], Cause) -> Arg1 = must_be_binary(Bin), - [Arg1,maybe_option_list_error(Options, Arg1)]; + Arg2 = case Cause of + badopt -> + must_be_list(Options, bad_option); + _ -> + [] + end, + case {Arg1,Arg2} of + {[],[]} -> + case lists:member(safe, Options) of + true -> + [bad_or_unsafe_ext_term]; + false -> + [bad_ext_term] + end; + {_,_} -> + [Arg1,Arg2] + end; format_erlang_error(bitstring_to_list, [_], _) -> [not_bitstring]; format_erlang_error(bump_reductions, [Int], _) -> @@ -1290,6 +1306,8 @@ expand_error(bad_encode_option) -> <<"not one of the atoms: latin1, utf8, or unicode">>; expand_error(bad_ext_term) -> <<"invalid external representation of a term">>; +expand_error(bad_or_unsafe_ext_term) -> + <<"invalid or unsafe external representation of a term">>; expand_error(bad_isdst) -> <<"not 'true', 'false', or 'undefined'">>; expand_error(bad_localtime) -> |