diff --git a/lib/serialization/ObjectMiddleware.js b/lib/serialization/ObjectMiddleware.js index 5e3af8aa5..d9b850e66 100644 --- a/lib/serialization/ObjectMiddleware.js +++ b/lib/serialization/ObjectMiddleware.js @@ -168,6 +168,7 @@ class ObjectMiddleware extends SerializerMiddleware { }; let currentPosTypeLookup = 0; const objectTypeLookup = new Map(); + const cycleStack = new Set(); const process = item => { // check if we can emit a reference const ref = referenceable.get(item); @@ -176,6 +177,14 @@ class ObjectMiddleware extends SerializerMiddleware { return; } if (typeof item === "object" && item !== null) { + if (cycleStack.has(item)) { + throw new Error( + `Circular references can't be serialized (${Array.from(cycleStack) + .concat([item]) + .map(obj => obj.constructor.name) + .join(" -> ")})` + ); + } const { request, name, serializer } = ObjectMiddleware.getSerializerFor( item ); @@ -188,11 +197,13 @@ class ObjectMiddleware extends SerializerMiddleware { } else { result.push(ESCAPE, currentPosTypeLookup - lastIndex); } + cycleStack.add(item); serializer.serialize(item, { write(value) { process(value); } }); + cycleStack.delete(item); result.push(ESCAPE, ESCAPE_END_OBJECT); addReferenceable(item); } else if (typeof item === "string") {