Skip to content

Commit 0e960cb

Browse files
committed
Don't suppress encoding errors when shared structures are saved
1 parent 6b010f5 commit 0e960cb

File tree

2 files changed

+26
-5
lines changed

2 files changed

+26
-5
lines changed

pack.js

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ export class Packr extends Unpackr {
121121
}
122122
if (hasSharedUpdate)
123123
hasSharedUpdate = false
124+
let encodingError;
124125
try {
125126
if (packr.randomAccessStructure && value && value.constructor && value.constructor === Object)
126127
writeStruct(value);
@@ -171,6 +172,9 @@ export class Packr extends Unpackr {
171172
return target
172173
}
173174
return target.subarray(start, position) // position can change if we call pack again in saveStructures, so we get the buffer now
175+
} catch(error) {
176+
encodingError = error;
177+
throw error;
174178
} finally {
175179
if (structures) {
176180
resetStructures();
@@ -179,12 +183,14 @@ export class Packr extends Unpackr {
179183
// we can't rely on start/end with REUSE_BUFFER_MODE since they will (probably) change when we save
180184
let returnBuffer = target.subarray(start, position)
181185
let newSharedData = prepareStructures(structures, packr);
182-
if (packr.saveStructures(newSharedData, newSharedData.isCompatible) === false) {
183-
// get updated structures and try again if the update failed
184-
return packr.pack(value, encodeOptions)
186+
if (!encodingError) { // TODO: If there is an encoding error, should make the structures as uninitialized so they get rebuilt next time
187+
if (packr.saveStructures(newSharedData, newSharedData.isCompatible) === false) {
188+
// get updated structures and try again if the update failed
189+
return packr.pack(value, encodeOptions)
190+
}
191+
packr.lastNamedStructuresLength = sharedLength
192+
return returnBuffer
185193
}
186-
packr.lastNamedStructuresLength = sharedLength
187-
return returnBuffer
188194
}
189195
}
190196
if (encodeOptions & RESET_BUFFER_MODE)

tests/test.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -643,6 +643,21 @@ suite('msgpackr basic tests', function() {
643643
var deserialized = unpack(serialized)
644644
assert.equal(deserialized.aDate, data.aDate.toString())
645645
})
646+
test('standard pack fails on circular reference with shared structures', function () {
647+
var data = {}
648+
data.self = data;
649+
let structures = []
650+
let savedStructures
651+
let packr = new Packr({
652+
structures,
653+
saveStructures(structures) {
654+
savedStructures = structures
655+
}
656+
})
657+
assert.throws(function () {
658+
packr.pack(data);
659+
});
660+
})
646661

647662
test('proto handling', function() {
648663
var objectWithProto = JSON.parse('{"__proto__":{"foo":3}}');

0 commit comments

Comments
 (0)