Software / code / prosody
Comparison
util/stanza.lua @ 9924:5a2e53bef031
util.stanza: Fix :top_tag() handling of namespaced attributes
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Mon, 25 Mar 2019 14:37:43 +0000 |
| parent | 9732:51583ea2b4fd |
| child | 10116:4807535b8673 |
comparison
equal
deleted
inserted
replaced
| 9923:e83dfcdeab59 | 9924:5a2e53bef031 |
|---|---|
| 268 end | 268 end |
| 269 self = self:get_child(name, xmlns); | 269 self = self:get_child(name, xmlns); |
| 270 until not self | 270 until not self |
| 271 end | 271 end |
| 272 | 272 |
| 273 local function _clone(stanza, only_top) | |
| 274 local attr, tags = {}, {}; | |
| 275 for k,v in pairs(stanza.attr) do attr[k] = v; end | |
| 276 local old_namespaces, namespaces = stanza.namespaces; | |
| 277 if old_namespaces then | |
| 278 namespaces = {}; | |
| 279 for k,v in pairs(old_namespaces) do namespaces[k] = v; end | |
| 280 end | |
| 281 local new = { name = stanza.name, attr = attr, namespaces = namespaces, tags = tags }; | |
| 282 if not only_top then | |
| 283 for i=1,#stanza do | |
| 284 local child = stanza[i]; | |
| 285 if child.name then | |
| 286 child = _clone(child); | |
| 287 t_insert(tags, child); | |
| 288 end | |
| 289 t_insert(new, child); | |
| 290 end | |
| 291 end | |
| 292 return setmetatable(new, stanza_mt); | |
| 293 end | |
| 294 | |
| 295 local function clone(stanza, only_top) | |
| 296 if not is_stanza(stanza) then | |
| 297 error("bad argument to clone: expected stanza, got "..type(stanza)); | |
| 298 end | |
| 299 return _clone(stanza, only_top); | |
| 300 end | |
| 273 | 301 |
| 274 local escape_table = { ["'"] = "'", ["\""] = """, ["<"] = "<", [">"] = ">", ["&"] = "&" }; | 302 local escape_table = { ["'"] = "'", ["\""] = """, ["<"] = "<", [">"] = ">", ["&"] = "&" }; |
| 275 local function xml_escape(str) return (s_gsub(str, "['&<>\"]", escape_table)); end | 303 local function xml_escape(str) return (s_gsub(str, "['&<>\"]", escape_table)); end |
| 276 | 304 |
| 277 local function _dostring(t, buf, self, _xml_escape, parentns) | 305 local function _dostring(t, buf, self, _xml_escape, parentns) |
| 308 _dostring(t, buf, _dostring, xml_escape, nil); | 336 _dostring(t, buf, _dostring, xml_escape, nil); |
| 309 return t_concat(buf); | 337 return t_concat(buf); |
| 310 end | 338 end |
| 311 | 339 |
| 312 function stanza_mt.top_tag(t) | 340 function stanza_mt.top_tag(t) |
| 313 local attr_string = ""; | 341 local top_tag_clone = clone(t, true); |
| 314 if t.attr then | 342 return tostring(top_tag_clone):sub(1,-3)..">"; |
| 315 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 | |
| 316 end | |
| 317 return s_format("<%s%s>", t.name, attr_string); | |
| 318 end | 343 end |
| 319 | 344 |
| 320 function stanza_mt.get_text(t) | 345 function stanza_mt.get_text(t) |
| 321 if #t.tags == 0 then | 346 if #t.tags == 0 then |
| 322 return t_concat(t); | 347 return t_concat(t); |
| 384 stanza:add_direct_child(child); | 409 stanza:add_direct_child(child); |
| 385 end | 410 end |
| 386 end | 411 end |
| 387 return stanza; | 412 return stanza; |
| 388 end | 413 end |
| 389 end | |
| 390 | |
| 391 local function _clone(stanza) | |
| 392 local attr, tags = {}, {}; | |
| 393 for k,v in pairs(stanza.attr) do attr[k] = v; end | |
| 394 local old_namespaces, namespaces = stanza.namespaces; | |
| 395 if old_namespaces then | |
| 396 namespaces = {}; | |
| 397 for k,v in pairs(old_namespaces) do namespaces[k] = v; end | |
| 398 end | |
| 399 local new = { name = stanza.name, attr = attr, namespaces = namespaces, tags = tags }; | |
| 400 for i=1,#stanza do | |
| 401 local child = stanza[i]; | |
| 402 if child.name then | |
| 403 child = _clone(child); | |
| 404 t_insert(tags, child); | |
| 405 end | |
| 406 t_insert(new, child); | |
| 407 end | |
| 408 return setmetatable(new, stanza_mt); | |
| 409 end | |
| 410 | |
| 411 local function clone(stanza) | |
| 412 if not is_stanza(stanza) then | |
| 413 error("bad argument to clone: expected stanza, got "..type(stanza)); | |
| 414 end | |
| 415 return _clone(stanza); | |
| 416 end | 414 end |
| 417 | 415 |
| 418 local function message(attr, body) | 416 local function message(attr, body) |
| 419 if not body then | 417 if not body then |
| 420 return new_stanza("message", attr); | 418 return new_stanza("message", attr); |