aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKim Alvefur <zash@zash.se>2018-12-01 18:30:19 +0100
committerKim Alvefur <zash@zash.se>2018-12-01 18:30:19 +0100
commit010770585cd6899a66fd5373192a94d479e74c86 (patch)
tree8344b048fdcf2d8096afffb387dd948d2ce09c5d
parent33472e319cf93b8fb0337e146c3defaf98166a3a (diff)
downloadprosody-010770585cd6899a66fd5373192a94d479e74c86.tar.gz
prosody-010770585cd6899a66fd5373192a94d479e74c86.zip
util.stanza: Deserialize stanza without mutating input (fixes #711)
-rw-r--r--util/stanza.lua44
1 files changed, 17 insertions, 27 deletions
diff --git a/util/stanza.lua b/util/stanza.lua
index 8d199912..a90d56b3 100644
--- a/util/stanza.lua
+++ b/util/stanza.lua
@@ -361,41 +361,31 @@ end
stanza_mt.__freeze = preserialize;
-local function deserialize(stanza)
+local function deserialize(serialized)
-- Set metatable
- if stanza then
- local attr = stanza.attr;
- for i=1,#attr do attr[i] = nil; end
+ if serialized then
+ local attr = serialized.attr;
local attrx = {};
- for att in pairs(attr) do
- if s_find(att, "|", 1, true) and not s_find(att, "\1", 1, true) then
- local ns,na = s_match(att, "^([^|]+)|(.+)$");
- attrx[ns.."\1"..na] = attr[att];
- attr[att] = nil;
+ for att, val in pairs(attr) do
+ if type(att) == "string" then
+ if s_find(att, "|", 1, true) and not s_find(att, "\1", 1, true) then
+ local ns,na = s_match(att, "^([^|]+)|(.+)$");
+ attrx[ns.."\1"..na] = val;
+ else
+ attrx[att] = val;
+ end
end
end
- for a,v in pairs(attrx) do
- attr[a] = v;
- end
- setmetatable(stanza, stanza_mt);
- for _, child in ipairs(stanza) do
+ local stanza = new_stanza(serialized.name, attrx);
+ for _, child in ipairs(serialized) do
if type(child) == "table" then
- deserialize(child);
- end
- end
- if not stanza.tags then
- -- Rebuild tags
- local tags = {};
- for _, child in ipairs(stanza) do
- if type(child) == "table" then
- t_insert(tags, child);
- end
+ stanza:add_direct_child(deserialize(child));
+ elseif type(child) == "string" then
+ stanza:add_direct_child(child);
end
- stanza.tags = tags;
end
+ return stanza;
end
-
- return stanza;
end
local function _clone(stanza)