diff options
author | Panu Matilainen <pmatilai@redhat.com> | 2017-03-07 14:06:55 +0200 |
---|---|---|
committer | Panu Matilainen <pmatilai@redhat.com> | 2017-03-07 14:06:55 +0200 |
commit | 307627993ec0c3eed729aea34843a87aa5bde6d2 (patch) | |
tree | f40de8972fad2bd00de2b8426cc15c256aaa7a70 | |
parent | 237f35f16f978bb20e4cafd78abfab1f2e5db480 (diff) | |
download | rpm-307627993ec0c3eed729aea34843a87aa5bde6d2.tar.gz |
Enforce visibility scoping for automatic macros
When a parametric macro "calls" another parametric macro with fewer
arguments than it received, the inner macro would see the %<n>
macros of the outer call which is an obvious scoping violation
and quirky behavior, making macro writing harder than it needs be.
Similar scoping issues exist for manually defined macros but those
have further complications (because of %undefine semantics) that we
sheepishly avoid here by limiting the visibility enforcing to automatic
macros only (for now at least).
-rw-r--r-- | rpmio/macro.c | 12 | ||||
-rw-r--r-- | tests/rpmmacro.at | 13 |
2 files changed, 22 insertions, 3 deletions
diff --git a/rpmio/macro.c b/rpmio/macro.c index 6428b9caa..69f5c9d81 100644 --- a/rpmio/macro.c +++ b/rpmio/macro.c @@ -1211,9 +1211,15 @@ expandMacro(MacroBuf mb, const char *src, size_t slen) mep = findEntry(mb->mc, f, fn, NULL); me = (mep ? *mep : NULL); - /* If we looked up a macro, consider it used */ - if (me) - me->flags |= ME_USED; + if (me) { + if ((me->flags & ME_AUTO) && mb->level > me->level) { + /* Ignore out-of-scope automatic macros */ + me = NULL; + } else { + /* If we looked up a macro, consider it used */ + me->flags |= ME_USED; + } + } /* XXX Special processing for flags */ if (*f == '-') { diff --git a/tests/rpmmacro.at b/tests/rpmmacro.at index e1d9ccfd7..e238edcea 100644 --- a/tests/rpmmacro.at +++ b/tests/rpmmacro.at @@ -79,6 +79,19 @@ foo 5 []) AT_CLEANUP +AT_SETUP([parametrized macro 2]) +AT_KEYWORDS([macros]) +AT_CHECK([ +runroot rpm \ + --define '%bar() "Bar %#: %{?1} %{?2}"' \ + --define '%foo() "Foo %#: %{?1} %{?2}" %bar a' \ + --eval '%foo 1 2' +], +[0], +["Foo 2: 1 2" "Bar 1: a " +]) +AT_CLEANUP + AT_SETUP([uncompress macro]) AT_KEYWORDS([macros]) AT_CHECK([ |