diff --git a/src/node/handler/PadMessageHandler.js b/src/node/handler/PadMessageHandler.js index 7cdefc65c..68686c9ef 100644 --- a/src/node/handler/PadMessageHandler.js +++ b/src/node/handler/PadMessageHandler.js @@ -742,7 +742,16 @@ function handleUserChanges(data, cb) return callback(new Error("Can't apply USER_CHANGES "+changeset+" with oldLen " + Changeset.oldLen(changeset) + " to document of length " + prevText.length)); } - pad.appendRevision(changeset, thisSession.author); + try + { + pad.appendRevision(changeset, thisSession.author); + } + catch(e) + { + client.json.send({disconnect:"badChangeset"}); + stats.meter('failedChangesets').mark(); + return callback(e) + } var correctionChangeset = _correctMarkersInPad(pad.atext, pad.pool); if (correctionChangeset) { diff --git a/src/static/js/Changeset.js b/src/static/js/Changeset.js index 355bef4a9..366ad15f9 100644 --- a/src/static/js/Changeset.js +++ b/src/static/js/Changeset.js @@ -903,6 +903,8 @@ exports.pack = function (oldLen, newLen, opsStr, bank) { * @params str {string} String to which a Changeset should be applied */ exports.applyToText = function (cs, str) { + var totalNrOfLines = str.split("\n").length; + var removedLines = 0; var unpacked = exports.unpack(cs); exports.assert(str.length == unpacked.oldLen, "mismatched apply: ", str.length, " / ", unpacked.oldLen); var csIter = exports.opIterator(unpacked.ops); @@ -916,6 +918,7 @@ exports.applyToText = function (cs, str) { assem.append(bankIter.take(op.chars)); break; case '-': + removedLines += op.lines; strIter.skip(op.chars); break; case '=': @@ -923,6 +926,7 @@ exports.applyToText = function (cs, str) { break; } } + exports.assert(totalNrOfLines >= removedLines,"cannot remove ", removedLines, " lines from text with ", totalNrOfLines, " lines"); assem.append(strIter.take(strIter.remaining())); return assem.toString(); };