misc: check XML model files are proper UTF-8 (#58791) #973
|
@ -4,6 +4,7 @@ import time
|
||||||
import zipfile
|
import zipfile
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
from django.utils.encoding import force_bytes
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
from pyzbar.pyzbar import ZBarSymbol
|
from pyzbar.pyzbar import ZBarSymbol
|
||||||
from pyzbar.pyzbar import decode as zbar_decode_qrcode
|
from pyzbar.pyzbar import decode as zbar_decode_qrcode
|
||||||
|
@ -299,10 +300,6 @@ def test_export_to_model_django_template(pub):
|
||||||
|
|
||||||
|
|
||||||
def test_export_to_model_xml(pub):
|
def test_export_to_model_xml(pub):
|
||||||
LoggedError = pub.loggederror_class
|
|
||||||
if LoggedError:
|
|
||||||
LoggedError.wipe()
|
|
||||||
|
|
||||||
formdef = FormDef()
|
formdef = FormDef()
|
||||||
formdef.name = 'foo-export-to-template-with-django'
|
formdef.name = 'foo-export-to-template-with-django'
|
||||||
formdef.fields = [
|
formdef.fields = [
|
||||||
|
@ -320,9 +317,10 @@ def test_export_to_model_xml(pub):
|
||||||
item.attach_to_history = True
|
item.attach_to_history = True
|
||||||
|
|
||||||
def run(template, filename='/foo/template.xml', content_type='application/xml'):
|
def run(template, filename='/foo/template.xml', content_type='application/xml'):
|
||||||
|
pub.loggederror_class.wipe()
|
||||||
upload = QuixoteUpload(filename, content_type=content_type)
|
upload = QuixoteUpload(filename, content_type=content_type)
|
||||||
upload.fp = io.BytesIO()
|
upload.fp = io.BytesIO()
|
||||||
upload.fp.write(template.encode())
|
upload.fp.write(force_bytes(template))
|
||||||
upload.fp.seek(0)
|
upload.fp.seek(0)
|
||||||
item.model_file = UploadedFile(pub.app_dir, None, upload)
|
item.model_file = UploadedFile(pub.app_dir, None, upload)
|
||||||
item.convert_to_pdf = False
|
item.convert_to_pdf = False
|
||||||
|
@ -340,18 +338,23 @@ def test_export_to_model_xml(pub):
|
||||||
assert run(template='<a>{{ form_var_string }}</a>', filename='/foo/template.svg') == '<a>écho</a>'
|
assert run(template='<a>{{ form_var_string }}</a>', filename='/foo/template.svg') == '<a>écho</a>'
|
||||||
|
|
||||||
# unknown file format
|
# unknown file format
|
||||||
with pytest.raises(UploadValidationError):
|
with pytest.raises(UploadValidationError) as e:
|
||||||
run(
|
run(
|
||||||
template='<a>{{ form_var_string }}</a>',
|
template='<a>{{ form_var_string }}</a>',
|
||||||
filename='/foo/template.txt',
|
filename='/foo/template.txt',
|
||||||
content_type='application/octet-stream',
|
content_type='application/octet-stream',
|
||||||
)
|
)
|
||||||
|
assert str(e.value) == 'Only OpenDocument and XML files can be used.'
|
||||||
|
|
||||||
|
# invalid UTF-8
|
||||||
|
with pytest.raises(UploadValidationError) as e:
|
||||||
|
assert run(template=b'<name>test \xE0 {{form_var_string}}</name>') == ''
|
||||||
|
assert str(e.value) == 'XML model files must be UTF-8.'
|
||||||
|
|
||||||
# malformed XML
|
# malformed XML
|
||||||
assert not LoggedError or LoggedError.count() == 0
|
|
||||||
assert run(template='<a>{{ form_var_string }}<a>') == '<a>écho<a>'
|
assert run(template='<a>{{ form_var_string }}<a>') == '<a>écho<a>'
|
||||||
# on error in the XML correctness no exception is raised but an error is logged
|
# on error in the XML correctness no exception is raised but an error is logged
|
||||||
assert not LoggedError or LoggedError.count() == 1
|
assert pub.loggederror_class.count() == 1
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('filename', ['template-form-details.odt', 'template-form-details-no-styles.odt'])
|
@pytest.mark.parametrize('filename', ['template-form-details.odt', 'template-form-details-no-styles.odt'])
|
||||||
|
|
|
@ -361,13 +361,18 @@ class ExportToModel(WorkflowStatusItem):
|
||||||
|
|
||||||
# XML
|
# XML
|
||||||
fp.seek(0)
|
fp.seek(0)
|
||||||
xml_prefix = fp.read(1)
|
xml_content = fp.read()
|
||||||
fp.seek(0)
|
fp.seek(0)
|
||||||
if (upload.content_type and upload.content_type in ('text/xml', 'application/xml')) or (
|
if (upload.content_type and upload.content_type in ('text/xml', 'application/xml')) or (
|
||||||
upload.base_filename and upload.base_filename.endswith('.xml') and xml_prefix == b'<'
|
upload.base_filename and upload.base_filename.endswith('.xml') and xml_content.startswith(b'<')
|
||||||
):
|
):
|
||||||
|
# check XML content is valid UTF-8
|
||||||
|
try:
|
||||||
|
xml_content.decode('utf-8')
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
raise UploadValidationError(_('XML model files must be UTF-8.'))
|
||||||
return 'xml'
|
return 'xml'
|
||||||
raise UploadValidationError(_('Only OpenDocument and XML files can be used'))
|
raise UploadValidationError(_('Only OpenDocument and XML files can be used.'))
|
||||||
|
|
||||||
def get_parameters(self):
|
def get_parameters(self):
|
||||||
parameters = ('model_file',)
|
parameters = ('model_file',)
|
||||||
|
|
Loading…
Reference in New Issue