Skip to content

Commit 8711ec8

Browse files
committed
Merge pull request #1761 from pguyot/w29/fix-list-subtraction
Operator --: fix memory corruption These changes are made under both the "Apache 2.0" and the "GNU Lesser General Public License 2.1 or later" license terms (dual license). SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
2 parents d7e5157 + 8d3099c commit 8711ec8

File tree

2 files changed

+17
-7
lines changed

2 files changed

+17
-7
lines changed

src/libAtomVM/nifs.c

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5799,14 +5799,21 @@ static term nif_erlang_lists_subtract(Context *ctx, int argc, term argv[])
57995799
return list1;
58005800
}
58015801

5802-
if (UNLIKELY(memory_ensure_free_with_roots(ctx, (last_filtered_idx + 1) * CONS_SIZE, last_filtered_idx + 1, cons, MEMORY_CAN_SHRINK) != MEMORY_GC_OK)) {
5803-
free(cons);
5804-
RAISE_ERROR(OUT_OF_MEMORY_ATOM);
5805-
}
5806-
5807-
term result = term_nil();
5802+
term result;
58085803
if (last_filtered_idx < len - 1) {
5804+
// GC including new tail which is at last_filtered_idx + 1 (last_filtered_idx was filtered)
5805+
if (UNLIKELY(memory_ensure_free_with_roots(ctx, (last_filtered_idx + 1) * CONS_SIZE, last_filtered_idx + 2, cons, MEMORY_CAN_SHRINK) != MEMORY_GC_OK)) {
5806+
free(cons);
5807+
RAISE_ERROR(OUT_OF_MEMORY_ATOM);
5808+
}
58095809
result = cons[last_filtered_idx + 1];
5810+
} else {
5811+
// if last_filtered_idx == len -1, tail is nil
5812+
if (UNLIKELY(memory_ensure_free_with_roots(ctx, (last_filtered_idx + 1) * CONS_SIZE, last_filtered_idx, cons, MEMORY_CAN_SHRINK) != MEMORY_GC_OK)) {
5813+
free(cons);
5814+
RAISE_ERROR(OUT_OF_MEMORY_ATOM);
5815+
}
5816+
result = term_nil();
58105817
}
58115818

58125819
for (int i = last_filtered_idx - 1; i >= 0; i--) {

tests/libs/estdlib/test_lists_subtraction.erl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,10 @@ test() ->
3838
{[1, 2, 3, 4], [4, 3, 2, 1], []},
3939
{[1, 2, 3, 4], [1, 2, 3, 4], []},
4040
{[1], [1.0], [1]},
41-
{[1.0], [1.0], []}
41+
{[1.0], [1.0], []},
42+
{[1, 2, 3, 4, 5, 6, 7, 8, 9], ?MODULE:sub([1, 2, 3, 4], [1, 2, 5, 6, 7, 8, 9]), [
43+
1, 2, 5, 6, 7, 8, 9
44+
]}
4245
],
4346
ok = expect_failure(fun() -> ?MODULE:sub([a, b | c], [a]) end, badarg),
4447
ok = expect_failure(fun() -> ?MODULE:sub([], [a, b | c]) end, badarg),

0 commit comments

Comments
 (0)