diff --git a/chrome/content/zotero/xpcom/data/dataObject.js b/chrome/content/zotero/xpcom/data/dataObject.js index 66beca393..78db5c3aa 100644 --- a/chrome/content/zotero/xpcom/data/dataObject.js +++ b/chrome/content/zotero/xpcom/data/dataObject.js @@ -404,6 +404,13 @@ Zotero.DataObject.prototype.setRelations = function (newRelations) { var oldRelations = this._relations; + // Limit predicates to letters and colons for now + for (let p in newRelations) { + if (!/[a-z]+:[a-z]+/.test(p)) { + throw new Error(`Invalid relation predicate '${p}'`); + } + } + // Relations are stored internally as a flat array with individual predicate-object pairs, // so convert the incoming relations to that var newRelationsFlat = this.ObjectsClass.flattenRelations(newRelations); diff --git a/test/tests/dataObjectTest.js b/test/tests/dataObjectTest.js index 008211b6e..ac645be3b 100644 --- a/test/tests/dataObjectTest.js +++ b/test/tests/dataObjectTest.js @@ -512,6 +512,17 @@ describe("Zotero.DataObject", function() { }) }) + describe("#setRelations()", function () { + it("shouldn't allow invalid 'relations' predicates", function* () { + var item = new Zotero.Item("book"); + assert.throws(() => { + item.setRelations({ + "0": ["http://example.com/foo"] + }); + }); + }); + }); + describe("#_getLinkedObject()", function () { it("should return a linked object in another library", function* () { var group = yield getGroup();