From c3f630df52c3a278316fba89c92f90b5426c36d8 Mon Sep 17 00:00:00 2001 From: Ulf Magnusson Date: Tue, 13 Sep 2016 00:40:37 +0200 Subject: [PATCH] bitbake: bitbake: fetch2: Make SRCREV_FORMAT name substitution safer The implementation of SRCREV_FORMAT has at least two issues: 1. Given two names "foo" and "foobar" and SRCREV_FORMAT = "foo_foobar", "foo" might currently get substituted twice, and "foobar" not at all. 2. If the revision substitued for some name happens to contain another name as a substring, then that substring might incorrectly get replaced. Fix both issues by sorting the names with the longest ones first and replacing all names at once with a regular expression. This was inspired by http://stackoverflow.com/questions/6116978/python-replace-multiple-strings. (Bitbake rev: 8e6a893cb7f13ea14051fc40c6c9baf41aa47fee) Signed-off-by: Ulf Magnusson Signed-off-by: Richard Purdie --- bitbake/lib/bb/fetch2/__init__.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/bitbake/lib/bb/fetch2/__init__.py b/bitbake/lib/bb/fetch2/__init__.py index 11c75cc723..06f1eb4e81 100644 --- a/bitbake/lib/bb/fetch2/__init__.py +++ b/bitbake/lib/bb/fetch2/__init__.py @@ -761,6 +761,7 @@ def get_srcrev(d, method_name='sortable_revision'): if not format: raise FetchError("The SRCREV_FORMAT variable must be set when multiple SCMs are used.") + name_to_rev = {} seenautoinc = False for scm in scms: ud = urldata[scm] @@ -769,7 +770,16 @@ def get_srcrev(d, method_name='sortable_revision'): seenautoinc = seenautoinc or autoinc if len(rev) > 10: rev = rev[:10] - format = format.replace(name, rev) + name_to_rev[name] = rev + # Replace names by revisions in the SRCREV_FORMAT string. The approach used + # here can handle names being prefixes of other names and names appearing + # as substrings in revisions (in which case the name should not be + # expanded). The '|' regular expression operator tries matches from left to + # right, so we need to sort the names with the longest ones first. + names_descending_len = sorted(name_to_rev, key=len, reverse=True) + name_to_rev_re = "|".join(re.escape(name) for name in names_descending_len) + format = re.sub(name_to_rev_re, lambda match: name_to_rev[match.group(0)], format) + if seenautoinc: format = "AUTOINC+" + format