Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit e4ca4ce

Browse filesBrowse files
philipp-spiessleebyron
authored andcommitted
Stop the iteration of an exhausted, unknown-sized sequence when slicing (#1324)
This PR fixes a bug with the slice operator that caused non value iterators of an unknown sized sequence to continue although the source sequence was exhausted, eventually accessing the value of a key/value pair that does not exist. The issue did not happen with fixed sized sequences since we can calculate resulting size in advance (as `sliceSize`) and bail out early. For an unknown sized sequence however, we can not know this size in advance (see this comment: [1]). To solve this, we now bail out when we encounter a completed iterator before proceeding to process it further. [1]: https://github.com/facebook/immutable-js/blob/27b231c8952366ddb96ab2a20d1eb351b3c8719e/src/Operations.js#L427-L428
1 parent 81bd729 commit e4ca4ce
Copy full SHA for e4ca4ce

File tree

Expand file treeCollapse file tree

5 files changed

+26
-4
lines changed
Filter options
Expand file treeCollapse file tree

5 files changed

+26
-4
lines changed

‎__tests__/slice.ts

Copy file name to clipboardExpand all lines: __tests__/slice.ts
+22Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,28 @@ describe('slice', () => {
126126
expect(iterTail.next()).toEqual({value: undefined, done: true});
127127
});
128128

129+
it('stops the entries iterator when the sequence has an undefined end', () => {
130+
let seq = Seq([0, 1, 2, 3, 4, 5]);
131+
// flatMap is lazy and thus the resulting sequence has no size.
132+
seq = seq.flatMap(a => [a]);
133+
expect(seq.size).toEqual(undefined);
134+
135+
let iterFront = seq.slice(0, 2).entries();
136+
expect(iterFront.next()).toEqual({value: [0, 0], done: false});
137+
expect(iterFront.next()).toEqual({value: [1, 1], done: false});
138+
expect(iterFront.next()).toEqual({value: undefined, done: true});
139+
140+
let iterMiddle = seq.slice(2, 4).entries();
141+
expect(iterMiddle.next()).toEqual({value: [0, 2], done: false});
142+
expect(iterMiddle.next()).toEqual({value: [1, 3], done: false});
143+
expect(iterMiddle.next()).toEqual({value: undefined, done: true});
144+
145+
let iterTail = seq.slice(4, 123456).entries();
146+
expect(iterTail.next()).toEqual({value: [0, 4], done: false});
147+
expect(iterTail.next()).toEqual({value: [1, 5], done: false});
148+
expect(iterTail.next()).toEqual({value: undefined, done: true});
149+
});
150+
129151
check.it('works like Array.prototype.slice',
130152
[gen.int, gen.array(gen.oneOf([gen.int, gen.undefined]), 0, 3)],
131153
(valuesLen, args) => {

‎dist/immutable.es.js

Copy file name to clipboardExpand all lines: dist/immutable.es.js
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1505,7 +1505,7 @@ function sliceFactory(collection, begin, end, useKeys) {
15051505
return iteratorDone();
15061506
}
15071507
var step = iterator.next();
1508-
if (useKeys || type === ITERATE_VALUES) {
1508+
if (useKeys || type === ITERATE_VALUES || step.done) {
15091509
return step;
15101510
}
15111511
if (type === ITERATE_KEYS) {

‎dist/immutable.js

Copy file name to clipboardExpand all lines: dist/immutable.js
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1511,7 +1511,7 @@ function sliceFactory(collection, begin, end, useKeys) {
15111511
return iteratorDone();
15121512
}
15131513
var step = iterator.next();
1514-
if (useKeys || type === ITERATE_VALUES) {
1514+
if (useKeys || type === ITERATE_VALUES || step.done) {
15151515
return step;
15161516
}
15171517
if (type === ITERATE_KEYS) {

‎dist/immutable.min.js

Copy file name to clipboardExpand all lines: dist/immutable.min.js
+1-1Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎src/Operations.js

Copy file name to clipboardExpand all lines: src/Operations.js
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,7 @@ export function sliceFactory(collection, begin, end, useKeys) {
479479
return iteratorDone();
480480
}
481481
const step = iterator.next();
482-
if (useKeys || type === ITERATE_VALUES) {
482+
if (useKeys || type === ITERATE_VALUES || step.done) {
483483
return step;
484484
}
485485
if (type === ITERATE_KEYS) {

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.