Skip to content

Commit

Permalink
Fix bugs in ListExtensions.slice and ListSlice.slice. (#290)
Browse files Browse the repository at this point in the history
Thanks to [@hcanyz](https://github.com/hcanyz) for finding the bugs,
and suggesting fixes.
Adds regression test.

Fixes #286
  • Loading branch information
lrhn committed May 23, 2023
1 parent f949b09 commit a37bd51
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
- `copy`: copies an instance without recalculating the canonical values of the keys.
- `toMap`: creates a `Map<K,V>` (with the original key values).
- `toMapOfCanonicalKeys`: creates a `Map<C,V>` (with the canonicalized keys).
- Fixes bugs in `ListSlice.slice` and `ListExtensions.slice`.
- lints: ^2.0.1

## 1.17.2
Expand Down
4 changes: 2 additions & 2 deletions lib/src/list_extensions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ extension ListExtensions<E> on List<E> {
ListSlice<E> slice(int start, [int? end]) {
end = RangeError.checkValidRange(start, end, length);
var self = this;
if (self is ListSlice) return self.slice(start, end);
if (self is ListSlice<E>) return self.slice(start, end);
return ListSlice<E>(this, start, end);
}

Expand Down Expand Up @@ -404,7 +404,7 @@ class ListSlice<E> extends ListBase<E> {
/// ```
ListSlice<E> slice(int start, [int? end]) {
end = RangeError.checkValidRange(start, end, length);
return ListSlice._(_initialSize, source, start + start, end - start);
return ListSlice._(_initialSize, source, this.start + start, end - start);
}

@override
Expand Down
13 changes: 13 additions & 0 deletions test/extensions_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1207,6 +1207,19 @@ void main() {
test('refuses length 0', () {
expect(() => iterable([1]).slices(0), throwsRangeError);
});
test('regression #286, bug in slice', () {
var l1 = <int>[1, 2, 3, 4, 5, 6];
List<int> l2 = l1.slice(1, 5); // (2..5)
// This call would stack-overflow due to a lacking type promotion
// which caused the extension method to keep calling itself,
// instead of switching to the instance method on `ListSlice`.
//
// If successful, it would use the `2` argument as offset, instead
// of the `1` offset from the `slice` call above.
var l3 = l2.slice(2, 4); // (4..5)
expect(l3, [4, 5]);
expect(l3.toList(), [4, 5]);
});
});
});

Expand Down

0 comments on commit a37bd51

Please sign in to comment.