mod_storage_memory: Serialize data functions that return the data (prevents mutation of stored data)
--- a/mod_storage_memory/mod_storage_memory.lua Thu Mar 30 23:38:40 2017 +0200
+++ b/mod_storage_memory/mod_storage_memory.lua Thu Mar 30 23:40:29 2017 +0200
@@ -1,3 +1,8 @@
+local serialize = require "util.serialization".serialize;
+local envload = require "util.envload".envload;
+local st = require "util.stanza";
+local is_stanza = st.is_stanza or function (s) return getmetatable(s) == st.stanza_mt end
+
local auto_purge_enabled = module:get_option_boolean("storage_memory_temporary", false);
local auto_purge_stores = module:get_option_set("storage_memory_temporary_stores", {});
@@ -9,7 +14,7 @@
end
});
-local NULL = {};
+local function NULL() return nil end
local function _purge_store(self, username)
self.store[username or NULL] = nil;
@@ -20,11 +25,11 @@
keyval_store.__index = keyval_store;
function keyval_store:get(username)
- return self.store[username or NULL];
+ return (self.store[username or NULL] or NULL)();
end
function keyval_store:set(username, data)
- self.store[username or NULL] = data;
+ self.store[username or NULL] = envload(serialize(data), "@data", {});
return true;
end
@@ -37,6 +42,14 @@
if type(when) ~= "number" then
when, with, value = value, when, with;
end
+ if is_stanza(value) then
+ value = st.preserialize(value);
+ value = function ()
+ return st.deserialize(envload(serialize(data), "@stanza", {}));
+ end
+ else
+ value = envload(serialize(data), "@data", {});
+ end
local a = self.store[username or NULL];
if not a then
a = {};
@@ -61,7 +74,7 @@
item = a[i];
when, with = item.when, item.with;
if when >= when_start and when_end >= when and (not match_with or match_with == with) then
- coroutine.yield(item.key, item.value, when, with);
+ coroutine.yield(item.key, item.value(), when, with);
count = count + 1;
if limit and count >= limit then return end
end