[Yum-devel] [PATCH] pkg matching: handle re.compile() errors. BZ 864294

Zdeněk Pavlas zpavlas at redhat.com
Tue Oct 9 12:23:11 UTC 2012


When something looks like a pattern but fails to compile, use it as is.
We'll probably never hit files named '[b-a]', but this seems better
than just ignoring such patterns.
---
 yum/misc.py        |   12 ++++++++++++
 yum/packageSack.py |   15 +++++----------
 yum/packages.py    |    5 ++---
 yum/rpmsack.py     |   24 +++++++++++-------------
 4 files changed, 30 insertions(+), 26 deletions(-)

diff --git a/yum/misc.py b/yum/misc.py
index 0fd3e90..22fddb9 100644
--- a/yum/misc.py
+++ b/yum/misc.py
@@ -97,6 +97,18 @@ def re_glob(s):
         _re_compiled_glob_match = re.compile('[*?]|\[.+\]').search
     return _re_compiled_glob_match(s)
 
+def compile_pattern(pat, ignore_case=False):
+    """ Compile shell wildcards, return a 'match' function. """
+    if re_glob(pat):
+        try:
+            return re.compile(fnmatch.translate(pat), ignore_case and re.I).match
+        except re.error:
+            pass # fall back to exact match
+    if ignore_case:
+        pat = pat.lower()
+        return lambda s: s.lower() == pat
+    return lambda s: s == pat
+
 _re_compiled_filename_match = None
 def re_filename(s):
     """ Tests if a string could be a filename. We still get negated character
diff --git a/yum/packageSack.py b/yum/packageSack.py
index 47832fc..a702ac1 100644
--- a/yum/packageSack.py
+++ b/yum/packageSack.py
@@ -282,11 +282,7 @@ class PackageSackBase(object):
 
         specs = {}
         for p in pkgspecs:
-            if misc.re_glob(p):
-                restring = fnmatch.translate(p)
-                specs[p] = re.compile(restring)
-            else:
-                specs[p] = p
+            specs[p] = misc.compile_pattern(p)
 
         #  We don't use simplePkgList() here because that loads all of the
         # rpmdb, if we are Eg. doing a "remove PackageKit".
@@ -304,13 +300,12 @@ class PackageSackBase(object):
                 ))
                 
             for (term,query) in specs.items():
-                if term == query:
-                    if query in names:
-                        exactmatch.append(self.searchPkgTuple(pkgtup)[0])
-                        unmatched.discard(term)
+                if term in names:
+                    exactmatch.append(self.searchPkgTuple(pkgtup)[0])
+                    unmatched.discard(term)
                 else:
                     for n in names:
-                        if query.match(n):
+                        if query(n):
                             matched.append(self.searchPkgTuple(pkgtup)[0])
                             unmatched.discard(term)
         return misc.unique(exactmatch), misc.unique(matched), list(unmatched)
diff --git a/yum/packages.py b/yum/packages.py
index 07c555c..7a2624a 100644
--- a/yum/packages.py
+++ b/yum/packages.py
@@ -132,11 +132,10 @@ def parsePackages(pkgs, usercommands, casematch=0,
                 trylist = pkgdict.keys()
                 # command and pkgdict are already lowered if not casematch
                 # so case sensitive is always fine
-                restring = fnmatch.translate(command)
-                regex = re.compile(restring)
+                regex = misc.compile_pattern(command)
                 foundit = 0
                 for item in trylist:
-                    if regex.match(item):
+                    if regex(item):
                         matched.extend(pkgdict[item])
                         del pkgdict[item]
                         foundit = 1
diff --git a/yum/rpmsack.py b/yum/rpmsack.py
index a4da4ab..302f613 100644
--- a/yum/rpmsack.py
+++ b/yum/rpmsack.py
@@ -546,13 +546,11 @@ class RPMDBPackageSack(PackageSackBase):
             qpat = pat[0]
             if qpat in ('?', '*', '['):
                 qpat = None
-            if ignore_case:
-                if qpat is not None:
-                    qpat = qpat.lower()
-                ret.append((qpat, re.compile(fnmatch.translate(pat), re.I)))
-            else:
-                ret.append((qpat, re.compile(fnmatch.translate(pat))))
+            elif ignore_case:
+                qpat = qpat.lower()
+            ret.append((qpat, misc.compile_pattern(pat, ignore_case)))
         return ret
+
     @staticmethod
     def _match_repattern(repatterns, hdr, ignore_case):
         """ This is basically parsePackages() but for rpm hdr objects. """
@@ -570,20 +568,20 @@ class RPMDBPackageSack(PackageSackBase):
                 qname = qname.lower()
             if qpat is not None and qpat != qname and qpat != epoch[0]:
                 continue
-            if repat.match(hdr['name']):
+            if repat(hdr['name']):
                 return True
-            if repat.match("%(name)s-%(version)s-%(release)s.%(arch)s" % hdr):
+            if repat("%(name)s-%(version)s-%(release)s.%(arch)s" % hdr):
                 return True
-            if repat.match("%(name)s.%(arch)s" % hdr):
+            if repat("%(name)s.%(arch)s" % hdr):
                 return True
-            if repat.match("%(name)s-%(version)s" % hdr):
+            if repat("%(name)s-%(version)s" % hdr):
                 return True
-            if repat.match("%(name)s-%(version)s-%(release)s" % hdr):
+            if repat("%(name)s-%(version)s-%(release)s" % hdr):
                 return True
-            if repat.match(epoch + ":%(name)s-%(version)s-%(release)s.%(arch)s"
+            if repat(epoch + ":%(name)s-%(version)s-%(release)s.%(arch)s"
                            % hdr):
                 return True
-            if repat.match("%(name)s-%(epoch)s:%(version)s-%(release)s.%(arch)s"
+            if repat("%(name)s-%(epoch)s:%(version)s-%(release)s.%(arch)s"
                            % hdr):
                 return True
         return False
-- 
1.7.4.4



More information about the Yum-devel mailing list