Skip to content

Commit 193cdec

Browse files
authored
Merge pull request #333236 from vscodebot-pr/fix/listview-invalid-array-length-333230-aw-33202685801
fix: clamp inverted visible range in ListView to prevent RangeError (fixes #333230)
2 parents 2936afe + 7429373 commit 193cdec

2 files changed

Lines changed: 29 additions & 2 deletions

File tree

src/vs/base/browser/ui/list/listView.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1560,9 +1560,11 @@ export class ListView<T> implements IListView<T> {
15601560
}
15611561

15621562
private getVisibleRange(renderTop: number, renderHeight: number): IRange {
1563+
const start = this.rangeMap.indexAt(renderTop);
15631564
return {
1564-
start: this.rangeMap.indexAt(renderTop),
1565-
end: this.rangeMap.indexAfter(renderTop + renderHeight - 1)
1565+
start,
1566+
// Clamp so a collapsed viewport (renderHeight <= 0) cannot produce an inverted range.
1567+
end: Math.max(start, this.rangeMap.indexAfter(renderTop + renderHeight - 1))
15661568
};
15671569
}
15681570

src/vs/base/test/browser/ui/list/listView.test.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -577,4 +577,29 @@ suite('ListView', function () {
577577
element.remove();
578578
}
579579
});
580+
581+
test('does not throw when laid out with a collapsed viewport and zero-height dynamic items', function () {
582+
type TestElement = { height: number };
583+
const delegate: IListVirtualDelegate<TestElement> = {
584+
getHeight() { return 0; },
585+
getTemplateId() { return 'template'; },
586+
getDynamicHeight(element) { return element.height; }
587+
};
588+
const renderer: IListRenderer<TestElement, void> = {
589+
templateId: 'template',
590+
renderTemplate() { },
591+
renderElement() { },
592+
disposeTemplate() { }
593+
};
594+
595+
const elements: TestElement[] = [{ height: 0 }, { height: 0 }, { height: 0 }];
596+
const listView = new ListView<TestElement>(document.createElement('div'), delegate, [renderer], { supportDynamicHeights: true });
597+
try {
598+
// Collapsing the viewport before splicing zero-height items previously yielded an inverted range that crashed probeDynamicHeights.
599+
listView.layout(0, 200);
600+
assert.doesNotThrow(() => listView.splice(0, 0, elements));
601+
} finally {
602+
listView.dispose();
603+
}
604+
});
580605
});

0 commit comments

Comments
 (0)