aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKim Alvefur <zash@zash.se>2018-10-27 12:43:03 +0200
committerKim Alvefur <zash@zash.se>2018-10-27 12:43:03 +0200
commitfdbc23fab67129d4764367f5fa4614cc244904b3 (patch)
treeb949b814294559492811672e610d7e8f75954a84
parent2801e1f10087b21a7ca8c0a10a11de5ac10c259d (diff)
downloadprosody-fdbc23fab67129d4764367f5fa4614cc244904b3.tar.gz
prosody-fdbc23fab67129d4764367f5fa4614cc244904b3.zip
util.serialization: Add option for allowing multiple references to the same table (but not cycles)
-rw-r--r--spec/util_serialization_spec.lua16
-rw-r--r--util/serialization.lua10
2 files changed, 25 insertions, 1 deletions
diff --git a/spec/util_serialization_spec.lua b/spec/util_serialization_spec.lua
index e73ca826..2af5d803 100644
--- a/spec/util_serialization_spec.lua
+++ b/spec/util_serialization_spec.lua
@@ -25,13 +25,27 @@ describe("util.serialization", function ()
t[t] = { t };
serialization.serialize(t)
end);
+ -- also with multirefs allowed
+ assert.has_error(function ()
+ local t = {}
+ t[t] = { t };
+ serialization.serialize(t, { multirefs = true })
+ end);
end);
it("rejects multiple references to same table", function ()
assert.has_error(function ()
local t1 = {};
local t2 = { t1, t1 };
- serialization.serialize(t2);
+ serialization.serialize(t2, { multirefs = false });
+ end);
+ end);
+
+ it("optionally allows multiple references to same table", function ()
+ assert.has_error(function ()
+ local t1 = {};
+ local t2 = { t1, t1 };
+ serialization.serialize(t2, { multirefs = true });
end);
end);
diff --git a/util/serialization.lua b/util/serialization.lua
index 998b16de..a8b64c04 100644
--- a/util/serialization.lua
+++ b/util/serialization.lua
@@ -120,6 +120,7 @@ local function new(opt)
local hex = opt.hex;
local freeze = opt.freeze;
local maxdepth = opt.maxdepth or 127;
+ local multirefs = opt.multiref;
-- serialize one table, recursively
-- t - table being serialized
@@ -136,7 +137,10 @@ local function new(opt)
return l;
end
+ -- Keep track of table loops
+ local ot = t; -- reference pre-freeze
o[t] = true;
+ o[ot] = true;
if freeze == true then
-- opportunity to do pre-serialization
@@ -200,6 +204,12 @@ local function new(opt)
o[l], l = s_rep(indentwith, d-1), l + 1;
end
o[l], l = tend, l +1;
+
+ if multirefs then
+ o[t] = nil;
+ o[ot] = nil;
+ end
+
return l;
end