From b481229d8fe2870e045fa78dc6fb73d2e6e51b2e Mon Sep 17 00:00:00 2001
From: Mike McLean <mikem@redhat.com>
Date: Oct 06 2016 21:40:51 +0000
Subject: [PATCH 1/3] assert basic nvr sanity for cg imports


---

diff --git a/hub/kojihub.py b/hub/kojihub.py
index 799821c..ccc833a 100644
--- a/hub/kojihub.py
+++ b/hub/kojihub.py
@@ -4975,6 +4975,8 @@ class CG_Importer(object):
                 datetime.datetime.fromtimestamp(float(metadata['build']['end_time'])).isoformat(' ')
         self.buildinfo = buildinfo
 
+        koji.check_NVR(buildinfo, strict=True)
+
         # get typeinfo
         b_extra = self.metadata['build'].get('extra', {})
         typeinfo = b_extra.get('typeinfo', {})
@@ -5178,6 +5180,8 @@ class CG_Importer(object):
                 raise koji.GenericError("Missing buildroot metadata for id %(buildroot_id)r" % fileinfo)
             if fileinfo['type'] not in ['rpm', 'log']:
                 self.prep_archive(fileinfo)
+            if fileinfo['type'] == 'rpm':
+                koji.check_NVRA(fileinfo['filename'], strict=True)
             outputs.append(fileinfo)
         self.prepped_outputs = outputs
 
diff --git a/koji/__init__.py b/koji/__init__.py
index 81ab53b..7adec74 100644
--- a/koji/__init__.py
+++ b/koji/__init__.py
@@ -916,6 +916,65 @@ def parse_NVRA(nvra):
         ret['location'] = location
     return ret
 
+
+def check_NVR(nvr, strict=False):
+    """Perform basic validity checks on an NVR
+
+    nvr may be a string or a dictionary with keys name, version, and release
+
+    This function only performs minimal, basic checking. It does not enforce
+    the sort of constraints that a project might have in their packaging
+    guidelines.
+    """
+
+    try:
+        return _check_NVR(nvr)
+    except GenericError:
+        if strict:
+            raise
+        else:
+            return False
+
+def _check_NVR(nvr):
+    if isinstance(nvr, basestring):
+        nvr = parse_NVR(nvr)
+    if '-' in nvr['version']:
+        raise GenericError('The "-" character not allowed in version field')
+    if '-' in nvr['release']:
+        raise GenericError('The "-" character not allowed in release field')
+    # anything else?
+    return True
+
+
+def check_NVRA(nvra, strict=False):
+    """Perform basic validity checks on an NVRA
+
+    nvr may be a string or a dictionary with keys name, version, and release
+
+    This function only performs minimal, basic checking. It does not enforce
+    the sort of constraints that a project might have in their packaging
+    guidelines.
+    """
+    try:
+        return _check_NVRA(nvra)
+    except GenericError:
+        if strict:
+            raise
+        else:
+            return False
+
+
+def _check_NVRA(nvra):
+    if isinstance(nvra, basestring):
+            nvr = parse_NVR(nvra)
+    if '-' in nvra['version']:
+        raise GenericError('The "-" character not allowed in version field')
+    if '-' in nvra['release']:
+        raise GenericError('The "-" character not allowed in release field')
+    if '.' in nvra['arch']:
+        raise GenericError('The "." character not allowed in arch field')
+
+
 def is_debuginfo(name):
     """Determines if an rpm is a debuginfo rpm, based on name"""
     if name.endswith('-debuginfo') or name.find('-debuginfo-') != -1:

From 30226706e1e37b36b8a99ae35bfd6b6277813c9f Mon Sep 17 00:00:00 2001
From: Mike McLean <mikem@redhat.com>
Date: Oct 06 2016 21:40:51 +0000
Subject: [PATCH 2/3] fix cut and paste errors


---

diff --git a/koji/__init__.py b/koji/__init__.py
index 7adec74..4ad82fc 100644
--- a/koji/__init__.py
+++ b/koji/__init__.py
@@ -949,7 +949,7 @@ def _check_NVR(nvr):
 def check_NVRA(nvra, strict=False):
     """Perform basic validity checks on an NVRA
 
-    nvr may be a string or a dictionary with keys name, version, and release
+    nvra may be a string or a dictionary with keys name, version, and release
 
     This function only performs minimal, basic checking. It does not enforce
     the sort of constraints that a project might have in their packaging
@@ -966,13 +966,14 @@ def check_NVRA(nvra, strict=False):
 
 def _check_NVRA(nvra):
     if isinstance(nvra, basestring):
-            nvr = parse_NVR(nvra)
+            nvra = parse_NVRA(nvra)
     if '-' in nvra['version']:
         raise GenericError('The "-" character not allowed in version field')
     if '-' in nvra['release']:
         raise GenericError('The "-" character not allowed in release field')
     if '.' in nvra['arch']:
         raise GenericError('The "." character not allowed in arch field')
+    return True
 
 
 def is_debuginfo(name):

From e1de395d67ab65a30547f63877f25515b1e00602 Mon Sep 17 00:00:00 2001
From: Mike McLean <mikem@redhat.com>
Date: Oct 06 2016 21:40:51 +0000
Subject: [PATCH 3/3] add unit tests for check_NVR[A] functions


---

diff --git a/tests/test_parsers.py b/tests/test_parsers.py
index 93de88a..6039037 100644
--- a/tests/test_parsers.py
+++ b/tests/test_parsers.py
@@ -63,5 +63,49 @@ class INITTestCase(unittest.TestCase):
         self.assertEqual(ret['arch'], "src")
         self.assertEqual(ret['src'], True)
 
+    def test_check_NVR(self):
+        """Test the check_NVR function"""
+        good = [
+            "name-version-release",
+            "fnord-5.23-17",
+            {'name': 'foo', 'version': '2.2.2', 'release': '1.1'},
+            ]
+        bad = [
+            "this is not an NVR",
+            {'name': 'foo', 'version': '2.2.2-a', 'release': '1.1'},
+            {'name': 'foo', 'version': '2.2.2', 'release': '1.1-b'},
+            ]
+        for value in good:
+            self.assertEqual(koji.check_NVR(value), True)
+        for value in bad:
+            self.assertEqual(koji.check_NVR(value), False)
+            self.assertRaises(koji.GenericError,
+                              koji.check_NVR, value, strict=True)
+
+    def test_check_NVRA(self):
+        """Test the check_NVRA function"""
+        good = [
+            "name-version-release.arch",
+            "fnord-5.23-17.x86_64",
+            {'name': 'foo', 'version': '2.2.2', 'release': '1.1',
+                'arch': 'i686'},
+            ]
+        bad = [
+            "this is not an NVRA",
+            "fnord-5.23-17",
+            {'name': 'foo', 'version': '2.2.2-a', 'release': '1.1',
+                'arch': 'ppc64'},
+            {'name': 'foo', 'version': '2.2.2', 'release': '1.1-b',
+                'arch': 'x86_64'},
+            {'name': 'foo', 'version': '2.2.2', 'release': '1.1',
+                'arch': 'x.86.64'},
+            ]
+        for value in good:
+            self.assertEqual(koji.check_NVRA(value), True)
+        for value in bad:
+            self.assertEqual(koji.check_NVRA(value), False)
+            self.assertRaises(koji.GenericError,
+                              koji.check_NVRA, value, strict=True)
+
 if __name__ == '__main__':
     unittest.main()

