Skip to content

Commit a853fff

Browse files
committed
py/obj.h: Fix mp_seq_replace_slice_no_grow to use memmove not memcpy.
Because the argument arrays may overlap, as show by the new tests in this commit. Also remove the debugging comments for these macros, add a new comment about overlapping regions, and separate the macros by blank lines to make them easier to read. Fixes issue micropython#6244. Signed-off-by: Damien George <[email protected]>
1 parent 895b1db commit a853fff

File tree

2 files changed

+28
-4
lines changed

2 files changed

+28
-4
lines changed

py/obj.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -992,17 +992,17 @@ bool mp_seq_cmp_objs(mp_uint_t op, const mp_obj_t *items1, size_t len1, const mp
992992
mp_obj_t mp_seq_index_obj(const mp_obj_t *items, size_t len, size_t n_args, const mp_obj_t *args);
993993
mp_obj_t mp_seq_count_obj(const mp_obj_t *items, size_t len, mp_obj_t value);
994994
mp_obj_t mp_seq_extract_slice(size_t len, const mp_obj_t *seq, mp_bound_slice_t *indexes);
995+
995996
// Helper to clear stale pointers from allocated, but unused memory, to preclude GC problems
996997
#define mp_seq_clear(start, len, alloc_len, item_sz) memset((byte *)(start) + (len) * (item_sz), 0, ((alloc_len) - (len)) * (item_sz))
998+
999+
// Note: dest and slice regions may overlap
9971000
#define mp_seq_replace_slice_no_grow(dest, dest_len, beg, end, slice, slice_len, item_sz) \
998-
/*printf("memcpy(%p, %p, %d)\n", dest + beg, slice, slice_len * (item_sz));*/ \
999-
memcpy(((char *)dest) + (beg) * (item_sz), slice, slice_len * (item_sz)); \
1000-
/*printf("memmove(%p, %p, %d)\n", dest + (beg + slice_len), dest + end, (dest_len - end) * (item_sz));*/ \
1001+
memmove(((char *)dest) + (beg) * (item_sz), slice, slice_len * (item_sz)); \
10011002
memmove(((char *)dest) + (beg + slice_len) * (item_sz), ((char *)dest) + (end) * (item_sz), (dest_len - end) * (item_sz));
10021003

10031004
// Note: dest and slice regions may overlap
10041005
#define mp_seq_replace_slice_grow_inplace(dest, dest_len, beg, end, slice, slice_len, len_adj, item_sz) \
1005-
/*printf("memmove(%p, %p, %d)\n", dest + beg + len_adj, dest + beg, (dest_len - beg) * (item_sz));*/ \
10061006
memmove(((char *)dest) + (beg + slice_len) * (item_sz), ((char *)dest) + (end) * (item_sz), ((dest_len) + (len_adj) - ((beg) + (slice_len))) * (item_sz)); \
10071007
memmove(((char *)dest) + (beg) * (item_sz), slice, slice_len * (item_sz));
10081008

tests/basics/memoryview_slice_assign.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,27 @@
6161
memoryview(array.array('i'))[0:2] = b'1234'
6262
except ValueError:
6363
print('ValueError')
64+
65+
# test shift left of bytearray
66+
b = bytearray(range(10))
67+
mv = memoryview(b)
68+
mv[1:] = mv[:-1]
69+
print(b)
70+
71+
# test shift right of bytearray
72+
b = bytearray(range(10))
73+
mv = memoryview(b)
74+
mv[:-1] = mv[1:]
75+
print(b)
76+
77+
# test shift left of array
78+
a = array.array('I', range(10))
79+
mv = memoryview(a)
80+
mv[1:] = mv[:-1]
81+
print(a)
82+
83+
# test shift right of array
84+
a = array.array('I', range(10))
85+
mv = memoryview(a)
86+
mv[:-1] = mv[1:]
87+
print(a)

0 commit comments

Comments
 (0)