Skip to content

Commit 2428297

Browse files
authored
1 parent dfca1cc commit 2428297

File tree

2 files changed

+52
-5
lines changed

2 files changed

+52
-5
lines changed

src/vs/base/common/map.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -576,12 +576,16 @@ export class TernarySearchTree<K, V> {
576576
if (!node.mid && !node.value) {
577577
if (node.left && node.right) {
578578
// full node
579+
// replace deleted-node with the min-node of the right branch.
580+
// If there is no true min-node leave things as they are
579581
const min = this._min(node.right);
580-
const { key, value, segment } = min;
581-
this._delete(min.key!, false);
582-
node.key = key;
583-
node.value = value;
584-
node.segment = segment;
582+
if (min.key) {
583+
const { key, value, segment } = min;
584+
this._delete(min.key!, false);
585+
node.key = key;
586+
node.value = value;
587+
node.segment = segment;
588+
}
585589

586590
} else {
587591
// empty or half empty

src/vs/base/test/common/map.test.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -862,6 +862,49 @@ suite('Map', () => {
862862
}
863863
});
864864

865+
test('TernarySearchTree: Cannot read properties of undefined (reading \'length\'): #161618 (simple)', function () {
866+
const raw = 'config.debug.toolBarLocation,floating,config.editor.renderControlCharacters,true,config.editor.renderWhitespace,selection,config.files.autoSave,off,config.git.enabled,true,config.notebook.globalToolbar,true,config.terminal.integrated.tabs.enabled,true,config.terminal.integrated.tabs.showActions,singleTerminalOrNarrow,config.terminal.integrated.tabs.showActiveTerminal,singleTerminalOrNarrow,config.workbench.activityBar.visible,true,config.workbench.experimental.settingsProfiles.enabled,true,config.workbench.layoutControl.type,both,config.workbench.sideBar.location,left,config.workbench.statusBar.visible,true';
867+
const array = raw.split(',');
868+
const tuples: [string, string][] = [];
869+
for (let i = 0; i < array.length; i += 2) {
870+
tuples.push([array[i], array[i + 1]]);
871+
}
872+
873+
const map = TernarySearchTree.forConfigKeys<string>();
874+
map.fill(tuples);
875+
876+
assert.strictEqual([...map].join(), raw);
877+
assert.ok(map.has('config.editor.renderWhitespace'));
878+
879+
const len = [...map].length;
880+
map.delete('config.editor.renderWhitespace');
881+
assert.ok(map._isBalanced());
882+
assert.strictEqual([...map].length, len - 1);
883+
});
884+
885+
test('TernarySearchTree: Cannot read properties of undefined (reading \'length\'): #161618 (random)', function () {
886+
const raw = 'config.debug.toolBarLocation,floating,config.editor.renderControlCharacters,true,config.editor.renderWhitespace,selection,config.files.autoSave,off,config.git.enabled,true,config.notebook.globalToolbar,true,config.terminal.integrated.tabs.enabled,true,config.terminal.integrated.tabs.showActions,singleTerminalOrNarrow,config.terminal.integrated.tabs.showActiveTerminal,singleTerminalOrNarrow,config.workbench.activityBar.visible,true,config.workbench.experimental.settingsProfiles.enabled,true,config.workbench.layoutControl.type,both,config.workbench.sideBar.location,left,config.workbench.statusBar.visible,true';
887+
const array = raw.split(',');
888+
const tuples: [string, string][] = [];
889+
for (let i = 0; i < array.length; i += 2) {
890+
tuples.push([array[i], array[i + 1]]);
891+
}
892+
893+
for (let round = 100; round >= 0; round--) {
894+
shuffle(tuples);
895+
const map = TernarySearchTree.forConfigKeys<string>();
896+
map.fill(tuples);
897+
898+
assert.strictEqual([...map].join(), raw);
899+
assert.ok(map.has('config.editor.renderWhitespace'));
900+
901+
const len = [...map].length;
902+
map.delete('config.editor.renderWhitespace');
903+
assert.ok(map._isBalanced());
904+
assert.strictEqual([...map].length, len - 1);
905+
}
906+
});
907+
865908
test('TernarySearchTree (PathSegments) - lookup', function () {
866909

867910
const map = new TernarySearchTree<string, number>(new PathIterator());

0 commit comments

Comments
 (0)