From fe5d43871f4d5dc1f32e85a774714440722965c1 Mon Sep 17 00:00:00 2001 From: webzwo0i Date: Sat, 30 Oct 2021 23:29:41 +0200 Subject: [PATCH] textLinesMutator: Fix removal at the end of the lines array ...in case we are in the middle of a line (curCol !== 0) and we remove everything up to the end of the line. Before this commit a string 'undefined' could make it into the splice. --- src/static/js/Changeset.js | 10 +++++--- .../frontend/specs/easysync-mutations.js | 23 +++++++++++++++++++ 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/static/js/Changeset.js b/src/static/js/Changeset.js index 53b3f2c8f..7076910a6 100644 --- a/src/static/js/Changeset.js +++ b/src/static/js/Changeset.js @@ -908,8 +908,10 @@ class TextLinesMutator { let removed = ''; if (this._isCurLineInSplice()) { if (this._curCol === 0) { + // First line to be removed is in splice. removed = this._curSplice[this._curSplice.length - 1]; this._curSplice.length--; + // Next lines to be removed are not in splice. removed += nextKLinesText(L - 1); this._curSplice[1] += L - 1; } else { @@ -917,11 +919,13 @@ class TextLinesMutator { this._curSplice[1] += L - 1; const sline = this._curSplice.length - 1; removed = this._curSplice[sline].substring(this._curCol) + removed; - this._curSplice[sline] = this._curSplice[sline].substring(0, this._curCol) + - this._linesGet(this._curSplice[0] + this._curSplice[1]); - this._curSplice[1] += 1; + // Is there a line left? + const remaining = this._linesGet(this._curSplice[0] + this._curSplice[1]) || ''; + this._curSplice[sline] = this._curSplice[sline].substring(0, this._curCol) + remaining; + this._curSplice[1] += remaining ? 1 : 0; } } else { + // Nothing that is removed is in splice. Implies curCol === 0. removed = nextKLinesText(L); this._curSplice[1] += L; } diff --git a/src/tests/frontend/specs/easysync-mutations.js b/src/tests/frontend/specs/easysync-mutations.js index c10d34519..dc997188e 100644 --- a/src/tests/frontend/specs/easysync-mutations.js +++ b/src/tests/frontend/specs/easysync-mutations.js @@ -137,6 +137,29 @@ describe('easysync-mutations', function () { ['skip', 1, 1, true], ], ['banana\n', 'cabbage\n', 'duffle\n']); + runMutationTest(8, ['\n', 'fun\n', '\n'], [ + ['remove', 1, 1, '\n'], + ['skip', 3, 0, false], + ['remove', 2, 2, '\n\n'], + ['insert', 'c'], + ], ['func']); + + runMutationTest(9, ['\n', 'fun\n', '\n'], [ + ['remove', 1, 1, '\n'], + ['skip', 3, 0, false], + ['remove', 2, 2, '\n\n'], + ['insert', 'c'], + ['insert', 'a\n', 1], + ['insert', 'c'], + ], ['funca\n', 'c']); + + runMutationTest(10, ['\n', 'fun\n', '\n'], [ + ['remove', 1, 1, '\n'], + ['skip', 2, 0, false], + ['remove', 3, 2, 'n\n\n'], + ['insert', 'z'], + ], ['fuz']); + it('mutatorHasMore', async function () { const lines = ['1\n', '2\n', '3\n', '4\n']; let mu;