1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-03-29 21:21:15 +02:00

All: Resolves : Handle invalid revision patches

This commit is contained in:
Laurent Cozic 2022-03-03 13:20:29 +00:00
parent 053dbabf74
commit 299a14755a
2 changed files with 66 additions and 8 deletions
packages/lib/models

@ -1,6 +1,6 @@
import { expectNotThrow, naughtyStrings, setupDatabaseAndSynchronizer, switchClient } from '../testing/test-utils';
import Note from '../models/Note';
import Revision from '../models/Revision';
import Revision, { ObjectPatch } from '../models/Revision';
describe('models/Revision', function() {
@ -139,6 +139,53 @@ describe('models/Revision', function() {
expect(JSON.stringify(merged)).toBe(JSON.stringify(newObject));
}));
it('should handle invalid object patch', (async () => {
const oldObject = {
one: '123',
two: '456',
three: '789',
};
const brokenPatch = `{"new":{"four":"444
"},"deleted":["one"]}`;
const expected = {
two: '456',
three: '789',
four: '444',
};
const merged = Revision.applyObjectPatch(oldObject, brokenPatch);
expect(JSON.stringify(merged)).toBe(JSON.stringify(expected));
}));
it('should not strip off newlines from object values', (async () => {
const oldObject = {
one: '123',
two: '456',
three: '789',
};
const patch: ObjectPatch = {
'new': {
'four': 'one line\ntwo line',
},
'deleted': [],
};
const expected = {
one: '123',
two: '456',
three: '789',
four: 'one line\ntwo line',
};
const merged = Revision.applyObjectPatch(oldObject, JSON.stringify(patch));
expect(JSON.stringify(merged)).toBe(JSON.stringify(expected));
}));
it('should move target revision to the top', (async () => {
const revs = [
{ id: '123' },

@ -8,6 +8,11 @@ const { sprintf } = require('sprintf-js');
const dmp = new DiffMatchPatch();
export interface ObjectPatch {
new: Record<string, any>;
deleted: string[];
}
export default class Revision extends BaseItem {
static tableName() {
return 'revisions';
@ -81,7 +86,7 @@ export default class Revision extends BaseItem {
public static createObjectPatch(oldObject: any, newObject: any) {
if (!oldObject) oldObject = {};
const output: any = {
const output: ObjectPatch = {
new: {},
deleted: [],
};
@ -100,16 +105,22 @@ export default class Revision extends BaseItem {
return JSON.stringify(output);
}
static applyObjectPatch(object: any, patch: any) {
patch = JSON.parse(patch);
// We need to sanitise the object patch because it seems some are broken and
// may contain new lines: https://github.com/laurent22/joplin/issues/6209
private static sanitizeObjectPatch(patch: string): string {
return patch.replace(/[\n\r]/g, '');
}
public static applyObjectPatch(object: any, patch: string) {
const parsedPatch: ObjectPatch = JSON.parse(this.sanitizeObjectPatch(patch));
const output = Object.assign({}, object);
for (const k in patch.new) {
output[k] = patch.new[k];
for (const k in parsedPatch.new) {
output[k] = parsedPatch.new[k];
}
for (let i = 0; i < patch.deleted.length; i++) {
delete output[patch.deleted[i]];
for (let i = 0; i < parsedPatch.deleted.length; i++) {
delete output[parsedPatch.deleted[i]];
}
return output;