util.x509: Only collect commonNames that pass idna
[prosody.git] / util / xml.lua
blobdac3f6fe80972335342edeaf6e194680614f7957
2 local st = require "util.stanza";
3 local lxp = require "lxp";
4 local t_insert = table.insert;
5 local t_remove = table.remove;
7 local _ENV = nil;
8 -- luacheck: std none
10 local parse_xml = (function()
11 local ns_prefixes = {
12 ["http://www.w3.org/XML/1998/namespace"] = "xml";
14 local ns_separator = "\1";
15 local ns_pattern = "^([^"..ns_separator.."]*)"..ns_separator.."?(.*)$";
16 return function(xml)
17 --luacheck: ignore 212/self
18 local handler = {};
19 local stanza = st.stanza("root");
20 local namespaces = {};
21 local prefixes = {};
22 function handler:StartNamespaceDecl(prefix, url)
23 if prefix ~= nil then
24 t_insert(namespaces, url);
25 t_insert(prefixes, prefix);
26 end
27 end
28 function handler:EndNamespaceDecl(prefix)
29 if prefix ~= nil then
30 -- we depend on each StartNamespaceDecl having a paired EndNamespaceDecl
31 t_remove(namespaces);
32 t_remove(prefixes);
33 end
34 end
35 function handler:StartElement(tagname, attr)
36 local curr_ns,name = tagname:match(ns_pattern);
37 if name == "" then
38 curr_ns, name = "", curr_ns;
39 end
40 if curr_ns ~= "" then
41 attr.xmlns = curr_ns;
42 end
43 for i=1,#attr do
44 local k = attr[i];
45 attr[i] = nil;
46 local ns, nm = k:match(ns_pattern);
47 if nm ~= "" then
48 ns = ns_prefixes[ns];
49 if ns then
50 attr[ns..":"..nm] = attr[k];
51 attr[k] = nil;
52 end
53 end
54 end
55 local n = {}
56 for i=1,#namespaces do
57 n[prefixes[i]] = namespaces[i];
58 end
59 stanza:tag(name, attr, n);
60 end
61 function handler:CharacterData(data)
62 stanza:text(data);
63 end
64 function handler:EndElement()
65 stanza:up();
66 end
67 local parser = lxp.new(handler, "\1");
68 local ok, err, line, col = parser:parse(xml);
69 if ok then ok, err, line, col = parser:parse(); end
70 --parser:close();
71 if ok then
72 return stanza.tags[1];
73 else
74 return ok, err.." (line "..line..", col "..col..")";
75 end
76 end;
77 end)();
79 return {
80 parse = parse_xml;