[kirkstone,2.0,01/18] providers: use local variable for packages_dynamic pattern

Message ID 4fddb0c9ef344d73b10fd9491a39f4c36e3094b1.1652205806.git.steve@sakoman.com
State Accepted, archived
Commit 69d3b86449be23b07f794e302f6e18f3a2c46424
Headers show
Series [kirkstone,2.0,01/18] providers: use local variable for packages_dynamic pattern | expand

Commit Message

Steve Sakoman May 10, 2022, 6:05 p.m. UTC
From: Matt Madison <matt@madison.systems>

During parsing, Python raises

   RuntimeError: dictionary changed size during iteration

in getRuntimeProviders, if you happen to have a recipe
with an explicit RDEPENDS on a dynamic package containing a '+'
character, such as 'gtk+3-locale-en'.

This is because we're using the modified pattern as the
key into the packages_dynamic dict to append to rproviders,
and since that key doesn't exist, the dict is getting modified
to add a new, empty, entry for it. So even without the runtime
error, we'd be generating an incorrect result.

Fix this by using a local variable for modifying the pattern
and using the original key to retrieve the value on a match.

Signed-off-by: Matt Madison <matt@madison.systems>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
(cherry picked from commit 07de375c3e57f17ab7b47569186f24ecd9896825)
Signed-off-by: Steve Sakoman <steve@sakoman.com>
---
 lib/bb/providers.py | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

Patch

diff --git a/lib/bb/providers.py b/lib/bb/providers.py
index 8c1c31a5..e11a4637 100644
--- a/lib/bb/providers.py
+++ b/lib/bb/providers.py
@@ -396,8 +396,8 @@  def getRuntimeProviders(dataCache, rdepend):
         return rproviders
 
     # Only search dynamic packages if we can't find anything in other variables
-    for pattern in dataCache.packages_dynamic:
-        pattern = pattern.replace(r'+', r"\+")
+    for pat_key in dataCache.packages_dynamic:
+        pattern = pat_key.replace(r'+', r"\+")
         if pattern in regexp_cache:
             regexp = regexp_cache[pattern]
         else:
@@ -408,7 +408,7 @@  def getRuntimeProviders(dataCache, rdepend):
                 raise
             regexp_cache[pattern] = regexp
         if regexp.match(rdepend):
-            rproviders += dataCache.packages_dynamic[pattern]
+            rproviders += dataCache.packages_dynamic[pat_key]
             logger.debug("Assuming %s is a dynamic package, but it may not exist" % rdepend)
 
     return rproviders