variants: Reject values with whitespace

If there is leading or trailing whitespace in a comps group name, it
will not be included in the compose and there will even be no error
message. Whitespace on module name results in a failure.

To avoid these errors, validating the variants file will now also check
that there is no whitespace in significant places, and abort the compose
if there a problem.

Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
This commit is contained in:
Lubomír Sedlář 2018-06-12 12:24:20 +02:00
parent fa92e54c22
commit 4a61de1e8a
2 changed files with 68 additions and 1 deletions

View File

@ -39,6 +39,21 @@ def get_variants_dtd(logger=None):
return variants_dtd return variants_dtd
class VariantsValidationError(ValueError):
pass
NO_WHITESPACE_ELEMENTS = [
"arch",
"environment",
"group",
"kojitag",
"module",
"name",
"package",
]
class VariantsXmlParser(object): class VariantsXmlParser(object):
def __init__(self, file_obj, tree_arches=None, tree_variants=None, logger=None): def __init__(self, file_obj, tree_arches=None, tree_variants=None, logger=None):
self.tree = lxml.etree.parse(file_obj) self.tree = lxml.etree.parse(file_obj)
@ -61,7 +76,24 @@ class VariantsXmlParser(object):
def validate(self): def validate(self):
if not self.dtd.validate(self.tree): if not self.dtd.validate(self.tree):
errors = [str(i) for i in self.dtd.error_log.filter_from_errors()] errors = [str(i) for i in self.dtd.error_log.filter_from_errors()]
raise ValueError("Variants XML doesn't validate:\n%s" % "\n".join(errors)) raise VariantsValidationError(
"Variants XML doesn't validate:\n%s" % "\n".join(errors)
)
errors = []
for text in self.tree.xpath("//text()"):
if text != text.strip() and not text.is_tail:
e = text.getparent()
if e.tag in NO_WHITESPACE_ELEMENTS:
errors.append(
"Tag %s on line %s contains leading or trailing whitespace"
% (e.tag, e.sourceline)
)
if errors:
raise VariantsValidationError(
"Variants XML doesn't validate:\n%s" % "\n".join(errors)
)
def parse_variant_node(self, variant_node, parent=None): def parse_variant_node(self, variant_node, parent=None):
variant_dict = { variant_dict = {

View File

@ -0,0 +1,35 @@
# -*- coding: utf-8 -*-
try:
import unittest2 as unittest
except ImportError:
import unittest
import os
import sys
from six.moves import cStringIO
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
from pungi.wrappers.variants import VariantsXmlParser
VARIANTS_WITH_WHITESPACE = """
<variants>
<variant id="Foo" name="Foo" type="variant">
<arches><arch>x86_64 </arch></arches>
<groups><group> core</group></groups>
<environments><environment> foo </environment></environments>
</variant>
</variants>
"""
class TestVariantsXmlParser(unittest.TestCase):
def test_whitespace_in_file(self):
input = cStringIO(VARIANTS_WITH_WHITESPACE)
with self.assertRaises(ValueError) as ctx:
VariantsXmlParser(input)
self.assertIn("Tag arch on line 4", str(ctx.exception))
self.assertIn("Tag group on line 5", str(ctx.exception))
self.assertIn("Tag environment on line 6", str(ctx.exception))