Hello community, here is the log from the commit of package python-relatorio for openSUSE:Factory checked in at 2018-10-04 19:02:02 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-relatorio (Old) and /work/SRC/openSUSE:Factory/.python-relatorio.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-relatorio" Thu Oct 4 19:02:02 2018 rev:6 rq:639874 version:0.8.1 Changes: -------- --- /work/SRC/openSUSE:Factory/python-relatorio/python-relatorio.changes 2017-12-14 10:57:29.287600635 +0100 +++ /work/SRC/openSUSE:Factory/.python-relatorio.new/python-relatorio.changes 2018-10-04 19:02:15.835154854 +0200 @@ -1,0 +2,10 @@ +Wed Oct 3 20:01:38 UTC 2018 - Axel Braun <[email protected]> + +- version 0.8.1 + * Add support for Python 3.7 + * Escape invalid XML characters + * Enforce closing tag to be the same directive as the opening + * Use compression for zip file + * Write mimetype as first file of the zip file + +------------------------------------------------------------------- Old: ---- relatorio-0.8.0.tar.gz New: ---- relatorio-0.8.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-relatorio.spec ++++++ --- /var/tmp/diff_new_pack.AIlrl7/_old 2018-10-04 19:02:17.219153399 +0200 +++ /var/tmp/diff_new_pack.AIlrl7/_new 2018-10-04 19:02:17.227153390 +0200 @@ -1,8 +1,8 @@ # # spec file for package python-relatorio # -# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany. -# Copyright (c) 2016-2017 Dr. Axel Braun +# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2016-2018 Dr. Axel Braun # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -21,7 +21,7 @@ %bcond_with tests %define mod_name relatorio Name: python-relatorio -Version: 0.8.0 +Version: 0.8.1 Release: 0 Summary: Python module to create reports from Python objects License: GPL-3.0+ @@ -61,7 +61,8 @@ %endif %files %{python_files} -%doc README AUTHORS LICENSE +%license LICENSE +%doc README AUTHORS %{python_sitelib}/* %changelog ++++++ relatorio-0.8.0.tar.gz -> relatorio-0.8.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/relatorio-0.8.0/.drone.yml new/relatorio-0.8.1/.drone.yml --- old/relatorio-0.8.0/.drone.yml 2017-11-20 11:04:12.000000000 +0100 +++ new/relatorio-0.8.1/.drone.yml 2018-08-18 13:27:26.000000000 +0200 @@ -17,11 +17,11 @@ include: - IMAGE: python:2.7 TOXENV: py27 - - IMAGE: python:3.3 - TOXENV: py33 - IMAGE: python:3.4 TOXENV: py34 - IMAGE: python:3.5 TOXENV: py35 - IMAGE: python:3.6 TOXENV: py36 + - IMAGE: python:3.7 + TOXENV: py37 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/relatorio-0.8.0/.hgtags new/relatorio-0.8.1/.hgtags --- old/relatorio-0.8.0/.hgtags 2017-12-04 16:25:33.000000000 +0100 +++ new/relatorio-0.8.1/.hgtags 2018-09-30 14:43:38.000000000 +0200 @@ -24,3 +24,4 @@ 50115e7464e35bc1517b23ed4fd4eed1d284273a 0.7.0 8ee1d7515d35918944151d3a44003063e1ab6a18 0.7.1 0775b131b51d40c2147b1ae104f760698a8d9f9e 0.8.0 +a9a586fec08da03f86ec781472a981949d4c455a 0.8.1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/relatorio-0.8.0/CHANGES new/relatorio-0.8.1/CHANGES --- old/relatorio-0.8.0/CHANGES 2017-12-03 22:12:27.000000000 +0100 +++ new/relatorio-0.8.1/CHANGES 2018-09-30 14:42:26.000000000 +0200 @@ -1,3 +1,10 @@ +0.8.1 - 20180930 +* Add support for Python 3.7 +* Escape invalid XML characters +* Enforce closing tag to be the same directive as the opening +* Use compression for zip file +* Write mimetype as first file of the zip file + 0.8.0 - 20171204 * Do not guess_type on styled cell content * Remove type attributes when guessing type diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/relatorio-0.8.0/PKG-INFO new/relatorio-0.8.1/PKG-INFO --- old/relatorio-0.8.0/PKG-INFO 2017-12-04 16:26:16.000000000 +0100 +++ new/relatorio-0.8.1/PKG-INFO 2018-09-30 14:44:06.000000000 +0200 @@ -1,11 +1,12 @@ Metadata-Version: 1.1 Name: relatorio -Version: 0.8.0 +Version: 0.8.1 Summary: A templating library able to output odt and pdf files Home-page: http://relatorio.tryton.org/ Author: Cedric Krier Author-email: [email protected] License: GPL License +Description-Content-Type: UNKNOWN Description: Relatorio ========= diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/relatorio-0.8.0/doc/conf.py new/relatorio-0.8.1/doc/conf.py --- old/relatorio-0.8.0/doc/conf.py 2017-12-03 22:11:45.000000000 +0100 +++ new/relatorio-0.8.1/doc/conf.py 2018-08-18 13:27:26.000000000 +0200 @@ -50,7 +50,7 @@ # The short X.Y version. version = '0.8' # The full version, including alpha/beta/rc tags. -release = '0.8.0' +release = '0.8.1' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/relatorio-0.8.0/relatorio/__init__.py new/relatorio-0.8.1/relatorio/__init__.py --- old/relatorio-0.8.0/relatorio/__init__.py 2017-12-03 22:11:59.000000000 +0100 +++ new/relatorio-0.8.1/relatorio/__init__.py 2018-08-18 13:27:26.000000000 +0200 @@ -12,5 +12,5 @@ from .reporting import MIMETemplateLoader, ReportRepository, Report from . import templates -__version__ = '0.8.0' +__version__ = '0.8.1' __all__ = ['MIMETemplateLoader', 'ReportRepository', 'Report', 'templates'] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/relatorio-0.8.0/relatorio/templates/opendocument.py new/relatorio-0.8.1/relatorio/templates/opendocument.py --- old/relatorio-0.8.0/relatorio/templates/opendocument.py 2017-11-20 11:57:58.000000000 +0100 +++ new/relatorio-0.8.1/relatorio/templates/opendocument.py 2018-08-18 13:27:26.000000000 +0200 @@ -83,6 +83,9 @@ THUMBNAILS = 'Thumbnails' output_encode = genshi.output.encode EtreeElement = lxml.etree.Element +XML_INVALID_CHAR_EXPR = re.compile( + # from https://www.w3.org/TR/REC-xml/#charsets + u'[\x00-\x08\x0b\x0c\x0e-\x1F\uD800-\uDFFF\uFFFE\uFFFF]') # A note regarding OpenDocument namespaces: # @@ -245,6 +248,14 @@ (node.attrib[py_attrs_attr], value) +def escape_xml_invalid_chars(value, repl=' '): + "Replace invalid characters for XML." + if isinstance(value, basestring): + return XML_INVALID_CHAR_EXPR.sub(repl, value) + else: + return value + + class Template(MarkupTemplate): def __init__(self, source, filepath=None, filename=None, loader=None, @@ -408,9 +419,14 @@ if directive in GENSHI_CLOSING_DIRECTIVE: # map closing tags with their opening tag if is_opening: - opened_tags.append(statement) + opened_tags.append((statement, directive)) else: - closing_tags[id(opened_tags.pop())] = statement + opening_statement, opening_directive = opened_tags.pop() + assert directive == opening_directive, ( + "Wrong pairing tags between '%s' and '%s'" + % (opening_statement.text.encode('utf-8'), + statement.text.encode('utf-8'))) + closing_tags[id(opening_statement)] = statement # - we only need to return opening statements if is_opening: r_statements.append((statement, @@ -526,7 +542,8 @@ if (grand_parent is None or grand_parent.tag != table_cell_tag ) or len(grand_parent) != 1 or has_style(parent): - r_node.attrib[py_replace] = expr + r_node.attrib[py_replace] = ( + '__relatorio_escape_invalid_chars(%s)' % expr) continue cache_id = id(r_node) @@ -790,6 +807,7 @@ type_ = 'float' elif isinstance(val, basestring): type_ = 'string' + val = escape_xml_invalid_chars(val) elif isinstance(val, datetime.timedelta): type_ = 'time' val = 'P%sD%sS' % (val.days, val.seconds) @@ -810,6 +828,7 @@ kwargs) kwargs['__relatorio_make_dimension'] = ImageDimension(self.namespaces) kwargs['__relatorio_guess_type'] = self._guess_type + kwargs['__relatorio_escape_invalid_chars'] = escape_xml_invalid_chars counter = ColumnCounter() kwargs['__relatorio_reset_col_count'] = counter.reset @@ -874,7 +893,8 @@ def fod2od(source): "Convert Flat OpenDocument to OpenDocument" odt_io = BytesIO() - odt_zip = zipfile.ZipFile(odt_io, mode='w') + odt_zip = zipfile.ZipFile( + odt_io, mode='w', compression=zipfile.ZIP_DEFLATED) fodt_tree = lxml.etree.parse(source) fodt_root = fodt_tree.getroot() office_ns = fodt_root.nsmap['office'] @@ -889,6 +909,8 @@ '{%s}body' % office_ns: ['content'], } mimetype = fodt_root.attrib['{%s}mimetype' % office_ns] + # mimetype should be written first to let detection through 'magic number' + odt_zip.writestr('mimetype', mimetype, zipfile.ZIP_STORED) documents = {} images = [] for child in fodt_root: @@ -917,7 +939,6 @@ odt_zip.writestr(fname, data) manifest.add_file_entry(fname, mime_type) odt_zip.writestr(MANIFEST, str(manifest)) - odt_zip.writestr('mimetype', mimetype) odt_zip.close() return odt_io @@ -1027,7 +1048,8 @@ self.manifest = Manifest(self.inzip.read(MANIFEST)) self.meta = Meta(self.inzip.read(META)) self.new_oo = BytesIO() - self.outzip = zipfile.ZipFile(self.new_oo, 'w') + self.outzip = zipfile.ZipFile( + self.new_oo, mode='w', compression=zipfile.ZIP_DEFLATED) self.xml_serializer = genshi.output.XMLSerializer() def __call__(self, stream): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/relatorio-0.8.0/relatorio/tests/test_odt.py new/relatorio-0.8.1/relatorio/tests/test_odt.py --- old/relatorio-0.8.0/relatorio/tests/test_odt.py 2017-11-20 10:47:38.000000000 +0100 +++ new/relatorio-0.8.1/relatorio/tests/test_odt.py 2018-08-18 13:27:26.000000000 +0200 @@ -31,7 +31,8 @@ from genshi.template.eval import UndefinedError from relatorio.templates.opendocument import Template, GENSHI_EXPR,\ - GENSHI_URI, RELATORIO_URI, fod2od, remove_node_keeping_tail + GENSHI_URI, RELATORIO_URI, fod2od, remove_node_keeping_tail, \ + escape_xml_invalid_chars OO_TABLE_NS = "urn:oasis:names:tc:opendocument:xmlns:table:1.0" @@ -100,7 +101,8 @@ root_interpolated = lxml.etree.parse(interpolated).getroot() child = root_interpolated[0] self.assertEqual( - child.get('{http://genshi.edgewall.org/}replace'), 'foo') + child.get('{http://genshi.edgewall.org/}replace'), + '__relatorio_escape_invalid_chars(foo)') def test_column_looping(self): xml = b''' @@ -412,3 +414,23 @@ self.assertEqual( lxml.etree.tostring(tree), b'''<parent><previous/>tailtail</parent>''') + + +class TestEscapeXMLInvalidChars(unittest.TestCase): + + def test_valid(self): + "Test escape valid" + self.assertEqual(escape_xml_invalid_chars("foo"), "foo") + + def test_valid_control(self): + "Test escape valid control" + self.assertEqual(escape_xml_invalid_chars("foo \x09"), "foo \x09") + + def test_invalid(self): + "Test escape invalid" + self.assertEqual(escape_xml_invalid_chars("foo \x00 bar"), "foo bar") + + def test_replacement(self): + "Test replacement" + self.assertEqual( + escape_xml_invalid_chars("foo \x00 bar", "?"), "foo ? bar") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/relatorio-0.8.0/relatorio.egg-info/PKG-INFO new/relatorio-0.8.1/relatorio.egg-info/PKG-INFO --- old/relatorio-0.8.0/relatorio.egg-info/PKG-INFO 2017-12-04 16:26:14.000000000 +0100 +++ new/relatorio-0.8.1/relatorio.egg-info/PKG-INFO 2018-09-30 14:44:06.000000000 +0200 @@ -1,11 +1,12 @@ Metadata-Version: 1.1 Name: relatorio -Version: 0.8.0 +Version: 0.8.1 Summary: A templating library able to output odt and pdf files Home-page: http://relatorio.tryton.org/ Author: Cedric Krier Author-email: [email protected] License: GPL License +Description-Content-Type: UNKNOWN Description: Relatorio ========= diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/relatorio-0.8.0/relatorio.egg-info/requires.txt new/relatorio-0.8.1/relatorio.egg-info/requires.txt --- old/relatorio-0.8.0/relatorio.egg-info/requires.txt 2017-12-04 16:26:14.000000000 +0100 +++ new/relatorio-0.8.1/relatorio.egg-info/requires.txt 2018-09-30 14:44:06.000000000 +0200 @@ -1,8 +1,8 @@ -Genshi >= 0.5 -lxml >= 2.0 +Genshi>=0.5 +lxml>=2.0 [chart] -pycha >= 0.4.0 +pycha>=0.4.0 pyyaml [fodt] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/relatorio-0.8.0/tox.ini new/relatorio-0.8.1/tox.ini --- old/relatorio-0.8.0/tox.ini 2017-11-20 11:04:12.000000000 +0100 +++ new/relatorio-0.8.1/tox.ini 2018-08-18 13:27:26.000000000 +0200 @@ -4,7 +4,7 @@ # and then run "tox" from this directory. [tox] -envlist = py26, py27, py32, py33, py34, py35, py36, pypy +envlist = py26, py27, py32, py33, py34, py35, py36, py37, pypy [testenv] commands = {envpython} setup.py test
