diff --git a/services/document-updater/app/coffee/UpdateManager.coffee b/services/document-updater/app/coffee/UpdateManager.coffee index e5ede11173..3d0a318b9b 100644 --- a/services/document-updater/app/coffee/UpdateManager.coffee +++ b/services/document-updater/app/coffee/UpdateManager.coffee @@ -138,10 +138,13 @@ module.exports = UpdateManager = # 16-bit character of a blackboard bold character (http://www.fileformat.info/info/unicode/char/1d400/index.htm). # Something must be going on client side that is screwing up the encoding and splitting the # two 16-bit characters so that \uD835 is standalone. + BAD_CHAR_REGEXP = /[\uD800-\uDFFF]/g for op in update.op or [] - if op.i? + if op.i? && BAD_CHAR_REGEXP.test(op.i) # Replace high and low surrogate characters with 'replacement character' (\uFFFD) - op.i = op.i.replace(/[\uD800-\uDFFF]/g, "\uFFFD") + op.i = op.i.replace(BAD_CHAR_REGEXP, "\uFFFD") + # remove any client-side hash because we have modified the content + delete update.hash return update _addProjectHistoryMetadataToOps: (updates, pathname, projectHistoryId, lines) -> diff --git a/services/document-updater/test/unit/coffee/UpdateManager/UpdateManagerTests.coffee b/services/document-updater/test/unit/coffee/UpdateManager/UpdateManagerTests.coffee index ac8d4c742c..280fad5f33 100644 --- a/services/document-updater/test/unit/coffee/UpdateManager/UpdateManagerTests.coffee +++ b/services/document-updater/test/unit/coffee/UpdateManager/UpdateManagerTests.coffee @@ -212,7 +212,7 @@ describe "UpdateManager", -> describe "with UTF-16 surrogate pairs in the update", -> beforeEach -> - @update = {op: [{p: 42, i: "\uD835\uDC00"}]} + @update = {op: [{p: 42, i: "\uD835\uDC00"}], hash: "f1d2d2f924e986ac86fdf7b36c94bcdf32beec15"} @UpdateManager.applyUpdate @project_id, @doc_id, @update, @callback it "should apply the update but with surrogate pairs removed", -> @@ -223,6 +223,9 @@ describe "UpdateManager", -> # \uFFFD is 'replacement character' @update.op[0].i.should.equal "\uFFFD\uFFFD" + it "should skip the hash check by removing any hash field present", -> + @update.should.not.have.property('hash') + describe "with an error", -> beforeEach -> @error = new Error("something went wrong")