1 |
1 |
2 local st = require "util.stanza"; |
2 local st = require "util.stanza"; |
3 local lxp = require "lxp"; |
3 local lxp = require "lxp"; |
4 local t_insert = table.insert; |
4 local t_insert = table.insert; |
5 local t_remove = table.remove; |
5 local t_remove = table.remove; |
|
6 local error = error; |
6 |
7 |
7 local _ENV = nil; |
8 local _ENV = nil; |
8 -- luacheck: std none |
9 -- luacheck: std none |
9 |
10 |
10 local parse_xml = (function() |
11 local parse_xml = (function() |
11 local ns_prefixes = { |
12 local ns_prefixes = { |
12 ["http://www.w3.org/XML/1998/namespace"] = "xml"; |
13 ["http://www.w3.org/XML/1998/namespace"] = "xml"; |
13 }; |
14 }; |
14 local ns_separator = "\1"; |
15 local ns_separator = "\1"; |
15 local ns_pattern = "^([^"..ns_separator.."]*)"..ns_separator.."?(.*)$"; |
16 local ns_pattern = "^([^"..ns_separator.."]*)"..ns_separator.."?(.*)$"; |
16 return function(xml) |
17 return function(xml, options) |
17 --luacheck: ignore 212/self |
18 --luacheck: ignore 212/self |
18 local handler = {}; |
19 local handler = {}; |
19 local stanza = st.stanza("root"); |
20 local stanza = st.stanza("root"); |
20 local namespaces = {}; |
21 local namespaces = {}; |
21 local prefixes = {}; |
22 local prefixes = {}; |
62 stanza:text(data); |
63 stanza:text(data); |
63 end |
64 end |
64 function handler:EndElement() |
65 function handler:EndElement() |
65 stanza:up(); |
66 stanza:up(); |
66 end |
67 end |
67 local parser = lxp.new(handler, "\1"); |
68 local parser; |
|
69 -- SECURITY: These two handlers, especially the Doctype one, are required to prevent exploits such as Billion Laughs. |
|
70 function handler:StartDoctypeDecl() |
|
71 if not parser.stop or not parser:stop() then |
|
72 error("Failed to abort parsing"); |
|
73 end |
|
74 end |
|
75 function handler:ProcessingInstruction() |
|
76 if not parser.stop or not parser:stop() then |
|
77 error("Failed to abort parsing"); |
|
78 end |
|
79 end |
|
80 if not options or not options.allow_comments then |
|
81 -- NOTE: comments are generally harmless and can be useful when parsing configuration files or other data, even user-provided data |
|
82 function handler:Comment() |
|
83 if not parser.stop or not parser:stop() then |
|
84 error("Failed to abort parsing"); |
|
85 end |
|
86 end |
|
87 end |
|
88 parser = lxp.new(handler, ns_separator); |
68 local ok, err, line, col = parser:parse(xml); |
89 local ok, err, line, col = parser:parse(xml); |
69 if ok then ok, err, line, col = parser:parse(); end |
90 if ok then ok, err, line, col = parser:parse(); end |
70 --parser:close(); |
91 --parser:close(); |
71 if ok then |
92 if ok then |
72 return stanza.tags[1]; |
93 return stanza.tags[1]; |