mirror of
https://github.com/ether/etherpad-lite.git
synced 2025-04-21 07:56:16 -04:00
Merge pull request #1926 from ether/fix/no-connect-to-corrupt-pad
Fix a whole range of bugs related to corrupted changesets
This commit is contained in:
commit
22e9e5fdcd
2 changed files with 23 additions and 19 deletions
|
@ -594,7 +594,7 @@ function handleUserChanges(data, cb)
|
||||||
// defined in the accompanying attribute pool.
|
// defined in the accompanying attribute pool.
|
||||||
Changeset.eachAttribNumber(changeset, function(n) {
|
Changeset.eachAttribNumber(changeset, function(n) {
|
||||||
if (! wireApool.getAttrib(n)) {
|
if (! wireApool.getAttrib(n)) {
|
||||||
throw "Attribute pool is missing attribute "+n+" for changeset "+changeset;
|
throw new Error("Attribute pool is missing attribute "+n+" for changeset "+changeset);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -608,22 +608,21 @@ function handleUserChanges(data, cb)
|
||||||
if(!attr) return
|
if(!attr) return
|
||||||
attr = wireApool.getAttrib(attr)
|
attr = wireApool.getAttrib(attr)
|
||||||
if(!attr) return
|
if(!attr) return
|
||||||
if('author' == attr[0] && attr[1] != thisSession.author) throw "Trying to submit changes as another author"
|
if('author' == attr[0] && attr[1] != thisSession.author) throw new Error("Trying to submit changes as another author in changeset "+changeset);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
|
||||||
catch(e)
|
|
||||||
{
|
|
||||||
// There is an error in this changeset, so just refuse it
|
|
||||||
console.warn("Can't apply USER_CHANGES "+changeset+", because: "+e);
|
|
||||||
client.json.send({disconnect:"badChangeset"});
|
|
||||||
return callback();
|
|
||||||
}
|
|
||||||
|
|
||||||
//ex. adoptChangesetAttribs
|
//ex. adoptChangesetAttribs
|
||||||
|
|
||||||
//Afaik, it copies the new attributes from the changeset, to the global Attribute Pool
|
//Afaik, it copies the new attributes from the changeset, to the global Attribute Pool
|
||||||
changeset = Changeset.moveOpsToNewPool(changeset, wireApool, pad.pool);
|
changeset = Changeset.moveOpsToNewPool(changeset, wireApool, pad.pool);
|
||||||
|
}
|
||||||
|
catch(e)
|
||||||
|
{
|
||||||
|
// There is an error in this changeset, so just refuse it
|
||||||
|
client.json.send({disconnect:"badChangeset"});
|
||||||
|
return callback(new Error("Can't apply USER_CHANGES, because "+e.message));
|
||||||
|
}
|
||||||
|
|
||||||
//ex. applyUserChanges
|
//ex. applyUserChanges
|
||||||
apool = pad.pool;
|
apool = pad.pool;
|
||||||
|
@ -651,9 +650,8 @@ function handleUserChanges(data, cb)
|
||||||
{
|
{
|
||||||
changeset = Changeset.follow(c, changeset, false, apool);
|
changeset = Changeset.follow(c, changeset, false, apool);
|
||||||
}catch(e){
|
}catch(e){
|
||||||
console.warn("Can't apply USER_CHANGES "+changeset+", possibly because of mismatched follow error");
|
|
||||||
client.json.send({disconnect:"badChangeset"});
|
client.json.send({disconnect:"badChangeset"});
|
||||||
return callback();
|
return callback(new Error("Can't apply USER_CHANGES, because "+e.message));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((r - baseRev) % 200 == 0) { // don't let the stack get too deep
|
if ((r - baseRev) % 200 == 0) { // don't let the stack get too deep
|
||||||
|
@ -674,9 +672,8 @@ function handleUserChanges(data, cb)
|
||||||
|
|
||||||
if (Changeset.oldLen(changeset) != prevText.length)
|
if (Changeset.oldLen(changeset) != prevText.length)
|
||||||
{
|
{
|
||||||
console.warn("Can't apply USER_CHANGES "+changeset+" with oldLen " + Changeset.oldLen(changeset) + " to document of length " + prevText.length);
|
|
||||||
client.json.send({disconnect:"badChangeset"});
|
client.json.send({disconnect:"badChangeset"});
|
||||||
return callback();
|
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);
|
pad.appendRevision(changeset, thisSession.author);
|
||||||
|
@ -700,7 +697,7 @@ function handleUserChanges(data, cb)
|
||||||
], function(err)
|
], function(err)
|
||||||
{
|
{
|
||||||
cb();
|
cb();
|
||||||
ERR(err);
|
if(err) console.warn(err.stack || err)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1006,11 +1003,17 @@ function handleClientReady(client, message)
|
||||||
//This is a normal first connect
|
//This is a normal first connect
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//prepare all values for the wire
|
//prepare all values for the wire, there'S a chance that this throws, if the pad is corrupted
|
||||||
|
try {
|
||||||
var atext = Changeset.cloneAText(pad.atext);
|
var atext = Changeset.cloneAText(pad.atext);
|
||||||
var attribsForWire = Changeset.prepareForWire(atext.attribs, pad.pool);
|
var attribsForWire = Changeset.prepareForWire(atext.attribs, pad.pool);
|
||||||
var apool = attribsForWire.pool.toJsonable();
|
var apool = attribsForWire.pool.toJsonable();
|
||||||
atext.attribs = attribsForWire.translated;
|
atext.attribs = attribsForWire.translated;
|
||||||
|
}catch(e) {
|
||||||
|
console.error(e.stack || e)
|
||||||
|
client.json.send({disconnect:"padCorrupted"});// pull the breaks
|
||||||
|
return callback();
|
||||||
|
}
|
||||||
|
|
||||||
// Warning: never ever send padIds.padId to the client. If the
|
// Warning: never ever send padIds.padId to the client. If the
|
||||||
// client is read only you would open a security hole 1 swedish
|
// client is read only you would open a security hole 1 swedish
|
||||||
|
|
|
@ -1504,6 +1504,7 @@ exports.moveOpsToNewPool = function (cs, oldPool, newPool) {
|
||||||
return upToDollar.replace(/\*([0-9a-z]+)/g, function (_, a) {
|
return upToDollar.replace(/\*([0-9a-z]+)/g, function (_, a) {
|
||||||
var oldNum = exports.parseNum(a);
|
var oldNum = exports.parseNum(a);
|
||||||
var pair = oldPool.getAttrib(oldNum);
|
var pair = oldPool.getAttrib(oldNum);
|
||||||
|
if(!pair) exports.error('Can\'t copy unknown attrib (reference attrib string to non-existant pool entry). Inconsistent attrib state!');
|
||||||
var newNum = newPool.putAttrib(pair);
|
var newNum = newPool.putAttrib(pair);
|
||||||
return '*' + exports.numToString(newNum);
|
return '*' + exports.numToString(newNum);
|
||||||
}) + fromDollar;
|
}) + fromDollar;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue