Skip to content

Commit 6a96312

Browse files
committed
Merge branch 'maint'
2 parents 289ff70 + 49a4686 commit 6a96312

2 files changed

Lines changed: 39 additions & 5 deletions

File tree

erts/emulator/beam/external.c

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2030,11 +2030,25 @@ static BIF_RETTYPE binary_to_term_int(Process* p, Eterm bin, B2TContext *ctx)
20302030
break;
20312031

20322032
case B2TDecodeInit:
2033-
if (is_non_value(ctx->trap_bin) && ctx->b2ts.extsize > ctx->reds) {
2034-
/* dec_term will maybe trap, allocate space for magic bin
2035-
before result term to make it easy to trim with HRelease.
2036-
*/
2037-
ctx = b2t_export_context(p, ctx);
2033+
if (is_non_value(ctx->trap_bin)) {
2034+
if (ctx->b2ts.extsize > ctx->reds) {
2035+
/* dec_term will maybe trap, allocate space for magic bin
2036+
* before result term to make it easy to trim with HRelease.
2037+
*/
2038+
ctx = b2t_export_context(p, ctx);
2039+
}
2040+
else {
2041+
/*
2042+
* We will probably not trap. To ensure we don't,
2043+
* artificially increase our available reductions.
2044+
* This is a workaround for GH-11404. Calling HAlloc()
2045+
* in b2t_export_context() after factory has been created
2046+
* causes problems.
2047+
*/
2048+
const SWord consumed = initial_reds - ctx->reds;
2049+
ctx->reds = (INT_MAX / B2T_MEMCPY_FACTOR);
2050+
initial_reds = ctx->reds + consumed;
2051+
}
20382052
}
20392053
ctx->u.dc.ep = ctx->b2ts.extp;
20402054
ctx->u.dc.res = (Eterm) (UWord) NULL;
@@ -2113,6 +2127,7 @@ static BIF_RETTYPE binary_to_term_int(Process* p, Eterm bin, B2TContext *ctx)
21132127
}while (ctx->reds > 0 || ctx->state >= B2TDone);
21142128

21152129
if (is_non_value(ctx->trap_bin)) {
2130+
ASSERT(ctx->state < B2TDecode);
21162131
ctx = b2t_export_context(p, ctx);
21172132
ASSERT(is_value(ctx->trap_bin));
21182133
}

erts/emulator/test/binary_SUITE.erl

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
bad_binary_to_term_2/1,safe_binary_to_term2/1,
7171
bad_binary_to_term/1, bad_terms/1, more_bad_terms/1,
7272
big_binary_to_term/1,
73+
binary_to_term_trap_crash/1,
7374
otp_5484/1,otp_5933/1,
7475
ordering/1,unaligned_order/1,gc_test/1,
7576
bit_sized_binary_sizes/1,
@@ -101,6 +102,7 @@ all() ->
101102
bad_binary_to_term_2, safe_binary_to_term2,
102103
bad_binary_to_term, bad_terms, t_hash, bad_size,
103104
big_binary_to_term,
105+
binary_to_term_trap_crash,
104106
sub_bin_copy, bad_term_to_binary, t2b_system_limit,
105107
term_to_iovec, more_bad_terms,
106108
unsorted_map_in_map,
@@ -1972,6 +1974,23 @@ trapping_loop2(Bif,Args,N) ->
19721974
apply(erlang,Bif,Args),
19731975
trapping_loop2(Bif, Args, N-1).
19741976

1977+
%% GH-11404: Bug caused SEGV or failed ASSERT.
1978+
binary_to_term_trap_crash(Config) ->
1979+
Term = {0,"1234567890123456",0,0,0,0,0,0,
1980+
[1 bsl 47], [], {127,0,0,1},
1981+
0,[],[],[],[],[],[],[],[],[],[],0,[],"123456789",[],[],0,0,
1982+
0,[],0,[],[],[],[],[],1,[],[],[],[],[],[],0,0,"123",[],0,[],
1983+
1,[],[],[],0,0,{0,0},0,[],0,0,0,[],[],0,[],0,0,[]},
1984+
Bin = term_to_binary(Term),
1985+
CONTEXT_REDS = erlang:system_info(context_reductions),
1986+
[begin
1987+
erlang:yield(),
1988+
erlang:bump_reductions(I),
1989+
binary_to_term(Bin)
1990+
end
1991+
|| I <- lists:seq(1,CONTEXT_REDS)],
1992+
ok.
1993+
19751994
large(Config) when is_list(Config) ->
19761995
List = lists:flatten(lists:map(fun (_) ->
19771996
[0,1,2,3,4,5,6,7,8]

0 commit comments

Comments
 (0)