Skip to content

Commit

Permalink
Merge branch 'maint'
Browse files Browse the repository at this point in the history
* maint:
  erts: Fix crash in ETS compressed tables
  • Loading branch information
jhogberg committed Aug 5, 2024
2 parents b1f15e2 + 991d2d6 commit 4e9a084
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 29 deletions.
50 changes: 22 additions & 28 deletions erts/emulator/beam/external.c
Original file line number Diff line number Diff line change
Expand Up @@ -3853,21 +3853,19 @@ enc_term_int(TTBEncodeContext* ctx, ErtsAtomCacheMap *acmp, Eterm obj, byte* ep,

ASSERT(!use_iov);

/* Use [BIT_]BINARY_INTERNAL_REF, copying the actual BinRef
* and/or ErlSubBits whenever that is smaller than the data
* itself. */
if (wire_size >= sizeof(BinRef)) {
if ((encoding == BINARY_EXT) &&
(base == (byte*)refc_binary->orig_bytes) &&
(size == refc_binary->orig_size * 8) &&
(offset == 0)) {
encoding = BINARY_INTERNAL_REF;
copy_payload = 0;
} else if (wire_size >= (sizeof(ErlSubBits) +
sizeof(BinRef))) {
encoding = BITSTRING_INTERNAL_REF;
copy_payload = 0;
}
/* Always use [BIT_]BINARY_INTERNAL_REF: this may lead to a
* larger result than copying the payload, but ensures that
* the decoded object is exactly the same as the encoded
* one, simplifying the decompression logic in ETS. */
if ((encoding == BINARY_EXT) &&
(base == (byte*)refc_binary->orig_bytes) &&
(size == refc_binary->orig_size * 8) &&
(offset == 0)) {
encoding = BINARY_INTERNAL_REF;
copy_payload = 0;
} else {
encoding = BITSTRING_INTERNAL_REF;
copy_payload = 0;
}
}

Expand Down Expand Up @@ -5606,19 +5604,15 @@ encode_size_struct_int(TTBSizeContext* ctx, ErtsAtomCacheMap *acmp, Eterm obj,

ASSERT(vlen < 0);

/* Use [BIT_]BINARY_INTERNAL_REF, copying the actual BinRef
* and/or ErlSubBits whenever that is smaller than the data
* itself. */
if (wire_size >= sizeof(BinRef)) {
if ((encoding == BINARY_EXT) &&
(base == (byte*)refc_binary->orig_bytes) &&
(size == refc_binary->orig_size * 8) &&
(offset == 0)) {
encoding = BINARY_INTERNAL_REF;
} else if (wire_size >= (sizeof(ErlSubBits) +
sizeof(BinRef))) {
encoding = BITSTRING_INTERNAL_REF;
}
/* Always use [BIT_]BINARY_INTERNAL_REF: see matching comment
* in enc_term_int. */
if ((encoding == BINARY_EXT) &&
(base == (byte*)refc_binary->orig_bytes) &&
(size == refc_binary->orig_size * 8) &&
(offset == 0)) {
encoding = BINARY_INTERNAL_REF;
} else {
encoding = BITSTRING_INTERNAL_REF;
}
}

Expand Down
7 changes: 6 additions & 1 deletion lib/stdlib/test/ets_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -7905,7 +7905,8 @@ maps_sum([L]) ->
types(Config) when is_list(Config) ->
init_externals(),
repeat_for_opts(fun types_do/1, [repeat_for_opts_atom2list(set_types),
compressed]).
compressed,
[ordered_set, compressed]]).

types_do(Opts) ->
EtsMem = etsmem(),
Expand Down Expand Up @@ -9312,9 +9313,12 @@ test_terms(Test_Func, Mode) ->
Bin2 = list_to_binary(lists:seq(0, ?heap_binary_size+1)),
Test_Func(Bin2),
Bin3 = list_to_binary(lists:seq(0, 255)),
%% Test an undersized refc binary. GH-8682
Bin4 = erts_debug:set_internal_state(binary, 61),
garbage_collect(),
Pib = process_info(self(),binary),
Test_Func(Bin3),
Test_Func(Bin4),
garbage_collect(),
case Mode of
strict -> Pib = process_info(self(),binary);
Expand All @@ -9325,6 +9329,7 @@ test_terms(Test_Func, Mode) ->
Test_Func(make_unaligned_sub_binary(Bin1)),
Test_Func(make_unaligned_sub_binary(Bin2)),
Test_Func(make_unaligned_sub_binary(Bin3)),
Test_Func(make_unaligned_sub_binary(Bin4)),

Test_Func(make_sub_binary(lists:seq(42, 43))),
Test_Func(make_sub_binary([42,43,44])),
Expand Down

0 comments on commit 4e9a084

Please sign in to comment.