From 20429527b1c455e2c6784d717c48d69e80b1138b Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 28 Dec 2018 20:49:01 +0100 Subject: util.stanza: Require a type attribute for iq stanzas --- util/stanza.lua | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'util/stanza.lua') diff --git a/util/stanza.lua b/util/stanza.lua index a90d56b3..e9847ca6 100644 --- a/util/stanza.lua +++ b/util/stanza.lua @@ -423,9 +423,15 @@ local function message(attr, body) end end local function iq(attr) - if not (attr and attr.id) then + if not attr then + error("iq stanzas require id and type attributes"); + end + if not attr.id then error("iq stanzas require an id attribute"); end + if not attr.type then + error("iq stanzas require a type attribute"); + end return new_stanza("iq", attr); end -- cgit v1.2.3 From e1b559853fb0f6e0967124a135e1d380d02316d9 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Mon, 25 Mar 2019 14:37:43 +0000 Subject: util.stanza: Fix :top_tag() handling of namespaced attributes --- util/stanza.lua | 62 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 30 insertions(+), 32 deletions(-) (limited to 'util/stanza.lua') diff --git a/util/stanza.lua b/util/stanza.lua index e9847ca6..7fe5c7ae 100644 --- a/util/stanza.lua +++ b/util/stanza.lua @@ -270,6 +270,34 @@ function stanza_mt:find(path) until not self end +local function _clone(stanza, only_top) + local attr, tags = {}, {}; + for k,v in pairs(stanza.attr) do attr[k] = v; end + local old_namespaces, namespaces = stanza.namespaces; + if old_namespaces then + namespaces = {}; + for k,v in pairs(old_namespaces) do namespaces[k] = v; end + end + local new = { name = stanza.name, attr = attr, namespaces = namespaces, tags = tags }; + if not only_top then + for i=1,#stanza do + local child = stanza[i]; + if child.name then + child = _clone(child); + t_insert(tags, child); + end + t_insert(new, child); + end + end + return setmetatable(new, stanza_mt); +end + +local function clone(stanza, only_top) + if not is_stanza(stanza) then + error("bad argument to clone: expected stanza, got "..type(stanza)); + end + return _clone(stanza, only_top); +end local escape_table = { ["'"] = "'", ["\""] = """, ["<"] = "<", [">"] = ">", ["&"] = "&" }; local function xml_escape(str) return (s_gsub(str, "['&<>\"]", escape_table)); end @@ -310,11 +338,8 @@ function stanza_mt.__tostring(t) end function stanza_mt.top_tag(t) - local attr_string = ""; - if t.attr then - for k, v in pairs(t.attr) do if type(k) == "string" then attr_string = attr_string .. s_format(" %s='%s'", k, xml_escape(tostring(v))); end end - end - return s_format("<%s%s>", t.name, attr_string); + local top_tag_clone = clone(t, true); + return tostring(top_tag_clone):sub(1,-3)..">"; end function stanza_mt.get_text(t) @@ -388,33 +413,6 @@ local function deserialize(serialized) end end -local function _clone(stanza) - local attr, tags = {}, {}; - for k,v in pairs(stanza.attr) do attr[k] = v; end - local old_namespaces, namespaces = stanza.namespaces; - if old_namespaces then - namespaces = {}; - for k,v in pairs(old_namespaces) do namespaces[k] = v; end - end - local new = { name = stanza.name, attr = attr, namespaces = namespaces, tags = tags }; - for i=1,#stanza do - local child = stanza[i]; - if child.name then - child = _clone(child); - t_insert(tags, child); - end - t_insert(new, child); - end - return setmetatable(new, stanza_mt); -end - -local function clone(stanza) - if not is_stanza(stanza) then - error("bad argument to clone: expected stanza, got "..type(stanza)); - end - return _clone(stanza); -end - local function message(attr, body) if not body then return new_stanza("message", attr); -- cgit v1.2.3 From 6e624e01c69504684b4afc4e4b1499da2d957c3d Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 2 Aug 2019 08:56:29 +0200 Subject: util.stanza: Use :text_tag internally everywhere May allow future changes in a single place. --- util/stanza.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'util/stanza.lua') diff --git a/util/stanza.lua b/util/stanza.lua index 7fe5c7ae..55c38c73 100644 --- a/util/stanza.lua +++ b/util/stanza.lua @@ -98,7 +98,7 @@ function stanza_mt:query(xmlns) end function stanza_mt:body(text, attr) - return self:tag("body", attr):text(text); + return self:text_tag("body", text, attr); end function stanza_mt:text_tag(name, text, attr, namespaces) @@ -417,7 +417,7 @@ local function message(attr, body) if not body then return new_stanza("message", attr); else - return new_stanza("message", attr):tag("body"):text(body):up(); + return new_stanza("message", attr):text_tag("body", body); end end local function iq(attr) @@ -449,7 +449,7 @@ local function error_reply(orig, error_type, condition, error_message) t.attr.type = "error"; t:tag("error", {type = error_type}) --COMPAT: Some day xmlns:stanzas goes here :tag(condition, xmpp_stanzas_attr):up(); - if error_message then t:tag("text", xmpp_stanzas_attr):text(error_message):up(); end + if error_message then t:text_tag("text", error_message, xmpp_stanzas_attr); end return t; -- stanza ready for adding app-specific errors end -- cgit v1.2.3 From b340e5e4628e2f5c136fe1f4300821d89ed4cb94 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 25 Nov 2019 20:44:05 +0100 Subject: util.stanza: Check that argument to reply is a stanza --- util/stanza.lua | 3 +++ 1 file changed, 3 insertions(+) (limited to 'util/stanza.lua') diff --git a/util/stanza.lua b/util/stanza.lua index 55c38c73..f46d5b30 100644 --- a/util/stanza.lua +++ b/util/stanza.lua @@ -434,6 +434,9 @@ local function iq(attr) end local function reply(orig) + if not is_stanza(orig) then + error("bad argument to reply: expected stanza, got "..type(orig)); + end return new_stanza(orig.name, orig.attr and { to = orig.attr.from, -- cgit v1.2.3 From 11095184a53cc144e37560b7bbbf4de19ce669c7 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 25 Nov 2019 20:46:55 +0100 Subject: util.stanza: Remove redundant check for attrs A stanza can't not have attrs if created the correct way --- util/stanza.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'util/stanza.lua') diff --git a/util/stanza.lua b/util/stanza.lua index f46d5b30..919d983c 100644 --- a/util/stanza.lua +++ b/util/stanza.lua @@ -438,7 +438,7 @@ local function reply(orig) error("bad argument to reply: expected stanza, got "..type(orig)); end return new_stanza(orig.name, - orig.attr and { + { to = orig.attr.from, from = orig.attr.to, id = orig.attr.id, -- cgit v1.2.3 From 52b7181979bcee9000acf1c90e85934976e4da6a Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 25 Nov 2019 20:52:01 +0100 Subject: util.stanza: Check that argument to error_reply is a stanza --- util/stanza.lua | 3 +++ 1 file changed, 3 insertions(+) (limited to 'util/stanza.lua') diff --git a/util/stanza.lua b/util/stanza.lua index 919d983c..24fd4fea 100644 --- a/util/stanza.lua +++ b/util/stanza.lua @@ -448,6 +448,9 @@ end local xmpp_stanzas_attr = { xmlns = xmlns_stanzas }; local function error_reply(orig, error_type, condition, error_message) + if not is_stanza(orig) then + error("bad argument to error_reply: expected stanza, got "..type(orig)); + end local t = reply(orig); t.attr.type = "error"; t:tag("error", {type = error_type}) --COMPAT: Some day xmlns:stanzas goes here -- cgit v1.2.3 From 54da2ab6f7fec145d05ac8682c50a776bb993880 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 25 Nov 2019 20:52:03 +0100 Subject: util.stanza: Check that argument to error_reply is NOT a stanza of type error Replying to an error is Very Bad --- util/stanza.lua | 2 ++ 1 file changed, 2 insertions(+) (limited to 'util/stanza.lua') diff --git a/util/stanza.lua b/util/stanza.lua index 24fd4fea..8ff1aae3 100644 --- a/util/stanza.lua +++ b/util/stanza.lua @@ -450,6 +450,8 @@ local xmpp_stanzas_attr = { xmlns = xmlns_stanzas }; local function error_reply(orig, error_type, condition, error_message) if not is_stanza(orig) then error("bad argument to error_reply: expected stanza, got "..type(orig)); + elseif orig.attr.type == "error" then + error("bad argument to error_reply: got stanza of type error which must not be replied to"); end local t = reply(orig); t.attr.type = "error"; -- cgit v1.2.3 From be23b274f685f5eac73b79231491f4f0141f1c1c Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 25 Nov 2019 20:59:36 +0100 Subject: util.stanza: Support the 'by' attribute on errors This is to be used when the entity generating the error is not the same as the one the stanza was directed to, e.g. an intermediate server. --- util/stanza.lua | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'util/stanza.lua') diff --git a/util/stanza.lua b/util/stanza.lua index 8ff1aae3..8e46f90f 100644 --- a/util/stanza.lua +++ b/util/stanza.lua @@ -447,7 +447,7 @@ local function reply(orig) end local xmpp_stanzas_attr = { xmlns = xmlns_stanzas }; -local function error_reply(orig, error_type, condition, error_message) +local function error_reply(orig, error_type, condition, error_message, error_by) if not is_stanza(orig) then error("bad argument to error_reply: expected stanza, got "..type(orig)); elseif orig.attr.type == "error" then @@ -455,7 +455,10 @@ local function error_reply(orig, error_type, condition, error_message) end local t = reply(orig); t.attr.type = "error"; - t:tag("error", {type = error_type}) --COMPAT: Some day xmlns:stanzas goes here + if t.attr.from == error_by then + error_by = nil; + end + t:tag("error", {type = error_type, by = error_by}) --COMPAT: Some day xmlns:stanzas goes here :tag(condition, xmpp_stanzas_attr):up(); if error_message then t:text_tag("text", error_message, xmpp_stanzas_attr); end return t; -- stanza ready for adding app-specific errors -- cgit v1.2.3 From 4e34c40ece0eb19f85720d63b1b0372f59e5616d Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sat, 14 Dec 2019 22:47:41 +0100 Subject: util.stanza: Accept util.error object to error_reply If we're moving towards util.error as the standard error container then this makes sense. This may allow for future extensibility without needing a lot of optional arguments. --- util/stanza.lua | 3 +++ 1 file changed, 3 insertions(+) (limited to 'util/stanza.lua') diff --git a/util/stanza.lua b/util/stanza.lua index 8e46f90f..f5cd5668 100644 --- a/util/stanza.lua +++ b/util/stanza.lua @@ -458,6 +458,9 @@ local function error_reply(orig, error_type, condition, error_message, error_by) if t.attr.from == error_by then error_by = nil; end + if type(error_type) == "table" then -- an util.error or similar object + error_type, condition, error_message = error_type.type, error_type.condition, error_type.text; + end t:tag("error", {type = error_type, by = error_by}) --COMPAT: Some day xmlns:stanzas goes here :tag(condition, xmpp_stanzas_attr):up(); if error_message then t:text_tag("text", error_message, xmpp_stanzas_attr); end -- cgit v1.2.3