Comparison

util/xml.lua @ 12201:e5e0ab93d7f4 0.11

util.xml: Break reference to help the GC (fix #1711) LuaExpat uses a registry reference to track handlers, which makes it so that an upvalue like this creates a reference loop that keeps the parser and its handlers from being garbage collected. The same issue has affected util.xmppstream in the past. Code for checking: local xml_parse = require"util.xml".parse; for i = 1, 10000 do xml_parse("<root/>") end collectgarbage(); collectgarbage(); print(collectgarbage("count"), "KiB"); A future release of LuaExpat may fix the underlying issue there.
author Kim Alvefur <zash@zash.se>
date Thu, 20 Jan 2022 09:57:20 +0100
parent 12181:783056b4e448
child 12202:ebeb4d959fb3
comparison
equal deleted inserted replaced
12182:5e21cf21d398 12201:e5e0ab93d7f4
63 stanza:text(data); 63 stanza:text(data);
64 end 64 end
65 function handler:EndElement() 65 function handler:EndElement()
66 stanza:up(); 66 stanza:up();
67 end 67 end
68 local parser;
69 -- SECURITY: These two handlers, especially the Doctype one, are required to prevent exploits such as Billion Laughs. 68 -- SECURITY: These two handlers, especially the Doctype one, are required to prevent exploits such as Billion Laughs.
70 function handler:StartDoctypeDecl() 69 function handler:StartDoctypeDecl()
71 if not parser.stop or not parser:stop() then 70 if not self.stop or not self:stop() then
72 error("Failed to abort parsing"); 71 error("Failed to abort parsing");
73 end 72 end
74 end 73 end
75 function handler:ProcessingInstruction() 74 function handler:ProcessingInstruction()
76 if not parser.stop or not parser:stop() then 75 if not self.stop or not self:stop() then
77 error("Failed to abort parsing"); 76 error("Failed to abort parsing");
78 end 77 end
79 end 78 end
80 if not options or not options.allow_comments then 79 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 80 -- NOTE: comments are generally harmless and can be useful when parsing configuration files or other data, even user-provided data
82 function handler:Comment() 81 function handler:Comment()
83 if not parser.stop or not parser:stop() then 82 if not self.stop or not self:stop() then
84 error("Failed to abort parsing"); 83 error("Failed to abort parsing");
85 end 84 end
86 end 85 end
87 end 86 end
88 parser = lxp.new(handler, ns_separator); 87 local parser = lxp.new(handler, ns_separator);
89 local ok, err, line, col = parser:parse(xml); 88 local ok, err, line, col = parser:parse(xml);
90 if ok then ok, err, line, col = parser:parse(); end 89 if ok then ok, err, line, col = parser:parse(); end
91 --parser:close(); 90 --parser:close();
92 if ok then 91 if ok then
93 return stanza.tags[1]; 92 return stanza.tags[1];