Skip to content

Commit

Permalink
Handle extending self correctly
Browse files Browse the repository at this point in the history
Pythons list implementation has a special case to ensure that
x.extend(x) is the same as x.extend(list(x)). i.e. it doesn't notice
changes to the size of the list during the extend.

Previously this case would not have been handled correctly by
bitarray. This changes that by checking what the size of the other
array is before we make any changes. This ensures both that this works
correctly and also (importantly) that we don't try to write past the
end of the array.
  • Loading branch information
DRMacIver committed Jul 3, 2015
1 parent b840f53 commit 60864a6
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 1 deletion.
9 changes: 8 additions & 1 deletion bitarray/_bitarray.c
Original file line number Diff line number Diff line change
Expand Up @@ -574,11 +574,18 @@ extend_bitarray(bitarrayobject *self, bitarrayobject *other)
if (other->nbits == 0)
return 0;

/*
Note: other may be self. Thus we take the size before we change the
size, ensuring we only copy the right parts of the array.
*/

idx_t n_other_bits = other->nbits;

n_sum = self->nbits + other->nbits;
if (resize(self, n_sum) < 0)
return -1;

copy_n(self, n_sum - other->nbits, other, 0, other->nbits);
copy_n(self, n_sum - other->nbits, other, 0, n_other_bits);
return 0;
}

Expand Down
5 changes: 5 additions & 0 deletions bitarray/test_bitarray.py
Original file line number Diff line number Diff line change
Expand Up @@ -1211,6 +1211,11 @@ def test_string01(self):
self.assertEqual(c.tolist(), a + b)
self.check_obj(c)

def test_extend_self(self):
a = bitarray('1')
a.extend(a)
self.assertEqual(a, bitarray('11'))


tests.append(ExtendTests)

Expand Down

0 comments on commit 60864a6

Please sign in to comment.