Fix macro scoping level on re-entry from %[] expresssion (#2354)

This is the same issue as commit 1767bc4fd8
was with Lua, and so the same fix works: restore the nesting level
from the macro context when re-entering macro engine from %[]
expression. Analysis and suggested fix by Michael Schroeder,
reproducer from Miro Hrončok.

Add tests for both %[] and %{expr:...}, although the latter isn't
affected because the expression is macro-expanded beforehand.

Fixes: #2354
This commit is contained in:
Panu Matilainen 2023-01-19 09:55:14 +02:00
parent c10e1ec114
commit fd2f743b3e
2 changed files with 48 additions and 2 deletions

View File

@ -58,8 +58,8 @@ struct rpmMacroEntry_s {
struct rpmMacroContext_s {
rpmMacroEntry *tab; /*!< Macro entry table (array of pointers). */
int n; /*!< No. of macros. */
int depth; /*!< Depth tracking when recursing from Lua */
int level; /*!< Scope level tracking when recursing from Lua */
int depth; /*!< Depth tracking on external recursion */
int level; /*!< Scope level tracking when on external recursion */
pthread_mutex_t lock;
pthread_mutexattr_t lockattr;
};
@ -586,7 +586,16 @@ static void doExpressionExpansion(MacroBuf mb, const char * expr, size_t len)
{
char *buf = rstrndup(expr, len);
char *result;
rpmMacroContext mc = mb->mc;
int odepth = mc->depth;
int olevel = mc->level;
mc->depth = mb->depth;
mc->level = mb->level;
result = rpmExprStrFlags(buf, RPMEXPR_EXPAND);
mc->depth = odepth;
mc->level = olevel;
if (!result) {
mb->error = 1;
goto exit;

View File

@ -526,6 +526,43 @@ runroot rpm \
[])
AT_CLEANUP
AT_SETUP([expression macro level])
AT_KEYWORDS([macros])
AT_CHECK([[
runroot rpm \
--define 'expopt(r) %[%{undefined yyy} ? "aa " : "bb "]%{-r:the -r option was set}%{!-r:the -r option was not set}' \
--eval '%expopt' \
--eval '%expopt -r' \
--define 'yyy 1' \
--eval '%expopt' \
--eval '%expopt -r'
]],
[0],
[aa the -r option was not set
aa the -r option was set
bb the -r option was not set
bb the -r option was set
],
[])
AT_CHECK([[
runroot rpm \
--define 'expopt(r) %{expr:%{undefined yyy} ? "aa " : "bb "}%{-r:the -r option was set}%{!-r:the -r option was not set}' \
--eval '%expopt' \
--eval '%expopt -r' \
--define 'yyy 1' \
--eval '%expopt' \
--eval '%expopt -r'
]],
[0],
[aa the -r option was not set
aa the -r option was set
bb the -r option was not set
bb the -r option was set
],
[])
AT_CLEANUP
AT_SETUP([short circuiting])
AT_KEYWORDS([macros])
AT_CHECK([