Может ли etree.XMLParser в режиме восстановления по-прежнему выдавать ошибку разбора? - PullRequest
1 голос
/ 22 мая 2019

У меня есть служебный метод, который анализирует XML с помощью парсера, созданного как etree.XMLParser(recover=True). Я хотел бы протестировать сценарии сбоев в модульном тесте. За исключением пустого ввода, выдавшего lxml.etree.XMLSyntaxError, я не могу сломать парсер.

У меня вопрос: возможно ли построить для этого парсера вход StringIO или BytesIO так, чтобы он генерировал ошибку разбора?

Вот несколько примеров (протестировано с Python 3.5 и lxml 4.3.3):

from io import BytesIO
from lxml import etree


def parse(xml):
    parser = etree.XMLParser(recover=True)
    elem = etree.parse(BytesIO(xml), parser)
    print(etree.tostring(elem))


parse(b'<broken<')  # prints b'<broken/>'
parse(b'</lf|\jf>')  # prints None
parse('<?xml encoding="ascii"?><foo>æøå</foo>'.encode('utf-8'))  # prints b'<foo/>'
parse(b'')  # Throws lxml.etree.XMLSyntaxError

Ответы [ 2 ]

3 голосов
/ 30 мая 2019

Если я шлепаю символ NULL в начале любого из показанных вами неверных входных данных, которые не вызывают ошибку, я получаю ошибку.Например:

parse(b'\0<broken<')

производит:

Traceback (most recent call last):
  File "test.py", line 13, in <module>
    parse(b'\0<broken<')  # prints b'<broken/>'
  File "test.py", line 9, in parse
    elem = etree.parse(BytesIO(xml), parser)
  File "src/lxml/etree.pyx", line 3435, in lxml.etree.parse
  File "src/lxml/parser.pxi", line 1857, in lxml.etree._parseDocument
  File "src/lxml/parser.pxi", line 1877, in lxml.etree._parseMemoryDocument
  File "src/lxml/parser.pxi", line 1765, in lxml.etree._parseDoc
  File "src/lxml/parser.pxi", line 1127, in lxml.etree._BaseParser._parseDoc
  File "src/lxml/parser.pxi", line 601, in lxml.etree._ParserContext._handleParseResultDoc
  File "src/lxml/parser.pxi", line 711, in lxml.etree._handleParseResult
  File "src/lxml/parser.pxi", line 640, in lxml.etree._raiseParseError
  File "<string>", line 1
lxml.etree.XMLSyntaxError: Document is empty, line 1, column 1
0 голосов
/ 05 июня 2019

Разве это не потому, что вы используете recovery = True?

restore - попытаться разобрать поврежденный XML

Я изменил recovery = False и получаю:

Traceback (most recent call last):
  File "./foo.py", line 11, in <module>
    parse(b'<broken<')  # prints b'<broken/>'
  File "./foo.py", line 7, in parse
    elem = etree.parse(BytesIO(xml), parser)
  File "src/lxml/etree.pyx", line 3435, in lxml.etree.parse
  File "src/lxml/parser.pxi", line 1857, in lxml.etree._parseDocument
  File "src/lxml/parser.pxi", line 1877, in lxml.etree._parseMemoryDocument
  File "src/lxml/parser.pxi", line 1765, in lxml.etree._parseDoc
  File "src/lxml/parser.pxi", line 1127, in lxml.etree._BaseParser._parseDoc
  File "src/lxml/parser.pxi", line 601, in lxml.etree._ParserContext._handleParseResultDoc
  File "src/lxml/parser.pxi", line 711, in lxml.etree._handleParseResult
  File "src/lxml/parser.pxi", line 640, in lxml.etree._raiseParseError
  File "<string>", line 1
lxml.etree.XMLSyntaxError: error parsing attribute name, line 1, column 8

Я что-то упустил?

...