mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Use a per-thread XML parser instance
This commit is contained in:
parent
d102aca175
commit
e5d6a6ef9f
@ -6,14 +6,29 @@ from __future__ import absolute_import, division, print_function, unicode_litera
|
||||
|
||||
|
||||
from lxml import etree
|
||||
import threading
|
||||
|
||||
|
||||
# resolve_entities is turned off as entities can cause
|
||||
# reads of local files, for example:
|
||||
# <!DOCTYPE foo [ <!ENTITY passwd SYSTEM "file:///etc/passwd" >]>
|
||||
SAFE_XML_PARSER = etree.XMLParser(recover=True, no_network=True, resolve_entities=False)
|
||||
SAFE_XML_PARSER_NO_RECOVER = etree.XMLParser(recover=False, no_network=True, resolve_entities=False)
|
||||
|
||||
|
||||
class GlobalParserTLS(threading.local):
|
||||
|
||||
def __call__(self, recover):
|
||||
parsers = getattr(self, 'parsers', None)
|
||||
if parsers is None:
|
||||
self.parsers = parsers = {
|
||||
True: etree.XMLParser(recover=True, no_network=True, resolve_entities=False),
|
||||
False: etree.XMLParser(recover=False, no_network=True, resolve_entities=False)
|
||||
}
|
||||
return parsers[recover]
|
||||
|
||||
|
||||
_global_tls = GlobalParserTLS()
|
||||
fs = etree.fromstring
|
||||
|
||||
|
||||
def safe_xml_fromstring(string_or_bytes, recover=True):
|
||||
return fs(string_or_bytes, SAFE_XML_PARSER if recover else SAFE_XML_PARSER_NO_RECOVER)
|
||||
return fs(string_or_bytes, _global_tls(recover))
|
||||
|
Loading…
x
Reference in New Issue
Block a user