Skip to content

Commit 2a7cd0f

Browse files
committed
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.
1 parent cd500bf commit 2a7cd0f

File tree

2 files changed

+30
-3
lines changed

2 files changed

+30
-3
lines changed

src/static/js/Changeset.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -904,20 +904,24 @@ class TextLinesMutator {
904904
let removed = '';
905905
if (this._isCurLineInSplice()) {
906906
if (this._curCol === 0) {
907+
// First line to be removed is in splice.
907908
removed = this._curSplice[this._curSplice.length - 1];
908909
this._curSplice.length--;
910+
// Next lines to be removed are not in splice.
909911
removed += nextKLinesText(L - 1);
910912
this._curSplice[1] += L - 1;
911913
} else {
912914
removed = nextKLinesText(L - 1);
913915
this._curSplice[1] += L - 1;
914916
const sline = this._curSplice.length - 1;
915917
removed = this._curSplice[sline].substring(this._curCol) + removed;
916-
this._curSplice[sline] = this._curSplice[sline].substring(0, this._curCol) +
917-
this._linesGet(this._curSplice[0] + this._curSplice[1]);
918-
this._curSplice[1] += 1;
918+
// Is there a line left?
919+
const remaining = this._linesGet(this._curSplice[0] + this._curSplice[1]) || '';
920+
this._curSplice[sline] = this._curSplice[sline].substring(0, this._curCol) + remaining;
921+
this._curSplice[1] += remaining ? 1 : 0;
919922
}
920923
} else {
924+
// Nothing that is removed is in splice. Implies curCol === 0.
921925
removed = nextKLinesText(L);
922926
this._curSplice[1] += L;
923927
}

src/tests/frontend/specs/easysync-mutations.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,29 @@ describe('easysync-mutations', function () {
137137
['skip', 1, 1, true],
138138
], ['banana\n', 'cabbage\n', 'duffle\n']);
139139

140+
runMutationTest(8, ['\n', 'fun\n', '\n'], [
141+
['remove', 1, 1, '\n'],
142+
['skip', 3, 0, false],
143+
['remove', 2, 2, '\n\n'],
144+
['insert', 'c'],
145+
], ['func']);
146+
147+
runMutationTest(9, ['\n', 'fun\n', '\n'], [
148+
['remove', 1, 1, '\n'],
149+
['skip', 3, 0, false],
150+
['remove', 2, 2, '\n\n'],
151+
['insert', 'c'],
152+
['insert', 'a\n', 1],
153+
['insert', 'c'],
154+
], ['funca\n', 'c']);
155+
156+
runMutationTest(10, ['\n', 'fun\n', '\n'], [
157+
['remove', 1, 1, '\n'],
158+
['skip', 2, 0, false],
159+
['remove', 3, 2, 'n\n\n'],
160+
['insert', 'z'],
161+
], ['fuz']);
162+
140163
it('mutatorHasMore', async function () {
141164
const lines = ['1\n', '2\n', '3\n', '4\n'];
142165
let mu;

0 commit comments

Comments
 (0)